你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的定时器中断使能

[复制链接]
攻城狮Melo 发布时间:2023-3-16 13:26
我们知道,STM32芯片里的ARM处理器都集成了1个24位向下计数的具备自动重装功能的SYSTICK定时器,功能比较单纯,就是计数定时。它常用来作为OS的滴答时钟,或者作为基本的计数时基。比方在各个RTOS系统里往往把SYSTICK作为滴答时钟,对于OS来讲,用它做时基可以提高代码移植方面的便利性,反正只要使用Arm核的芯片都有这个SYSTICK定时器。再比方,ST公司的HAL库一般默认将SYSTICK作为一个基本的延时功能定时器,那个库函数HAL_Delay()就是用SYSTICK实现计数延时,一般默认设置为每毫秒中断1次。
" C5 n! R" \5 \
因为SYSTICK定时器属于核外设,所以在STM32芯片的参考手册里并没有很仔细的介绍,关于它的介绍需要查看ARM公司提供的相关内核的技术手册。
' V$ R9 r! L8 ^: x  Y8 P' W
其大致工作架构如下:3 x& \4 e! I: j
微信图片_20230316131254.png
每次计数器发生从1记到0时进行计数器的重装并开启下轮计数,此时COUNTFLAG标志被置位并可以触发中断。SYSTICK定时器涉及到4个主要的寄存器,分别是SYSTICK控制寄存器、重装值寄存器、计数器值寄存器、校准值寄存器。这里重点看看前3个。
微信图片_20230316131247.png

  p9 N' D5 K8 t: x
其中,计数器值寄存器自然是体现任一时刻计数器的值,对它的写操作都会让其计数器值清零,同时使得COUNTFLAG【控制寄存器的一位】被清零。重装值寄存器盛放计数器每次向下记到0时要重装的起始值,结合时钟一起决定计数周期长短。4 J- J, M# L6 p& C8 _0 N
对SYSTICK定时器的计数器进行启、停操作,SYSTICK定时中断的使能、关闭操作以及对SYSTICK时钟源的选择就由SYSTICK控制寄存器掌控,其中起作用的就是4个位,参考下图:
# X/ e* \7 j% S& k4 W! h& H: W1 ]

# p$ L, w5 C/ Q% l
微信图片_20230316131239.png
+ H5 I8 x; B& l
BIT0【ENABLE】掌控SYSTICK计数器的启动、停止,类似于STM32外设定时器控制寄存器里的CEN位。8 ?+ b- }* j7 J5 W# Q3 \: P' q
BIT1【TICKINT】掌控SYSTICK中断请求的使能、禁用,类似于STM32各个外设事件的中断请求使能控制位。
* x# g8 X! k+ E
BIT3【ClockSource】掌控SYSTICK时钟源的选择。
BIT4【COUNTFLAG】是状态标志位,当计数器从1记到0时该位被置1,可以读清零。
我们在STM32应用中,尤其基于CubeMx配置生成基于HAL库的工程时,SYSTICK定时器默认打开,并开启1ms的周期性中断。有时,如果我希望关闭或临时关闭SYSTICK的中断请求,即不希望它产生中断请求,如何操作呢?
既然是不希望SYSTICK产生中断请求,自然会想到直接关闭其中断请求使能,即对上面控制寄存器中的TICKINT位进行清零。) |* b4 X! i5 g9 o0 O$ g$ p

; Y+ D2 d# h% L# b2 w  b# b
微信图片_20230316131234.png
5 x3 h+ y- F7 b  `( \( G
  |5 d6 u% @$ p% M5 k: p2 {
如果基于STM32库定义的写法可以是这样:
. y5 l  C3 ]9 D$ g; y; z* ?& D
SysTick->CTRL &=~SysTick_CTRL_TICKINT_Msk;
一般来讲,关闭SYSTICK的中断功能后其计数定时功能往往也不太需要了,即使需要也不太方便使用。既然这样,我们也可以通过关闭SYSTICK的计数功能进而阻止基于硬件计数事件的中断请求产生。【我为什么加个基于硬件计数事件呢,是因为很多中断请求都可以基于软件方式产生】,基于STM32库定义的写法可以是这样:
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
当然,对于关闭SYSTICK计数器的做法除了直接对控制寄存器的计数使能位清零外,还有个比较快捷省事的做法,那就是直接对其重装寄存器写0值,即像下面这样操作:
SysTick->LOAD  = 0 ;  
这个时候,SYSTICK将不做计数动作,自然也不会产生计数溢出而触发中断请求。
为什么我前面强调“基于STM32库定义的写法”呢?是因为有关SYSTICK的寄存器的命名,STM32库定义的跟ARM技术手册命名不一样。ARM的命名是这样的:

  M' y$ y) Q' e$ t
微信图片_20230316131229.png
- Q! @- z7 f' D% X$ V( M+ z
而STM32库定义的寄存器命名是这样的:

8 |# J+ S6 D% M3 H- O: D( C; p5 D  h
微信图片_20230316131222.png
" i8 M4 q: d& ~9 w$ ^
当然这个命名只是符号上的差异,最终对应的访问地址都是一样的。个人觉得ST库定义的更直观、易记、易识别点。
上面说的都是基于不同方式如何关闭SYSTICK的中断请求,开启只是个逆过程而已,无须赘述。
前面重点介绍了从外设端如何关闭SYSTICK中断请求,令其不向内核申请中断。至于如何从内核端使能或禁止对其做出响应,那是NVIC控制器的事了。比方,在STM32的HAL库函数里,HAL_NVIC_EnableIRQ()和HAL_NVIC_DisableIRQ()就是用来针对特定中断请求做允许响应和禁止响应的设定。关于从外设端开关中断请求和从内核端开关中断响应的关系以及行为差异,我们下次找机会再聊。

9 _$ v* @' \$ n" Q( S1 u
转载自: [color=var(--weui-FG-2)]Miler
[color=var(--weui-FG-2)]
如有侵权请联系删除
$ Y- F# @' s$ g

4 y0 o, B6 Y. `) Z4 U* V& S0 Q
收藏 评论0 发布时间:2023-3-16 13:26

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版