一、通用定时器简介
STM32F407 有 10 个通用定时器(TIM2 ~ TIM5 和 TIM9 ~ TIM14)。这些定时器彼此完全独立,不共享任何资源。其主要特性如下:16 位递增、递减、中心对齐计数器(计数值:0 ~ 65535),16 位可编程预分频器(预分频系数:1 ~ 65536),用于对计数器时钟频率进行分频,还可以触发 DAC、ADC的同步电路,以及在更新事件、触发事件、输入捕获、输出比较时,会生成中断/DMA 请求。它有 4 个独立通道,可用于:输入捕获、输出比较、输出 PWM 、单脉冲模式等。可以使用外部信号控制定时器且可以实现多个定时器互连的同步电路。它支持编码器和霍尔传感器电路等。
STM32 芯片的计数器大多数都是 16 位的。通用定时器和高级定时器其实也就是在基本定时器的基础上,添加了一些其他功能,如:输入捕获、输出比较、输出 PWM 和单脉冲模式等。而通用定时器数量较多,其特性也有一些的差异,但是基本原理都一样。
二、通用定时器框图
①、时钟源
通用定时器时钟可以选择下面四类时钟源之一:
- 内部时钟(CK_INT)
- 外部时钟模式 1:外部输入引脚(TIx),x=1,2(即只能来自于通道 1 或者通道 2)
- 外部时钟模式 2:外部触发输入(ETR)
- 内部触发输入(ITRx):使用一个定时器作为另一定时器的预分频器
通用定时器时钟源的设置方法如下表所示:
【1】、内部时钟(CK_INT)
STM32F4 系列的定时器 TIM2 ~ TIM7、TIM12 ~ TIM14 都是挂载在 APB1 总线上,这些定时器的内部时钟(CK_INT)实际上来自于 APB1 总线提供的时钟。但是这些定时器时钟不是由 APB1 总线直接提供,而是要先经过一个倍频器。在,系统时钟初始化函数 System_Clock_Init() 已经设置 APB1 总线时钟频率为 42MHz,APB1 预分频器的预分频系数为 2,所以这些定时器时钟源频率为 84MHz。因为当 APB1 预分频器的预分频系数≥2 分频时,挂载在 APB1 总线上的定时器时钟频率是该总线时钟频率的两倍。
APB2 总线上挂载的通用定时器 TIM9 ~ TIM11,挂载的总线变成了 APB2,在系统时钟初始化函数 System_Clock_Init() 已经设置 APB2 总线时钟频率为 84MHz,预分频器的预分频系数为 2,所以上述的定时器时钟源频率为 168MHz。
【2】、外部时钟模式 1(TI1、TI2)
外部时钟模式 1 这类时钟源,顾名思义时钟信号来自芯片外部。时钟源进入定时器的流程如下:外部时钟源信号 → IO → TIMx_CH1(或者 TIMx_CH2)
,这里需要注意的是:外部时钟模式 1 下,时钟源信号只能从 CH1 或者 CH2 输入到定时器,CH3 和 CH4 都是不可以的。从 IO 到 TIMx_CH1(或者 TIMx_CH2),就需要我们配置 IO 的复用功能,才能使 IO 和定时器通道相连通。
时钟源信号 TI2 到达 CH2 后,来到定时器内部,TI2 首先经过一个滤波器,由 ICF[3:0]位来设置滤波方式,也可以设置不使用滤波器。接着经过边沿检测器,由 CC2P 位来设置检测的边沿,可以上升沿或者下降沿检测。然后经过触发输入选择器,由 TS[4:0] 位来选择 TRGI(触发输入信号)的来源。
可以看到图中框出了 TI1F_ED、TI1FP1 和 TI2FP2 三个触发输入信号(TRGI)。TI1F_ED 表示来自于 CH1,并且没有经过边沿检测器过滤的信号,所以它是 CH1 的双边沿信号,即上升沿或者下降沿都是有效的。TI1FP1 表示来自 CH1 并经过边沿检测器后的信号,可以是上升沿或者下降沿。TI2FP2 表示来自 CH2 并经过边沿检测器后的信号,可以是上升沿或者下降沿。这里以 CH2 为例,那只能选择 TI2FP2。如果是 CH1 为例,那就可以选择 TI1F_ED 或者 TI1FP1。
最后经过从模式选择器,由 ECE 位和 SMS[2:0] 位来选择定时器的时钟源。这里我们介绍的是外部时钟模式 1,所以 ECE 位置 0,SMS[2:0]=111 即可。CK_PSC 需要经过定时器的预分频器分频后,最终就能到达计数器进行计数了。
【3】、外部时钟模式 2(ETR)
外部时钟模式 2,时钟信号来自芯片外部。时钟源进入定时器的流程如下:外部时钟源信号 → IO → TIMx_ETR
。从 IO 到 TIMx_ETR,就需要我们配置 IO 的复用功能,才能使 IO 和定时器相连通。
定时器时钟信号首先从 ETR 引脚进来。接着经过外部触发极性选择器,由 ETP 位来设置上升沿有效还是下降沿有效,选择下降沿有效的话,信号会经过反相器。然后经过外部触发预分频器,由 ETPS[1:0] 位来设置预分频系数,系数范围:1、2、4、8。紧接着经过滤波器器,由 ETF[3:0] 位来设置滤波方式,也可以设置不使用滤波器。\(f_{DTS}\) 由 TIMx_CR1 寄存器的 CKD 位设置。最后经过从模式选择器,由 ECE 位和 SMS[2:0]位来选择定时器的时钟源。这里我们介绍的是外部时钟模式 2,直接把 ECE 位置 1 即可。CK_PSC 需要经过定时器的预分频器分频后,最终就能到达计数器进行计数了。
【4】、内部触发输入(ITRx)
内部触发输入是使用一个定时器作为另一个定时器的预分频器,即实现定时器的级联。
上图中,TIM1 作为 TIM2 的预分频器,需要完成的配置步骤如下:
- TIM1_CR2 寄存器的 MMS[2:0] 位设置为 010,即 TIM1 的主模式选择为更新(选择更新事件作为触发输出 (TRGO))。
- TIM2_SMCR 寄存器的 TS[2:0]位设置为 000,即使用 ITR1 作为内部触发。TS[2:0] 位用于配置触发选择
除了 ITR1,还有其他的选择,详细描述如下图所示:
②、控制器
控制器包括:从模式控制器、编码器接口和触发控制器(TRGO)。从模式控制器可以控制计数器复位、启动、递增/递减、计数。编码器接口针对编码器计数。触发控制器用来提供触发信号给别的外设,比如为其它定时器提供时钟或者为 DAC/ADC 的触发转换提供信号。
③、时基单元
时基单元包括:计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR) 。这部分内容和基本定时器基本一样的。
不同点是:通用定时器的计数模式有三种:递增计数模式、递减计数模式 和 中心对齐模式;
递增计数模式可以参考基本定时器篇章。
递减计数模式 就是来了一个计数脉冲,计数器就减 1,直到计数器寄存器的值减到 0,减到 0 时定时器溢出,由于是递减计数,故而称为 定时器下溢,定时器溢出就会伴随着更新事件的发生。然后计数器又从自动重载寄存器影子寄存器的值开始继续递减计数,如此循环。
最后是 中心对齐模式,该模式下,计数器先从 0 开始递增计数,直到计数器的值等于自动重载寄存器影子寄存器的值减 1 时,定时器上溢,同时生成更新事件,然后从自动重载寄存器影子寄存器的值开始递减计算,直到计数值等于 1 时,定时器下溢,同时生成更新事件,然后又从 0 开始递增计数,依此循环。每次定时器上溢或下溢都会生成更新事件。计数器的计数模式的设置请参考 TIMx_CR1 寄存器的位 CMS 和位 DIR。
④、输入捕获
输入捕获,一般应用是要和第 ⑤ 部分一起完成测量功能。TIMx_CH1 ~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通过复用功能与这些通道相连。配置好 IO 端口的复用功能后,将需要测量的信号输入到相应的 IO 端口,输入捕获部分可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常见的测量有:测量输入信号的脉冲宽度、测量 PWM 输入信号的频率和占空比等。
测量高电平脉冲宽度的工作原理:一般先要设置输入捕获的边沿检测极性,如:我们设置上升沿检测,那么当检测到上升沿时,定时器会把计数器 CNT 的值锁存到相应的捕获/比较寄存器 TIMx_CCRy 里,y=1~4。然后我们再设置边沿检测为下降沿检测,当检测到下降沿时,定时器会把计数器 CNT 的值再次锁存到相应的捕获/比较寄存器 TIMx_CCRy 里。最后,我们将前后两次锁存的 CNT 的值相减,就可以算出高电平脉冲期间内计数器的计数个数,再根据定时器的计数频率就可以计算出这个高电平脉冲的时间。如果要测量的高电平脉宽时间长度超过定时器的溢出时间周期,就会发生溢出,这时候我们还需要做定时器溢出的额外处理。低电平脉冲捕获同理。
待测量信号 TI1 到达 TIMx_CH1 后,TI1 首先经过一个滤波器,由 ICF[3:0] 位来设置滤波方式,也可以设置不使用滤波器。fDTS 由 TIMx_CR1 寄存器的 CKD 位设置。接着经过边沿检测器,由 CC1P 位来设置检测的边沿,可以上升沿或者下降沿检测。(CC1NP 是配置互补通道的边沿检测的,在高级定时器才有,通用定时器没有。)然后经过输入捕获映射选择器,由 CC1S[1:0] 位来选择把 IC1 映射到 TI1、TI2 还是 TRC。这里我们的待测量信号从通道 1 进来,所以选择 IC1 映射到 TI1 上即可。紧接着经过输入捕获 1 预分频器,由 ICPS[1:0] 位来设置预分频系数,范围:1、2、4、8。最后需要把 CC1E 位置 1,使能输入捕获,IC1PS 就是分频后的捕获信号。
首先看到捕获/比较预装载寄存器,我们以通道 1 为例,那么它就是 CCR1 寄存器,通道 2、通道 3、通道 4 就分别对应 CCR2、CCR3、CCR4。在图中就可以看到 CCR1 ~ 4 是有影子寄存器的,该寄存器不可直接访问。
图左下角的 CC1G 位可以产生软件捕获事件,那么硬件捕获事件如何产生的?这里我们还是以通道 1 输入为例,CC1S[1:0] = 01,即 IC1 映射到 TI1 上;CC1E 位置 1,使能输入捕获;比如不滤波、不分频,ICF[3:0] = 00,ICPS[1:0] = 00;比如检测上升沿,CC1P 位置 0;接着就是等待测量信号的上升沿到来。当上升沿到来时,IC1PS 信号就会触发输入捕获事件发生,计数器的值就会被锁存到捕获/比较影子寄存器里。当 CCR1 寄存器没有被进行读操作的时候,捕获/比较影子寄存器里的值就会锁存到 CCR1 寄存器中,那么程序员就可以读取 CCR1 寄存器,得到计数器的计数值。检测下降沿同理。
⑤、输入捕获和输出比较公用部分
该部分需要结合第 ④ 部分或者第 ⑥ 部分共同完成相应功能。
⑥、输出比较
图中的第 ⑥ 部分是输出比较,一般应用是要和第 ⑤ 部分一起完成定时器输出功能。TIMx_CH1 ~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通过复用功能与这些通道相连。
首先程序员写 CCR1 寄存器,即写入比较值。这个比较值需要转移到对应的捕获/比较影子寄存器后才会真正生效。什么条件下才能转移?图中可以看到 compare_transfer 旁边的与门,需要满足三个条件:CCR1 不在写入操作期间、CC1S[1:0] = 0 配置为输出、OC1PE 位置 0(或者 OC1PE 位置 1,并且需要发生更新事件,这个更新事件可以软件产生或者硬件产生)。当 CCR1 寄存器的值转移到其影子寄存器后,新的值就会和计数器的值进行比较,它们的比较结果将会通过第⑥部分影响定时器的输出。
上图中,可以看到输出模式控制器,由 OC1M[2:0]位配置输出比较模式。F4 系列有 8 种输出比较模式之多。oc1ref 是输出参考信号,高电平有效,为高电平时称之为有效电平,为低电平时称之为无效电平。它的高低电平受到三个方面的影响:OC1M[3:0]位配置的输出比较模式、第 ⑤ 部分比较器的比较结果、还有就是 OC1CE 位配置的 ETRF 信号。ETRF 信号可以将 oc1ref 电平强制清零,该信号来自 IO 外部。
一般来说,当计数器的值和捕获/比较寄存器的值相等时,输出参考信号 oc1ref 的极性就会根据我们选择的输出比较模式而改变。如果开启了比较中断,还会发生比较中断。
- CC1P 位用于选择通道输出极性。
- CC1E 位置 1 使能通道输出。
- OC1 信号就会从 TIMx_CH1 输出到 IO 端口,再到 IO 外部。
三、通用定时器常用寄存器
3.1、TIMx控制寄存器
TIMx_CR1 寄存器位 7(ARPE)用于控制自动重载寄存器是否进行缓冲,如果 ARPE 位置 1,ARR 起缓冲作用,即只有在更新事件发生时才会把 ARR 的值写入其影子寄存器里;如果 ARPE 位置 0,那么修改自动重载寄存器的值时,该值会马上被写入其影子寄存器中,从而立即生效。
TIMx_CR1 寄存器 CMS[6:5] 位,用于设置边沿对齐模式还是中心对齐模式。当 CMS[1:0] 位设置为 00 时,为边沿对齐模式,其它值为中心对齐模式。
TIMx_CR1 寄存器位 4 DIR 位,用于控制定时器的计数方向。设置 DIR 位为 0 时,为递增计数。设置 DIR 位为 1 时,为递减计数。当定时器配置为中心对齐模式或编码器模式时,该位为只读状态。
TIMx_CR1 寄存器位 0 CEN 位,用于使能计数器的工作,必须要设置该位为 1,计数器才会开始计数。
3.2、TIMx从模式控制寄存器
该寄存器的 SMS[2:0]位,用于从模式选择,其实就是选择计数器输入时钟的来源。比如通用定时器中断例程中我们设置 SMS[2:0]=000,禁止从模式,这样 PSC 预分频器的时钟就直接来自内部时钟(CK_INT),按照我们例程 System_Clock_Init() 函数的配置,频率为 84Mhz(APB1 总线时钟频率的 2 倍)。
3.3、TIMx DMA中断/使能寄存器
该寄存器用于使能/失能触发 DMA 请求、捕获/比较中断以及更新中断。如果我们要使用更新中断,所以把位 0(UIE)置 1 即可。
3.4、TIMx状态寄存器
该寄存器都是一些中断标志位,比如更新中断标志位、捕获/比较中断标志位等。在通用定时器中断例程中我们用到更新中断标志位,当定时器更新中断到来后,位 0(UIF)会由硬件置 1,我们需要在中断服务函数里面把该位清零。
3.5、TIMx事件生成寄存器
该寄存器作用是让用户用软件方式产生各类事件。UG 位是更新事件的控制位,作用和定时器溢出时产生的更新事件一样,区别是这里是通过软件产生的,而定时器溢出是硬件自己完成的。只有开启了更新中断,这两种方式都可以产更新中断。
3.6、TIMx捕获/比较模式寄存器
该寄存器的有些位在不同模式下,功能不一样。比如我们要让 TIM14 的 CH1 输出 PWM 波为例进行介绍,该寄存器的模式设置位 OC1M[2:0] 就是对应着通道 1 的模式设置,此部分由 3 位组成。总共可以配置成 8 种模式,我们使用的是 PWM 模式,所以这 3 位必须设置为 110 或者 111,分别对应 PWM 模式 1 和 PWM 模式 2。这两种 PWM 模式的区别就是输出有效电平的极性相反。
3.7、TIMx捕获/比较使能寄存器
该寄存器控制着各个输入输出通道的开关和极性。如果我们想让要让 TIM14 的 CH1 输出 PWM 波,这里我们要使能 CC1E 位,该位是通道 1 输入/输出使能位,要想 PWM 从 IO 口输出,这个位必须设置为 1。CC1P 位是设置通道 1 的输出极性。
3.8、TIMx计数器
TIM2/TIM5 的计数寄存器是 32 位的,TIM3/TIM4 的计数寄存器都是 16 位有效的,计数模式可以是递增计数模式、递减计数模式和中心对齐计数模式。其他定时器和基本定时器一样,可以直接写该寄存器设置计数的初始值,也可以读取该寄存器获取计数器值。
3.9、TIMx预分频器
定时器的预分频寄存器都是 16 位的,即写入该寄存器的数值范围是 0 到 65535,表示 1 到 65536 分频。比如我们要 8400 分频,就往该寄存器写入 8399。
3.10、TIMx自动重载寄存器
在 F4 系列中,TIM2 和 TIM5 的自动重装载寄存器是 32 位的,其他通用定时器自动重载寄存器是低 16 位有效。该寄存器可以由 APRE 位设置是否进行缓冲。计数器的值会和自动重装寄存器影子寄存器进行比较,当两者相等,定时器就会溢出,从而发生更新事件,如果打开了更新中断,还会发生更新中断。
3.11、TIMx捕获/比较寄存器
捕获/比较寄存器(TIMx_CCR1),该寄存器只有 1 个,对应通道 CH1。我们使用的是通道 1。在输出模式下,捕获/比较寄存器影子寄存器的值与 CNT 的值比较,根据比较结果产生相应动作,利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的占空比了。
四、通用定时器对应通道引脚
【1】、TIM2 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PA0 | PA5/PA15 |
Channel 2 | PA1 | PB3 |
Channel 3 | PA2 | PB10 |
Channel 4 | PA3 | PB11 |
【2】、TIM3 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PA6 | PC6/PB4 |
Channel 2 | PA7 | PC7/PB5 |
Channel 3 | PB0 | PC8 |
Channel 4 | PB1 | PC9 |
【3】、TIM4 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PD12 | PB6 |
Channel 2 | PD13 | PB7 |
Channel 3 | PD14 | PB8 |
Channel 4 | PD15 | PB9 |
【4】、TIM5 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PA0 | |
Channel 2 | PA1 | |
Channel 3 | PA2 | |
Channel 4 | PA3 |
【5】、TIM9 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PE5 | PA2 |
Channel 2 | PE6 | PA3 |
【6】、TIM10 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PF6 | PB8 |
【7】、TIM11 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PF7 | PB9 |
【8】、TIM12 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PB14 | |
Channel 2 | PB15 |
【9】、TIM13 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PF8 | PA6 |
【10】、TIM14 对应通道引脚及其重映射
通道名 | 通道引脚 | 重映射通道引脚 |
---|---|---|
Channel 1 | PF9 | PA7 |