硬件中断是实现性能高效、实时控制的核心机制。
平时在STM32的项目开发中,中断应用是在项目开发文档里面写清楚的一项。这也是为了确保系统的稳定性、实时性和可维护性。
中断初始化
无论是定时器中断还是外部GPIO引脚中断(EXTI),其初始化流程都必须严谨,遗漏任何一步都可能导致中断无法触发,误触发等问题。
中断服务函数(ISR)编写规范
中断服务函数是硬件自动调用的特殊函数,编写时需遵守严格规范:
函数命名:必须与启动文件(startup_stm32f407xx.s)中定义的中断向量表名称完全一致(如 TIM2_IRQHandler 或 EXTI0_IRQHandler),否则链接器无法将中断事件指向你的代码。
清除中断标志:这是最关键的一步。进入 ISR 后,必须检查并清除相应的中断挂起标志位(如 TIM_ClearITPendingBit 或 EXTI_ClearITPendingBit)。若不清除,CPU 会认为中断请求依然存在,导致反复进入 ISR,造成程序“死锁”。
快进快出原则:
禁止在中断中执行耗时操作,如 delay 延时、printf 打印、复杂数学运算或大型循环。
禁卡在中断中进行内存动态分配。
推荐做法:在中断中仅置位标志变量(Flag)或读取关键数据,具体的业务逻辑处理应放在主循环(while(1))或操作系统任务中执行。
共享变量的保护与volatile关键字
当主程序和中断服务程序同时访问同一个全局变量时,必须注意数据一致性:
volatile 修饰:所有在中断中被修改、在主程序中读取的全局变量,必须使用 volatile 关键字修饰。这告诉编译器不要对该变量进行优化缓存,每次读取都直接从内存地址获取,防止因编译器优化导致读取到过期的旧值。
原子操作:如果主程序需要“读-改-写”变量的操作(如 对某变量进行某位的置位或清零操作),而中断可能随时修改它,建议在读取前暂时关闭中断(临界区保护),读取完成后立即开启,以防止读取过程中发生中断导致数据高低字节不一致。
NVIC 优先级配置策略
STM32 使用嵌套向量中断控制器(NVIC)管理中断优先级,合理配置可避免数据丢失和系统卡顿:
优先级分组:整个工程只能设置一次优先级分组(如 NVIC_PriorityGroup_2,即 2 位抢占,2 位子优先级)。通常在 main 函数最开始配置。
抢占 vs 子优先级:
抢占优先级:决定高优先级中断能否打断低优先级中断的执行(嵌套)。数值越小,优先级越高。
子优先级:当抢占优先级相同时,决定哪个中断先响应。子优先级高的先执行,但不能相互嵌套。
关键中断优先:对实时性要求极高的中断(如 CAN接收、电机控制反馈)应设置为高抢占优先级,防止被长时间运行的低优先级中断(如定时器计数)阻塞,从而避免数据丢失(如CAN缓冲区溢出)。
中断程序的实现对一个嵌入式项目的性能影响极大,建议在项目开发的时候先利用文档将中断程序涉及的事件与变量全部明示出来。
我要赚赏金
