STM32 怎么实现多任务?裸机该怎么做?

STM32 · 4 浏览
STM32 怎么实现多任务?裸机该怎么做?

回答(4)

裸机多任务最怕任务里用HAL_Delay,一卡全卡。建议把所有延时都改成基于tick的非阻塞等待。
STM32玩家 · 2026-08-17
如果任务间有共享变量,记得加临界区保护,比如关中断或使用原子操作,不然会数据错乱。
码农小刘 · 2026-08-17
我一般用定时器中断+主循环轮询,但注意tick_ms要声明为volatile,否则编译器优化会出问题。
嵌入式老张 · 2026-08-17
在STM32裸机环境下实现多任务,核心是**时间片轮询**和**状态机**。不要用阻塞式延时(如HAL_Delay),它会卡死CPU。 **1. 时间片轮询(超级循环+定时器)** 用SysTick或TIM定时器产生1ms中断,在中断里递增一个全局tick计数。主循环中,每个任务检查自己的时间片是否到达,到达则执行非阻塞逻辑。 ```c volatile uint32_t tick_ms; void SysTick_Handler(void) { tick_ms++; } #define TASK1_PERIOD 10 // 10ms #define TASK2_PERIOD 50 // 50ms void main_loop() { uint32_t last1 = 0, last2 = 0; while(1) { if (tick_ms - last1 >= TASK1_PERIOD) { last1 = tick_ms; task1_run(); } if (tick_ms - last2 >= TASK2_PERIOD) { last2 = tick_ms; task2_run(); } // 其他低优先级任务 } } ``` **2. 状态机** 对于复杂任务(如按键扫描、通信协议),用switch-case实现状态转移,每个状态只做一小步,不阻塞。 **实操建议**: - 避免在任务里使用长循环或等待;若必须等待,用非阻塞查询+超时。 - 中断里只做标记,不做耗时处理。 - 若任务数多且优先级复杂,可考虑引入RTOS(如FreeRTOS),但裸机够用就别上。 **3. 协作式调度** 可简单实现一个函数指针数组作为任务表,按顺序轮询,每个任务返回是否完成。 记住:裸机多任务本质是“伪并行”,靠快速切换和状态保存实现。
mcuku 阿沐 · 2026-08-17