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);

编译与下载

  1. 确认LED_PIN宏已正确定义为你的板载LED引脚号(如GET_PIN(B, 1))。
  2. 在RT-Thread Studio中直接编译下载,或使用Keil/arm-none-eabi-gcc编译后通过ST-Link烧录。
  3. 系统启动后,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字节通常足够,若使用浮点或大数组需增大)。
0ms 500ms 1000ms LED 亮 (500ms) LED 灭 (500ms) 1个周期 = 1秒 = 1Hz 线程运行中 线程挂起(延时) 线程运行中 循环