【电路笔记 STM32】STM32CubeMX配置&自动移植FreeRTOS + STM32&FreeRTOS点灯的最简单示例

文章目录

    • [1. 新建CubeMX工程,选择芯片](#1. 新建CubeMX工程,选择芯片)
    • [2. 基础硬件配置(时钟、调试、引脚)](#2. 基础硬件配置(时钟、调试、引脚))
      • [2.1 配置系统时钟(必须,FreeRTOS依赖系统时钟)](#2.1 配置系统时钟(必须,FreeRTOS依赖系统时钟))
      • [2.2 配置调试接口(SYS配置页的"Timebase Source 时基源)](#2.2 配置调试接口(SYS配置页的“Timebase Source 时基源))
          • [2.3 配置引脚](#2.3 配置引脚)
      • [2.4. 开启FreeRTOS并配置核心参数](#2.4. 开启FreeRTOS并配置核心参数)
      • 2.5:生成工程代码
      • [3. 代码开发:极简版------单个任务实现LED常闪烁](#3. 代码开发:极简版——单个任务实现LED常闪烁)
      • [4. Keil编译+烧录运行](#4. Keil编译+烧录运行)
      • 4.1:Keil工程编译
      • 4.2:硬件接线
      • 4.3:烧录程序
    • [5. 运行效果验证](#5. 运行效果验证)
  • STM32CubeMX已经内置了FreeRTOS的移植模板,能自动适配STM32F103的硬件,无需手动修改FreeRTOS内核源码(新手友好),步骤如下:

1. 新建CubeMX工程,选择芯片

  1. 打开STM32CubeMX,点击File -> New Project
  2. Search for Part Number中输入STM32F103C8T6,选中芯片后点击Start Project
  3. 弹出Pinout Configuration提示,直接点击OK(后续再配置引脚)。

2. 基础硬件配置(时钟、调试、引脚)

2.1 配置系统时钟(必须,FreeRTOS依赖系统时钟)

  1. 点击左侧System Core -> RCC
  2. 右侧High Speed Clock (HSE)选择Crystal/Ceramic Resonator(外部8M晶振,蓝色小药丸标配);
  3. 点击左侧Clock Configuration,配置系统时钟为72MHz (STM32F103最大主频):
    • PLL Source Mux选择HSE
    • PLL Mulitplier选择x9(8M*9=72M);
    • AHB Prescaler选择1
    • APB1 Prescaler选择2(APB1最大36MHz);
    • APB2 Prescaler选择1
    • 点击Clock Configuration上方的Refresh,确认无红色报错。

2.2 配置调试接口(SYS配置页的"Timebase Source 时基源)

  • 点击左侧System Core -> SYS
  • 右侧Debug选择Serial Wire(SWD调试,仅需2根线,不占用太多引脚)。
  • 为HAL库选择一个**独立的定时器(如TIM3)**作为时基源,避免资源竞争:
    • SysTick被FreeRTOS独占:FreeRTOS默认使用SysTick作为任务调度的时钟节拍(Tick),用于生成1ms的心跳中断,实现任务切换。
    • HAL库也需要时基 :HAL库的HAL_Delay()uwTick全局变量等功能,也依赖一个1ms的时基中断(TIM1/TIM2/TIM3)。
    • 冲突风险 :如果两者都用SysTick,会导致HAL的时基和FreeRTOS的调度时钟冲突,造成HAL_Delay()失效、任务调度异常。
定时器 类型 位数 时钟源 核心特点 适用场景
TIM1 高级控制定时器 16位 内部时钟/外部时钟/触发信号 带死区生成、刹车功能,支持PWM互补输出 电机控制、需要互补PWM的功率驱动场景
TIM2/TIM3 通用定时器 16位 内部时钟/外部时钟/触发信号 基础定时、PWM输出、输入捕获、输出比较 普通定时、LED呼吸灯、脉冲计数、简单PWM输出
  • 时钟树配置:通用定时器(TIM2/TIM3)挂载在APB1总线上,最大时钟频率为36MHz;高级定时器(TIM1)挂载在APB2总线上,最大时钟频率为72MHz。
2.3 配置引脚
  • 蓝色小药丸默认LED引脚PC13(低电平点亮,因为硬件上LED接VCC,引脚拉低则导通);

2.4. 开启FreeRTOS并配置核心参数

CubeMX的Middleware中集成了FreeRTOS,直接开启即可,自动完成内核移植:

  • 点击左侧Middleware -> FreeRTOS,右侧Mode选择CMSIS-RTOS v1(CMSIS-RTOS v2也行);
  • 进入Config Parameters(FreeRTOS核心配置),新手保持默认即可 (关键参数无需修改):
    • Tick SourceSysTick(时钟节拍用系统滴答定时器,FreeRTOS的心跳);
    • TICK_RATE_HZ1000(时钟节拍1ms,即系统时钟中断1ms一次,任务调度的最小时间片);
    • MINIMAL_STACK_SIZE128(最小任务栈大小);
  • 进入Tasks and Queues可添加新的任务函数(如myTask02,新手可保持默认)。其他参数(如任务栈大小、优先级、队列/信号量)后续可在代码中配置,无需提前修改。

2.5:生成工程代码

  • 点击右上角Project Manager,配置工程信息:

    • Project Name:自定义;
    • Project Location:选择工程保存路径(无中文、无空格);
    • Toolchain/IDE:选择MDK-ARM V5
  • 点击Code Generator,勾选:

    • Generate peripheral initialization as *.c and *.h files(外设初始化分文件,代码更整洁);
    • Copy all used libraries into the project folder(将库文件复制到工程,避免路径问题);
  • 点击右上角GENERATE CODE,生成完成后点击Open Project,自动打开Keil MDK工程。

  • 源码内容:

    D:.
    │ .mxproject
    │ rtos_1.ioc

    └─Core
    ├─Inc
    │ FreeRTOSConfig.h
    │ main.h
    │ stm32f1xx_hal_conf.h
    │ stm32f1xx_it.h

    └─Src
    freertos.c
    main.c
    stm32f1xx_hal_msp.c
    stm32f1xx_hal_timebase_tim.c
    stm32f1xx_it.c

3. 代码开发:极简版------单个任务实现LED常闪烁

  • defaultTask(普通优先级)实现PC13每500ms闪烁一次,myTask02保持空任务即可,只需要修改StartDefaultTask函数:
c 复制代码
void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
    // 翻转PC13引脚电平(亮/灭切换)
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    // FreeRTOS延时500ms,延时期间释放CPU给其他任务
    osDelay(500);
  }
  /* USER CODE END 5 */
}
  • StartTask02函数保持原有代码不变即可。

4. Keil编译+烧录运行

4.1:Keil工程编译

  1. 打开Keil工程后,点击左上角Magic Wand(魔法棒),进入Target选项卡,确认Stack SizeHeap Size设置为0x200(512字节,足够FreeRTOS使用);
  2. 点击Build(编译)或Rebuild(全编译),确保0 Error,0 Warning(无错误无警告)。

4.2:硬件接线

4.3:烧录程序

  • 蓝色小药丸烧录方式有2种,新手推荐SWD烧录(串口烧录 需进入烧录模式:按住蓝色小药丸的BOOT0按键,再按一下RESET复位键,松开BOOT0(此时芯片进入ISP烧录模式)):

    • Keil中点击Download(下载),烧录完成后,再按一下RESET键(退出烧录模式,进入运行模式)。
  • 另外,中间出现一次错误:

c 复制代码
File       : E:\Keil_v5\ARM\PACK\Keil\STM32F1xx_DFP\2.4.1\Keil.STM32F1xx_DFP.pdsc 
Sequence   : CheckID 
Context    : Item #1: <control if="jep106id != 0x20">
                 Item #0: <block>::Line 2 
Expression : "              Message(2, "Not a genuine ST Device! Abort connection.");" 
----------------------------^ 
E203       : Undefined identifier - function 'Message'
 
Load "rtos_1\\rtos_1.axf" 
Erase Done.
Programming Done.
Verify OK.
Flash Load finished at **:**:**
  • 重新连接下载器后得以更正:
c 复制代码
Load "rtos_1\\rtos_1.axf" 
Erase Done.
Programming Done.
Verify OK.
Flash Load finished at **:**:**

5. 运行效果验证

相关推荐
马猴烧酒.1 小时前
【JAVA算法|hot100】数组类型题目详解笔记
java·笔记
浅念-2 小时前
C++ STL list 容器
开发语言·数据结构·c++·经验分享·笔记·算法·list
眼镜哥(with glasses)2 小时前
0215笔记-面向开发者的LLM入门课程-课时10:文本扩展-课题11:聊天机器人
笔记
2501_918126912 小时前
stm32什么程序效率最高,体积小,运行快,适应广?
c语言·stm32·单片机·嵌入式硬件·学习
2501_918126912 小时前
stm32能做次声波发射器吗?
linux·stm32·嵌入式硬件·学习·个人开发
马猴烧酒.2 小时前
【JAVA算法|hot100】堆类型题目详解笔记
java·开发语言·笔记
2501_918126912 小时前
stm32能做哪些程序?
linux·stm32·单片机·嵌入式硬件·个人开发
johnny2332 小时前
《Vibe Coding:AI编程时代的认知重构》笔记
笔记·ai编程
2501_918126912 小时前
stm32程序是用什么语言写的?
c语言·stm32·单片机·嵌入式硬件·个人开发