STM32 的中断(裸机开发)
STM32 的中断就像是 “紧急电话”,当某个硬件事件(比如按键按下、定时器到点、串口收到数据)发生时,CPU 会 暂停 当前的任务,立刻处理 这个紧急事件,处理完再回来继续原来的工作。
关键点:
中断源:
比如 GPIO 引脚电平变化、定时器溢出、UART 收到数据等,都能触发中断。
STM32 的中断向量表(
startup_stm32xxxxx.s
)定义了所有可能的中断。
中断优先级:
STM32 使用 NVIC(嵌套向量中断控制器)管理优先级。
优先级高的中断可以打断优先级低的中断(嵌套中断)。
中断处理函数(ISR):
在代码里写一个函数,比如
void USART1_IRQHandler()
,STM32 检测到中断后会自动跳转执行它。ISR 要尽量短,避免长时间占用 CPU,否则会影响其他中断和主程序。
中断开关:
HAL_NVIC_EnableIRQ(USART1_IRQn)
—— 开启中断HAL_NVIC_DisableIRQ(USART1_IRQn)
—— 关闭中断
FreeRTOS 的中断管理
FreeRTOS 是一个实时操作系统,它 仍然依赖 STM32 的中断机制,但增加了 任务调度 和 临界区保护,避免中断和任务互相干扰。
关键点:
FreeRTOS 如何管理中断?
FreeRTOS 提供了 “中断安全”的 API(以
FromISR
结尾的函数),比如xQueueSendFromISR()
,可以在中断里安全地发送数据给任务。普通任务 API(如
xQueueSend()
)不能在中断里用!
临界区保护(关中断):
taskENTER_CRITICAL()
—— 临时关闭中断(防止任务被中断打断)taskEXIT_CRITICAL()
—— 恢复中断适用于 保护共享数据(比如全局变量)。
任务和中断的交互:
中断发送信号量/队列 → 任务接收并处理(避免在中断里做复杂操作)。
例如:
// 在中断里发送数据 BaseType_t xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(xQueue, &data, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); // 如果需要,立即切换任务
中断优先级 vs FreeRTOS 优先级:
FreeRTOS 的 任务切换(PendSV) 通常设为 最低优先级,确保高优先级中断能立即响应。
SysTick 中断(系统心跳)负责 任务时间片调度。
对比总结
对比项 | STM32(裸机) | FreeRTOS |
---|---|---|
中断处理 | 直接写 ISR | 用 FromISR API |
任务切换 | 无 | 由 SysTick 和 PendSV 管理 |
临界区保护 | 手动开关中断 | taskENTER_CRITICAL() |
数据交互 | 全局变量(需保护) | 队列、信号量(更安全) |
大白话总结
STM32 中断:就像 “接紧急电话”,处理完就回去继续干活。
FreeRTOS 中断:在“接电话”时,还能 告诉任务(比如:“数据收到了,你去处理吧”),但 不能耽误太久,否则系统会卡住。
FreeRTOS 的优势:让中断和任务 安全协作,避免数据混乱,提高系统稳定性。
适用场景:
裸机中断:简单项目,比如 LED 闪烁、按键检测。
FreeRTOS 中断:复杂系统,比如多任务 + 网络通信 + 传感器数据处理。