【STM32学习】定时器寄存器配置、功能工作过程详解
零、参考
一、引言
本文针对STM32F103系列单片机的定时器进行介绍。
主要是其常用功能的工作流程、以及寄存器的对应配置。
该图清晰的表明了各种定时器的参数与功能。其中,基础定时器基本上就只有最简单的计数到了然后触发中断的功能;通用和高级定时器,在其基础上还有PWM输出、捕获/比较、刹车、死区设置等功能。图片来源
二、功能以及寄存器说明
1、最基本的定时功能(时基单元)
1.1 框图
这是截取了参考手册中三种定时器的款图,对于下半部分该功能涉及不到。
对于定时器的始终来源CK_INT,大家可以根据RCC时钟树,查看时钟源频率是多少。
从CK_INT到CK_PSC,三种类型的定时器基本都是一致的;从CK_PSC到最后的中断触发,不同的是高级定时器还有一个重复数据定时器。也就是说高级定时器,并不是当计数器溢出之后就立即触发中断,其还会经过重复计数器的操作才会被触发。
影子寄存器
:框图中带有阴影的寄存器,除了自己本体外,还有一个一模一样的影子寄存器。我们可以将本体理解为用来当作缓冲的,影子才是真正起作用的。为什么这样设计呢?比如,当定时器正在运行当中,此时ARR=36,CNT计数到32,就在这时,我们修改ARR为30,如果没有影子,那么CNT此时来说已经溢出了,会直接触发中断,但是很明显,由于我们的修改,怕破坏了当前定时器输出的周期,如果是PWM输出的话,在要求及其严格的场景下,可能会产生某些误差。所以增加了影子寄存器,当我们修改重要寄存器的时候会先放到本体寄存器,然后当当前周期结束时,才会由UEV事件触发,将本体中的设置放到影子中起作用。
从图中可以看出,当新值写入时,是先写入到本体,并未起作用。当当前运行周期结束后,才会将新值加载到影子中。
1.2 工作流程
对于基本和通用定时器:
PSC预分频器,根据设置的分频数,将CK_INT传递过来的时钟频率分频后,驱动CNT计数器计数。即计一个数的时间t是1/(TIMxCLK/(PSC+1))=(PSC+1)/TIMxCLK;那么将CNT中的数据计完,需要的时间为(ARR+1)*(PSC+1)/TIMxCLK。然后触发中断,ARR会将数据重新装到CNT中,然后执行中断服务函数。
例如,TIMXCLK=72MHz,PSC=7199,ARR=4999。则中断事件为t=(4999+1)*(7199+1)/ 72 * 1000000 = 0.5s,即500ms产生一次中断。注意时间与频率的关系。
而对于高级定时器:
当上述CNT计数溢出之后,并不是直接触发中断,而是触发重复计数器(RCR)计数,当RCR计数溢出之后,才会触发中断服务函数。
1.3 寄存器介绍
根据stm32固件库,我们可以看出,只需要对
时基初始化结构体 TIM_TimeBaseInitTypeDef
结构体进行配置能,就能实现最基本的定时器功能。
先看该结构体中有哪些东西:
再看初始化函数:
不难发现,使用的寄存器有:CR1、PSC、ARR、CNT、RCR、EGR。
其中CNT寄存器,在框图中出现了。
1.3.1 CR1寄存器
位0:计数器使能,必须开启
位1:是否允许中断差触发UEV,进而更新影子寄存器
位2:设置哪些事件能触发中断
位4-位6:5:计数方式的设置
位7:是否使用ARR的影子寄存器
1.3.2 CNT、PSC、ARR寄存器
这三个没什么好说的,知道如何计算中断时间就行。PSC和ARR的范围为1-65535。
1.3.3 EGR寄存器
对于高级和通用定时器,EGR寄存器还有很多其他功能,但是就对基本的使用来说,仅需设置这一位。
这一位什么意思呢?中断的产生都是硬件自动控制的(溢出等)。而这个是用来通过软件的方式触发中断或者事件更新的,进而将本体寄存器中的值放入到影子寄存器中。
例如,在固件库中,初始化的时候,这一位是设置为1的。即初始化的时候,立马触发一个中断,将该放的数据放到该放的位置。
1.3.4 RCR寄存器
该寄存器只有高级定时器才有。
所以,当用高级定时器来实现定时功能的时候,该位应该设置为0,否则,定时事件会感觉很长。固件库配置默认为0。
关于其最后两句话,通过下图很好理解。
1.3.5 DIER寄存器
在定时功能下,只需要设置最后一位。
在库函数中,TIM_ITConfig函数就是用来是遏制允许中断的。