STM32F0x定时器之计数器模式

向上计数模式

在递增计数模式下,计数器从0计数到自动重载值(TIMx_ARR寄存器的内容),然后从0重新开始计数,并产生一个计数器溢出事件。

如果使用重复计数器,则在递增计数器重复了重复计数器寄存器(TIMx_RCR)中所编程的次数后,会产生更新事件(UEV)。否则,每次计数器溢出时都会产生更新事件。

设置 TIMx_EGR 寄存器的 UG 位(通过软件或从机模式控制器)也会产生一个更新事件。

UEV 事件可以通过软件将 TIMx_CR1 寄存器的UDIS位置位来禁用。这是为了避免在预载寄存器中写入新值时更新影子寄存器。那么在UDIS位被写入0之前,不会发生更新事件。然而,计数器会从0重新开始,预分频器的计数器也是如此(但预分频率不变)。此外,如果 TIMx_CR1 寄存器中的URS位(更新请求选择)被置位,则置位UG位会产生一个更新事件UEV,但不会置位UIF标志(因此不会发送中断或DMA请求)。这是为了避免在清除捕获事件计数器时同时产生更新和捕获中断。

发生更新事件时,所有寄存器都会更新,更新标志( TIMx_SR 寄存器中的UIF位)也会被置位(取决于URS位):

  • 重复计数器被重新载入 TIMx_RCR 寄存器的内容,
  • 自动重装载影子寄存器用预加载值(TIMx_ARR)更新,
  • 预分频器的缓冲器重新载入预载值(TIMx_PSC 寄存器的内容)。

下面的这两张图至关重要,涉及到 TIMx_ARR 寄存器动态改变后,计数器时序图如何变化。这里面,前面的文章(STM32F0x高级定时器简介)中多次提到的TIMx_CR1中的ARPE位,将发挥重要作用。

图47,计数器时序图,当ARPE=0时更新事件(TIMx_ARR未预加载)
图47,计数器时序图,当ARPE=0时更新事件(TIMx_ARR未预加载)
先看图47,TIMx_ARR的值更新后,自动重载预装载寄存器的值立即更新(最后一行)。TIMx_ARR原来的值是0xff,那么第四行的Counter寄存器应该计数到0xff才产生溢出,但是在计数器计数到0x32的时候,TIMx_ARR被更新到了0x36,图中这个设置是立即生效的,因为接下来第五行的定时器的溢出事件并没有计数到原来的0xff,而是直接在计数到0x36这个新设置的值后就重新开始跑了。这要归功于最重要的一项设置,就是ARPE=0,意思就是不要预加载,改动立即生效(其实前面的文章已经讲过,就是让ARR的预加载寄存器立即更新到影子寄存器)。

图48,计数器时序图,当ARPE=1时更新事件(TIMx_ARR预加载)
图48,计数器时序图,当ARPE=1时更新事件(TIMx_ARR预加载)
再看图48,最重要的一项改动,就是ARPE=1。原先TIMx_ARR的值为0xf5,但在第四行定时器的计数器跑到0xf1的时候,ARR被改到了0x36,请看图,这个改动立即生效了吗?这时Counter的值(0xf1)大于了ARR的预加载值(0x36),但时序图中的第五行并没有在这个时刻发生定时器溢出事件,第四行的计数器也没有被复位,而是继续跑。同时自动重装载影子寄存器也没有被更新,还是0xf5。而是要等到什么时候?等到计数器跑到原先值0xf5后这一切才被更新!

所以,ARPE是干啥的?之前网上搜了大量文章硬是没搜出个名堂,现在终于解惑了!它就是对ARR预加载,不让改动立即生效,而是等到下一个更新事件到来,再把这个值传输到影子寄存器。

向下计数模式

在递减计数模式下,计数器从自动重载值(TIMx_ARR寄存器的内容)递减计数至0,然后从自动重载值重新开始计数,并产生一个计数器下溢事件。

如果使用重复计数器,则在递减计数重复了重复计数器寄存器(TIMx_RCR)中设置的次数后,会产生更新事件(UEV)。否则,在每次计数器下溢时产生更新事件。

设置TIMx_EGR寄存器的UG位(通过软件或从机模式控制器)也会产生一个更新事件。

UEV更新事件可以被软件禁用,通过设置TIMx_CR1寄存器的UDIS位。这是为了避免在预载寄存器中写入新值时更新影子寄存器。那么在UDIS位被写入0之前,不会发生更新事件。然而,计数器从当前自动重载值重新启动,而预分频器的计数器从0重新启动(但预分频率不变)。

