STM32轮询定时器中断标志位不准
文章探讨了STM32定时器标志位轮询中的时序问题。作者发现一个看似无用的标志位赋值语句(flag_200hz=0)会微妙影响200Hz定时任务的执行节奏:保留该语句时,5ms定时发送正常;删除后发送间隔拉长至15ms。这揭示了在高频任务中,即使简单语句的执行耗时也会影响外设操作时序。最终建议采用定时器精准分频而非轮询方式,以确保时序准确性。案例展示了嵌入式开发中时序控制的精妙性和潜在陷阱。
STM32轮询定时器中断标志位
我们常常利用定时器的标志位,来给while循环中的代码一个时钟基准,做到定时触发某些任务。今天小编遇到了一个很神奇的现象,接下来给大家详细说说。
定时器配置

小编使用的是480M时钟,所以定时器是2000hz。
定时器中断回调函数

其中要说明的是AVG_COUNT = 10,当然也有人会说这个代码比较重复,分频明明能用一个变量进行。 I know, but I like it.
main函数

有请今天的主角,main函数,函数很直接,我们之前说过AVG_COUNT = 10,所以这是一个200hz分频处理过程,然后发送一包数据。我可以使用定时器,但我就想试一试在while循环中轮询中断。
![]()
这个200hz标志位就是我们最大的主角,大家一定觉得这行没什么作用,放这毫无意义,接下来我们看现象。 先说明:代码正确逻辑是5ms发送一帧数据,频率为200hz
注释flag_200hz = 0

保留flag_200hz = 0

还要说明的是flag_200hz 这个标志位,除了在上面的图中有所使用,其他没有任何地方使用。
想法
不知道大家看完上面的现象有没有疑惑,但我是充满了疑惑的,我认为,flag_200hz在当前代码片段中没有被其他逻辑使用,但它的 “执行耗时” 是真实影响代码时序的 —— 在高频触发的逻辑中,哪怕是一条简单的赋值语句,也可能改变整体执行节奏,进而影响外设操作的时序。 flag_200hz = 0的存在,相当于给每 5ms 一次的内层逻辑 “增加了极少量的执行时间”,这个时间差会影响send1000kHz的调用时机
- 保留时:执行节奏刚好匹配外设(比如 DMA、串口)的空闲时间,发送能按 5ms 间隔完成;
- 删除时:代码执行变快,send1000kHz被调用的时机与外设的 “忙状态” 冲突,只能等待外设空闲,最终表现为发送间隔被拉长到 15ms。
最后还是建议大家用定时器里精准分频吧
更多推荐
所有评论(0)