1. LED闪烁控制
任务目标
在STM32平台上使用RT-Thread操作系统,创建一个动态线程,控制板载LED以1Hz频率(即500ms翻转一次)闪烁。通过本案例掌握rt_thread_create、rt_thread_startup以及rt_thread_mdelay的核心用法。
硬件与工程准备
- 硬件:任意带板载LED的STM32开发板(如STM32F407探索板、正点原子/野火系列),LED接GPIO输出引脚。
- 软件:RT-Thread Studio 或已有RT-Thread Nano移植工程(包含
board.c中已初始化LED GPIO)。 - 依赖:RT-Thread内核(线程调度、时钟节拍),无需额外软件包。
关键完整代码
在main.c中实现如下逻辑。若你的工程已有LED驱动函数,请将led_on/led_off替换为实际寄存器操作或HAL函数。
#include <rtthread.h>
#include "board.h" // 包含LED引脚定义
/* 假设LED低电平点亮,若高电平点亮请反转逻辑 */
#define LED_ON() rt_pin_write(LED_PIN, PIN_LOW)
#define LED_OFF() rt_pin_write(LED_PIN, PIN_HIGH)
/* 线程入口函数 */
static void led_thread_entry(void *parameter)
{
while (1)
{
LED_ON();
rt_thread_mdelay(500); /* 亮500ms */
LED_OFF();
rt_thread_mdelay(500); /* 灭500ms,合计周期1s = 1Hz */
}
}
/* 线程控制块与栈(静态方式更省资源,也可用动态创建) */
static struct rt_thread led_thread;
static rt_uint8_t led_thread_stack[256];
int main(void)
{
/* 初始化LED引脚为输出 */
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
LED_OFF();
/* 静态初始化线程:名称、入口、栈、优先级、时间片 */
rt_thread_init(&led_thread,
"led",
led_thread_entry,
RT_NULL,
&led_thread_stack[0],
sizeof(led_thread_stack),
20, /* 优先级,数值越小优先级越高 */
10); /* 时间片(仅同优先级轮转时有效) */
rt_thread_startup(&led_thread);
return 0;
}
说明:若你的工程使用动态线程创建,可用以下方式替代rt_thread_init部分:
rt_thread_t tid = rt_thread_create("led",
led_thread_entry,
RT_NULL,
256, /* 栈大小 */
20, /* 优先级 */
10); /* 时间片 */
if (tid != RT_NULL)
rt_thread_startup(tid);
编译与下载
- 确认
LED_PIN宏已正确定义为你的板载LED引脚号(如GET_PIN(B, 1))。 - 在RT-Thread Studio中直接编译下载,或使用Keil/arm-none-eabi-gcc编译后通过ST-Link烧录。
- 系统启动后,
main函数创建并启动LED线程,随后main退出(RT-Thread中main作为初始化线程结束,不影响其他线程运行)。
验证方法与判定标准
- 现象验证:板载LED以1Hz频率闪烁(每秒亮灭各一次),周期稳定无漂移。
- 系统验证:在串口控制台(若启用FinSH)输入
list_thread,应能看到名为led的线程处于suspend状态(因延时挂起),优先级为20。 - 通过条件:LED闪烁频率肉眼判断约为1Hz(可用秒表对比10次闪烁耗时约10秒),且系统无崩溃或看门狗复位。
常见问题
- LED不亮:检查
LED_PIN引脚号是否正确,以及GPIO初始化是否在main中执行。 - 闪烁频率不对:确认
rt_thread_mdelay参数单位为毫秒,500ms×2=1s周期。 - 线程未运行:检查优先级数值是否合法(RT-Thread有效范围0~255,数值越小优先级越高),且栈大小是否足够(256字节通常足够,若使用浮点或大数组需增大)。