此外,如果TIMx_CR1寄存器中的URS位(更新请求选择)被置位,则置位UG位会产生一个更新事件UEV,但不会置位UIF标志(因此不会发送中断或DMA请求)。这是为了避免在清除捕获事件计数器时同时产生更新和捕获中断。

发生更新事件时,所有寄存器都会更新,更新标志(TIMx_SR寄存器中的UIF位)也会置位(取决于URS位):

  • 重复计数器重新载入TIMx_RCR寄存器的内容
  • 预分频器的缓冲器重新载入预载值(TIMx_PSC寄存器的内容)
  • 自动重载有效寄存器用预载值(TIMx_ARR寄存器的内容)更新。请注意,自动重载是在计数器重载之前更新的,因此下一个周期是预期的周期。(这句话的意思是说,先更新ARR,再更新CNT)

中心对齐模式(向上/向下计数)

在中心对齐模式下,计数器从0计数到自动重载值(TIMx_ARR寄存器的内容)–1,产生一个计数器溢出事件,然后从自动重载值倒计数到1,并产生一个计数器下溢事件。然后它从0开始重新计数。

当TIMx_CR1寄存器中的CMS位不等于'00'时,中心对齐模式生效。输出中配置的通道的输出比较中断标志在以下情况下置位:计数器递减计数(中心对齐模式1,CMS = "01"),计数器递增计数(中心对齐模式2,CMS = "10"),计数器递增计数和递减计数(中心对齐模式3,CMS = "11")。这里千万别被这个CMS位的这三种模式误解,虽然有三种模式,但计数器都是交替地向上和向下计数,只是输出比较中断标志什么时候被置位的区别,可以看寄存器手册中的相关定义,如下:

CMS[1:0]: 居中对齐模式选择

  • 00: 边缘对齐模式。计数器根据方向位(DIR)递增或递减计数。
  • 01: 居中对齐模式1。计数器交替上下计数。仅当计数器递减计数时,才会设置输出中配置的通道的输出比较中断标志(TIMx_CCMRx寄存器中的CCxS=00)。
  • 10: 居中对齐模式2。计数器交替上下计数。仅当计数器递增计数时,才会设置输出中配置的通道的输出比较中断标志(TIMx_CCMRx寄存器中的CCxS=00)。
  • 11: 居中对齐模式3。计数器交替上下计数。计数器递增计数或递减计数时,输出中配置的通道的输出比较中断标志(TIMx_CCMRx寄存器中的CCxS=00)都会置位。

注意:只要计数器使能(CEN=1),就不允许从边缘对齐模式切换到中心对齐模式。

在这种模式下,TIMx_CR1寄存器中的DIR方向位不能写入。它由硬件更新并给出计数器的当前方向。

每次计数器上溢和下溢时都会产生更新事件,或者通过设置TIMx_EGR寄存器中的UG位(通过软件或使用从机模式控制器)也会产生更新事件。这种情况下,计数器从0开始重新计数,预分频器的计数器也是如此。

通过设置TIMx_CR1寄存器的UDIS位,软件可以禁用UEV更新事件。这是为了避免在预载寄存器中写入新值时更新影子寄存器。那么在UDIS位被写入0之前,不会发生更新事件。但是,计数器会根据当前的自动重装载值继续上下计数。

此外,如果TIMx_CR1寄存器中的URS位(更新请求选择)被置位,则置位UG位会产生UEV更新事件,但不会置位UIF标志(因此不会发送中断或DMA请求)。这是为了避免在清除捕获事件计数器时同时产生更新和捕获中断。

发生更新事件时,所有寄存器都会更新,更新标志(TIMx_SR寄存器中的UIF位)也会置位(取决于URS位):

  • 重复计数器重新载入TIMx_RCR寄存器的内容
  • 预分频器的缓冲器重新载入预载值(TIMx_PSC寄存器的内容)
  • 自动重载有效寄存器用预载值(TIMx_ARR寄存器的内容)更新。请注意,如果更新源是计数器溢出,则自动重装载值会在计数器重新加载之前更新,因此下一个周期就会是预期周期(计数器加载新值)。

图54,计数器时序图,内部时钟除以1,TIMx_ARR = 0x6
图54,计数器时序图,内部时钟除以1,TIMx_ARR = 0x6
图中使用的是中心对齐模式1,UIF仅在计数器递减到1的时候产生中断。且可以看出,计数器是交替上下计数的。文章来源地址https://uudwc.com/A/EyOzo

原文地址:https://blog.csdn.net/hjf789/article/details/129816139

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年08月08日 04:01
STM32CubeIDE如何实现HAL库 微秒Us延迟(HAL_Us_Delay)
下一篇 2023年08月08日 04:03