返回上一级
1296 字
6 分钟
课程导览、硬件准备与工程搭建

p1 ~ p8(约 77 分钟)

这门课在讲什么#

全名《FreeRTOS 快速入门与工程实践》,百问网出品,分两部分:

快速入门 API 怎么用——怎么创建任务、怎么用队列
工程实践 先摆出场景和问题,再讲用 FreeRTOS 的哪个功能去解决

第二部分才是主线。整门课写了 30 多个程序,但它们不是 30 个独立例子,而是三个项目被反复改进的结果:音乐播放、打砖块、汽车游戏。打砖块是核心,最终框架会用到队列、信号量、互斥量、事件组;全课就是一步步提问题、一步步改代码,最后把这个框架搭出来。后两个游戏来自开源项目 nWatch。

讲法上有个特点:理论部分不念 PPT,用绘图板现场画图;实践部分先讲思路,再从第一条指令开始现场写、现场调试,不给现成代码。模块驱动只讲接口怎么调,不讲内部实现——重点是 RTOS,不是 HAL 库开发。

硬件平台#

中间是一块 STM32F103C8T6 核心板,外面套一块黑色 12 边形底板,模块都插在底板上,配 ST-Link 下载器。软件是 STM32CubeMX + Keil。

板上的资源大致这几类:

类别器件用到哪
显示OLED(I2C1,PB6/PB7)数字、菜单、游戏画面
输入红外接收头、旋转编码器、按键游戏手柄
感知姿态传感器摇晃控制、姿态控制
输出LED(PC13)、无源蜂鸣器、全彩 LED、直流电机状态提示、音乐、动作

两个配置上的取舍:

Debug 接口选 SWD,不选 JTAG。 JTAG 会占掉很多引脚,换 SWD 能省出 3 条,底板上正好用它们控制全彩 LED 或直流电机。

时基选 TIM4。 因为 TIM1、TIM2、TIM3 都被模块占用了。

三个项目#

音乐播放是第 9 个程序,接无源蜂鸣器,按三角符号播放或停止。

打砖块是核心。挡板可以用三种方式控制:摇晃板子、红外遥控器、旋转编码器。球碰到边缘会发声。

汽车游戏是第 17 个程序,遥控器上 1/2/3 键控制。

自己建一个 FreeRTOS 工程#

配套模板能直接用,自己从零建只是给想折腾的人。步骤记下来是因为坑都藏在细节里。

CubeMX 里:

① 新建工程,选 STM32F103C8T6(列表里有两个相近型号,选第一个)
② 时钟源使能 HSE 外部晶振;System Core → Debug 选 SWD;时基选 TIM4
③ 时钟树填 72,回车
④ Middleware → FreeRTOS,接口选 CMSIS_V2
其余保持默认:可抢占开着、tick 频率 1000、heap_4、堆大小默认(3072 字节)
⑤ 启动后默认已有一个 defaultTask,名字、栈、优先级都保持默认
⑥ Project Manager:工程名 01_FreeRTOS_my,IDE 选 MDK-ARM
Code Generator 勾上「把用到的库拷贝进工程」
⑦ 生成 → 编译 → 下载

第 ④ 步选的是 CMSIS_V2,所以生成出来的是 MX_FREERTOS_Init() + osKernelStart() 和默认任务 defaultTask,不是裸的 xTaskCreate。

第 ⑦ 步下载完什么都不会发生——工程里还没有任何操作硬件的代码,这是正常的。

加 LED 和 OLED#

LED 在 PC13。CubeMX 里配成 GPIO_Output、推挽输出、不用内部上下拉,生成后 MX_GPIO_Init 里已经配好了。

驱动文件从模板复制:

driver_led 两个文件,放到工程 driver/ 目录
driver_timer driver_led 里用了延时,要一起加

工程里新建 group(F2 改名 DShanMCU-F103),把文件加进去。编译报「找不到头文件」就去 Options → C/C++ → Include Paths 加上头文件目录。

然后在 defaultTask 里 #include "driver_led.h",在 USER CODE BEGIN 区调 led_test()。

OLED 走 I2C1、PB6/PB7。重新打开 CubeMX 的办法是双击工程里的 .ioc 文件,把 I2C1 使能,引脚会自动选上,参数保持默认。

驱动要复制三样:driver_oled、driver_lcd,还有字库文件。driver_lcd.c 只是对具体屏幕的封装,以后换屏只改它,上层统一用 driver_lcd.h 的函数。字库被其他文件包含,不需要在工程里手动添加;编译会有一堆警告,能用。

通用流程就四步:CubeMX 加配置 → 拷代码到工程 → 工程里添加文件 → 调用它的测试函数。

Reset and Run 这个坑#

第一次烧写 LED 程序后灯不闪。不是程序错,是 Flash Download 里的 Reset and Run 被取消了,芯片下载完没自动复位运行。重新上电就正常。

麻烦的是:每次重新生成代码,这个勾选都会掉一次,要重新去 Debug → Settings → Flash Download 里勾上。不知道这件事,很容易把「没反应」当成程序写错了。

坑#

  • 模块驱动不能拿来直接用。以 OLED 为例,驱动内部发命令实际是调 I2C1 控制器的发送函数,所以必须先让 CubeMX 把 I2C1 和引脚初始化好。
  • 每次重新生成代码后 Reset and Run 会掉,烧写后没反应先查这里。
  • 工程放在中文目录里,Keil 退出调试时会报错,挪到非中文路径就好。
  • MX_FREERTOS_Init() 里的 defaultTask 不是摆设,后面第二个任务是在它之外手动建的,别顺手删掉。
课程导览、硬件准备与工程搭建
https://me.622168.xyz/posts/freertos/01-course-setup/
作者
Shaw 的小屋
发布于
2026-09-29
许可协议
CC BY-NC-SA 4.0