STM32F429 有14个定时器,其中包括
2 个基本定时器(TIM6 和 TIM7)、
10 个通用定时器(TIM2~TIM5,TIM9~TIM14)、
2 个高级控制定时器(TIM1 和 TIM8)。
由上表知道:除了 TIM2 和 TIM5 是 32 位的计数器,其他定时器是 16 位的。通用定时器和高级定时器其实也就是在基本定时器的基础上,添加了一些其他功能,如:输入捕获、输出比较、输出 PWM 和单脉冲模式等。而通用定时器数量较多,其特性也有一些的差异,但基本原理一样。
基本定时器
先学习基本定时器框图,通过学习基本定时器框图会有一个很好的整体掌握,同时对之后的编程也会有一个清晰的思路。
① 时钟源
基本定时器时钟挂载在 APB1 总线,所以它的时钟来自于 APB1 总线,但是基本定时器时钟不是直接由 APB1 总线直接提供,而是先经过一个倍频器。在 TIMPRE 位默认设置为 0 的情况下,当 APB1 的预分频器预的分频系数为 1 时,这个倍频器系数就为 1,即定时器的时钟源频率等于 APB1 总线时钟频率;当 APB1 的预分频器的预分频系数系数≥2 分频时,这个倍频器系数就为 2,即定时器的时钟源频率等于 APB1 总线时钟频率的两倍。
我们在时钟设置函数 sys_stm32_clock_init 已经设置 APB1 总线时钟频率为 45MHz,预分频器的预分频系数为 2,所以定时器时钟源频率为90Mhz。
② 控制器
控制器除了控制定时器复位、使能、计数等功能之外,还可以用于触发 DAC 转换。
③ 时基单元
时基单元包括:预分频器寄存器(TIMx_PSC)、计数器寄存器(TIMx_CNT)、自动重载寄存器(TIMx_ARR) 。基本定时器的这三个寄存器都是 16 位有效数字,即可设置值范围是 0~65535。
预分频器寄存器(TIMx_PSC)可以在运行过程中修改它的数值,新的预分频数值将在下一个更新事件时起作用。因为更新事件发生时,会把 TIMx_PSC 寄存器值更新到其影子寄存器中,这才会起作用。
什么是影子寄存器?从框图上看,可以看到图 19.1.1.1 中的预分频器 PSC 后面有一个影子,
自动重载寄存器也有个影子,这就表示这些寄存器有影子寄存器。影子寄存器是一个实际起作用的寄存器,不可直接访问。预分频器寄存器只是起到缓存数据的作用,只有等到更新事件发生时,预分频器寄存器的值才会被自动写入其影子寄存器中,这时才真正起作用。
自动重载寄存器及其影子寄存器的作用和上述同理。不同点在于自动重载寄存器是否具有缓冲作用还受到TIMx_CR1_ARPE位的控制,当该位置0时,ARR寄存器不进行缓冲,我们写入新的 ARR 值时,该值会马上被写入 ARR 影子寄存器中,从而直接生效;当该位置 1 时,ARR 寄存器进行缓冲,我们写入新的 ARR 值时,该值不会马上被写入 ARR 影子寄存器中,而是要等到更新事件发生才会被写入 ARR 影子寄存器,这时才生效。预分频器寄存器则没有这样相关的控制位,这就是它们不同点。
更新事件的产生有两种情况,一是由软件产生,将 TIMx_EGR 寄存器的位 UG 置 1,产生更新事件后,硬件会自动将 UG 位清零。二是由硬件产生,满足以下条件即可:计数器的值等于自动重装载寄存器影子寄存器的值。
基本定时器的计数器(CNT)是一个递增的计数器,当寄存器(TIMx_CR1)的 CEN位置1,即使能定时器,每来一个 CK_CNT 脉冲,TIMx_CNT 的值就会递增加 1。当 TIMx_CNT 值与 TIMx_ARR 的设定值相等时,TIMx_CNT 的值就会被自动清零并且会生成更新事件(如果开启相应的功能,就会产生 DMA 请求、产生中断信号或者触发 DAC 同步电路),然后下一个CK_CNT 脉冲到来,TIMx_CNT 的值就会递增加 1,如此循环。在此过程中,TIMx_CNT 等于TIMx_ARR时,我们称之为定时器溢出,因为是递增计数,故而又称为定时器上溢。定时器溢出就伴随着更新事件的发生。
基本定时器寄存器
⚫ 控制寄存器 1(TIMx_CR1)
位 0(CEN)用于使能或者禁止计数器。还有位 7(ARPE)用于控制自动重载寄存器 ARR 是否具有缓冲作用,ARR 起缓冲作用,即只有在更新事件发生时才会把 ARR 的值写入其影子寄存器里;否则修改自动重载寄存器的值时,该值会马上被写入其影子寄存器中,从而立即生效。
⚫ DMA/中断使能寄存器(TIMx_DIER)
位 0(UIE)用于使能或者禁止更新中断。位 8(UDE)用于使能或禁止更新 DMA 请求。
⚫ 状态寄存器(TIMx_SR)
位 0(UIF)是中断更新的标志位,当发生中断时由硬件置 1,然后就会执行中断服务函数,需要软件去清零,所以我们必须在中断服务函数里把该位清零。如果中断到来后,不把该位清零,那么系统就会一直进入中断服务函数。
通用/高级定时器下该寄存器存放中断标志位。比如更新中断标志位、捕获/比较中断标志位等。
⚫ 计数器寄存器(TIMx_CNT)
该寄存器位[15:0]就是计数器的实时的计数值。
⚫ 预分频寄存器(TIMx_PSC)
该寄存器是 TIM6/TIM7 的预分频寄存器,比如我们要 9000 分频,就往该寄存器写入 8999。
注意这是 16 位的寄存器,写入的数值范围:0 到 65535,分频系数范围:1 到 65536。
⚫ 自动重载寄存器(TIMx_ARR)
该寄存器可以由 ARPE 位设置是否进行缓冲。计数器的值会和 ARR 寄存器影子寄存器进行比较,当两者相等,定时器就会溢出,从而发生更新事件,如果打开更新中断,还会发生更新中断。
基本定时器总结
STM32F4有2个基本定时器,TIM6 和 TIM7。
基本定时器框图有三个部分,时钟源、控制器和时基单元。时基单元又有PSC预分频器、CNT计数器和ARR自动重装载寄存器。
基本定时器相关寄存器有6个:
PSC 预分频寄存器,存储预分频值。预分频9000就写8999。
CNT 计数器,存当前计数值。
ARR 自动重装载寄存器。存储重装载值。计数9000就写8999。
CR1 控制寄存器1。有ARPE位控制自动重装载预装载使能。有CEN位控制计数使能。
DIER DMA/中断使能寄存器。有UDE位使能DMA更新请求。有UIE位使能中断。
SR 状态寄存器。有UIF位记录中断更新标志,需手动清零否则持续进入中断。
通用定时器
下面我们以 TIM2/TIM3/TIM4/TIM5 的框图为例来学习通用定时器框图,其他通用定时器的框图会有差异,因为内容比较多,大家学习了这里的框图再看 ST 官方手册其他的定时器框图就会比较容易理解。
如上图,通用定时器的框图比基本定时器的框图复杂许多,为了方便介绍,我们将其分成六个部分讲解:
① 时钟源
通用定时器时钟可以选择下面四类时钟源之一:
1)内部时钟(CK_INT)
2)外部时钟模式 1:外部输入引脚(TIx),x=1,2(即只能来自于通道 1 或者通道 2)
3)外部时钟模式 2:外部触发输入(ETR)
4)内部触发输入(ITRx):使用一个定时器作为另一定时器的预分频器
通用定时器时钟源的设置方法如下表所示:
内部时钟(CK_INT)
STM32F4 系列的 TIM2/TIM3/TIM4/TIM5/ TIM6/TIM7/ TIM12/ TIM13/ TIM14 都是挂载在
APB1 总线上,这些定时器的内部时钟(CK_INT)实际上来自于 APB1 总线提供的时钟。但是这些定时器时钟不是由 APB1 总线直接提供,而是要先经过一个倍频器。在 HAL 库版本例程源码的 sys.c 文件中,系统时钟初始化函数 sys_stm32_clock_init 已经设置 APB1 总线时钟频率为45MHz,预分频器的预分频系数为 2,所以这些定时器时钟源频率为 90MHz。因为在 TIMPRE
位默认设置为 0 的情况下,当 APB1 预分频器的预分频系数≥2 分频时,挂载在 APB1 总线上的定时器时钟频率是该总线时钟频率的两倍。这个和基本定时器一样,可回顾基本定时器这部分内容。
APB2 总线上挂载的通用定时器 TIM9/TIM10/TIM11,以及高级定时器 TIM1 和 TIM8,它们的情况是上面的描述是一样的,不同点是:定时器挂载的总线变成了 APB2,在系统时钟初始化函数 sys_stm32_clock_init 已经设置 APB2 总线时钟频率为 90MHz,预分频器的预分频系数为 2,所以上述的定时器时钟源频率为 180MHz。
外部时钟模式 1(TI1、TI2)
外部时钟模式 1 这类时钟源,顾名思义时钟信号来自芯片外部。时钟源进入定时器的流程如下:外部时钟源信号→IO→TIMx_CH1(或者 TIMx_CH2),这里需要注意的是:外部时钟模式 1 下,时钟源信号只能从 CH1或者 CH2输入到定时器,CH3和 CH4都是不可以的。从 IO到 TIMx_CH1(或者 TIMx_CH2),需要我们配置 IO 的复用功能,才能使 IO 和定时器通道相连通。
时钟源信号来到定时器 CH1 或 CH2 后,需要经过什么“关卡”才能到达计数器作为计数的时钟频率的,下面通过外部时钟模式 1 框图给大家解答。
图 20.1.2 中是以 CH2(通道 2)为例的,时钟源信号到达 CH2 后,那么这里我们把这个时钟源信号用 TI2 表示,因为它只是个信号,来到定时器内部,那我们就按定时器内部的信号来命名,所谓入乡随俗。
TI2 首先经过一个滤波器,由 ICF[3:0]位来设置滤波方式,也可以设置不使用滤波器。
接着经过边沿检测器,由 CC2P 位来设置检测的边沿,可以上升沿或者下降沿检测。然后经过触发输入选择器,由 TS[2:0]位来选择 TRGI(触发输入信号)的来源。可以看到图 20.1.2 中框出了 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 需要经过定时器的预分频器分频后,最终就能到达计数器进行计数了。
外部时钟模式 2(ETR)
外部时钟模式 2,顾名思义时钟信号来自芯片外部。时钟源进入定时器的流程如下:外部时钟源信号→IO→TIMx_ETR。从 IO 到 TIMx_ETR,就需要我们配置 IO 的复用功能,才能使 IO 和定时器相连通。
时钟源信号来到定时器 TIMx_ETR后,需要经过什么“关卡”才能到达计数器作为计数的时钟频率的,下面通过外部时钟模式 2 框图给大家解答。
图 20.1.3 中,可以看到在外部时钟模式 2 下,定时器时钟信号首先从 ETR 引脚进来。
接着经过外部触发极性选择器,由 ETP 位来设置上升沿有效还是下降沿有效,选择下降沿有效的话,信号会经过反相器。然后经过外部触发预分频器,由 ETPS[1:0]位来设置预分频系数,系数范围:1、2、4、8。紧接着经过滤波器,由 ETF[3:0]位来设置滤波方式,也可以设置不使用滤波器。fDTS 由 TIMx_CR1 寄存器的 CKD 位设置。
最后经过从模式选择器,由 ECE 位和 SMS[2:0]位来选择定时器的时钟源。这里我们介绍的是外部时钟模式 2,直接把 ECE 位置 1 即可。CK_PSC 需要经过定时器的预分频器分频后,最终就能到达计数器进行计数了。
内部触发输入(ITRx)
内部触发输入是使用一个定时器作为另一个定时器的预分频器,即实现定时器的级联。下面以 TIM3 作为 TIM2 的预分频器为例,给大家介绍。
上图中,TIM3 作为 TIM2 的预分频器,需要完成的配置步骤如下:
1,TIM3_CR2 寄存器的 MMS[2:0]位设置为 010,即 TIM3 的主模式选择为更新(选择更新事件作为触发输出 (TRGO))。
2,TIM2_SMCR 寄存器的 TS[2:0]位设置为 010,即 TIM2 使用 ITRx 作为内部触发(查内部触发连接表)。TS[2:0]位用于配置触发选择,除了 ITR2,还有其他的选择,详细描述如下图所示:
上图中的触发选择中,我们在讲解外部时钟模式1的时候说过TI1F_ED、TI1FP1和TI2FP2,以及外部时钟模式 2 讲的 ETRF,它们都是属于外部的,其余的都是内部触发了。那么这内部触发都代表什么意思呢?大家打开《STM32F4xx 参考手册_V4(中文版).pdf》的 428 页,就可以找下面这个表。
在步骤 2 中,TS[2:0]位设置为 010,使用 ITR2 作为内部触发,这个 ITR2 什么意思?由表20.1.3 可以知道,当从模式定时器为 TIM2 时,ITR2 表示主模式定时器就是 TIM3。这里只是TIM2~5 的内部触发连接情况,其他定时器请查看参考手册的相应章节。
3,TIM2_SMCR 寄存器的 SMS[2:0] 置为 111,即 TIM2 从模式控制器选择外部时钟模式 1。
4,TIM3 和 TIM2 的 CEN 位都要置 1,即启动计数器。
定时器的时钟源这部分内容是非常重要的,因为这计数器工作的基础。虽然定时器有四类时钟源之多,但是我们最常用的还是内部时钟。
② 控制器
控制器包括:从模式控制器 SMCR、编码器接口和触发控制器(TRGO)。从模式控制器可以控制计数器复位、启动、递增/递减、计数。编码器接口针对编码器计数。触发控制器用来提供触发信号给别的外设,比如为其它定时器提供时钟或者为 DAC/ADC 的触发转换提供信号。
③ 时基单元
时基单元包括:计数器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR)。这部分内容和基本定时器基本一样的,大家可以参考基本定时器的介绍。
不同点是:通用定时器的计数模式有三种:递增计数模式、递减计数模式和中心对齐模式;TIM2 和 TIM5 的计数器是 32 位的。递增计数模式在讲解基本定时器的时候已经讲过了,那么对应到递减计数模式就很好理解了。就是来了一个计数脉冲,计数器就减 1,直到计数器寄存器的值减到 0,减到 0 时定时器溢出,由于是递减计数,故而称为定时器下溢,定时器溢出就会伴随着更新事件的发生。然后计数器又从自动重载寄存器影子寄存器的值开始继续递减计数,如此循环。最后是中心对齐模式,字面上不太好理解。该模式下,计数器先从 0 开始递增计数,直到计数器的值等于自动重载寄存器影子寄存器的值减 1 时,定时器上溢,同时生成更新事件,然后从自动重载寄存器影子寄存器的值开始递减计算,直到计数值等于 1 时,定时器下溢,同时生成更新事件,然后又从 0 开始递增计数,依此循环。每次定时器上溢或下溢都会生成更新事件。计数器的计数模式的设置请参考 TIMx_CR1 寄存器的位 CMS 和位 DIR。
上表的描述属于硬件更新事件发生条件,我们还可以通过 UG 位产生软件更新事件。
④ 输入捕获
图 20.1.1.1 中的第④部分是输入捕获,一般要和第⑤部分(公共部分)一起完成测量功能。
TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通过复用功能与这些通道相连。配置好 IO 端口的复用功能后,将需要测量的信号输入到相应的 IO 端口,输入捕获部分可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常见的测量有:测量输入信号的脉冲宽度、测量 PWM 输入信号的频率和占空比等。
下面简单说一下测量高电平脉冲宽度的工作原理,方便大家的理解:一般先要设置输入捕获的边沿检测极性,如:我们设置上升沿检测,那么当检测到上升沿时,定时器会把计数器 CNT 的值锁存到相应的捕获/比较寄存器 TIMx_CCRy 里,y=1~4。然后我们再设置边沿检测为下降沿检测,当检测到下降沿时,定时器会把计数器 CNT 的值再次锁存到相应的捕获/比较寄存器TIMx_CCRy里。最后,我们将前后两次锁存的 CNT的值相减,就可以算出高电平脉冲期间内计数器的计数个数,再根据定时器的计数频率就可以计算出这个高电平脉冲的时间。如果要测量的高电平脉宽时间长度超过定时器的溢出时间周期,就会发生溢出,这时候我们还需要做定时器溢出的额外处理。低电平脉冲捕获同理。
上面的描述是第④部分输入捕获整体上的一个应用情况,下面我们来看第④部分的细节。
当需要测量的信号进入通道后,需要经过哪些“关卡”?我们用图 20.1.7 给大家讲解。
图 20.1.7 是图 20.1.1 第④部分通道 1 的“放大版”,这里是以通道 1 输入捕获为例进行介绍,其他通道同理。
待测量信号到达 TIMx_CH1 后,那么这里我们把这个待测量信号用 TI1 表示,原因在讲解外部时钟模式 1 的时候说过,所谓“入乡随俗”。
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 就是分频后的捕获信号。这个信号将会到达图 20.1.1 的第⑤部分(公共部分)。
下面我们接着看图 20.1.1 的第⑤部分的“放大版”,如下图所示:
图 20.1.8 中,灰色阴影部分是输出比较功能部分,讲到第⑥部分输出比较的时候再介绍。左边没有阴影部分就是输入捕获功能部分了。
首先看到捕获/比较预装载寄存器,我们以通道 1 为例,那么它就是 CCR1 寄存器,通道 2、
通道 3、通道 4 就分别对应 CCR2、CCR3、CCR4。在图 20.1.1 中就可以看到 CCR1~4 是有影
子寄存器的,所以这里就可以看到图 20.1.8 中有捕获/比较影子寄存器,该寄存器不可直接访问。
图 20.1.8 左下角的 CC1G 位可以产生软件捕获事件,那么硬件捕获事件如何产生的?这里我们还是以通道 1 输入为例,CC1S[1:0] = 01,即 IC1 映射到 TI1 上;CC1E 位置 1,使能输入捕获;比如不滤波、不分频,ICF[3:0] = 00,ICPS[1:0] = 00;比如检测上升沿,CC1P 位置 0;接着就是等待测量信号的上升沿到来。当上升沿到来时,IC1PS 信号就会触发输入捕获事件发生,计数器的值就会被锁存到捕获/比较影子寄存器里。当 CCR1 寄存器没有被进行读操作的时候,捕获/比较影子寄存器里的值就会锁存到 CCR1 寄存器中,那么程序员就可以读取 CCR1寄存器,得到计数器的计数值。检测下降沿同理。
⑤ 输入捕获和输出比较公用部分
该部分需要结合第④部分(输入捕获)或者第⑥部分(输出比较)共同完成相应功能。
⑥ 输出比较
图 20.1.1.1 中的第⑥部分是输出比较,一般应用是要和第⑤部分一起完成定时器输出功能。
TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通
过复用功能与这些通道相连。
下面我们按照输出信号产生过程顺序给大家介绍定时器如何实现输出功能的?首先看到第⑤部分的“放大版”图,如下图所示:
图 20.1.9 中,灰色阴影部分是输入捕获功能部分,前面已经讲过。这里我们看到右边没有阴影部分就是输出比较功能部分了。下面以通道 1 输出比较功能为例给大家介绍定时器如何实现输出功能的。
首先程序员写 CCR1 寄存器,即写入比较值。这个比较值需要转移到对应的捕获/比较影子寄存器后才会真正生效。什么条件下才能转移?图 20.1.9 中可以看到 compare_transfer 旁边的与门,需要满足三个条件:CCR1 不在写入操作期间、CC1S[1:0] = 0 配置为输出、OC1PE 位置 0(或者 OC1PE 位置 1,并且需要发生更新事件,这个更新事件可以软件产生或者硬件产生)。
当 CCR1 寄存器的值转移到其影子寄存器后,新的值就会和计数器的值进行比较,它们的比较结果将会通过第⑥部分影响定时器的输出。下面来看看第⑥部分通道 1 的“放大版”,如下图所示
上图中,可以看到输出模式控制器,由 OC1M[3:0]位配置输出比较模式,oc1ref 是输出参考信号,高电平有效,为高电平时称之为有效电平,为低电平时称之为无效电平。它的高低电平受到三个方面的影响:OC1M[3:0]位配置的输出比较模式、第⑤部分比较器的比较结果、还有就是OC1CE 位配置的 ETRF 信号。ETRF 信号可以将 Oc1ref 电平强制清零,该信号来自 IO 外部。
一般来说,当计数器的值和捕获/比较寄存器的值相等时,输出参考信号 oc1ref 的极性就会根据我们选择的输出比较模式而改变。如果开启了比较中断,还会发生比较中断。
CC1P 位用于选择通道输出极性。
CC1E 位置 1 使能通道输出。
OC1 信号就会从 TIMx_CH1 输出到 IO 端口,再到 IO 外部。
通用定时器寄存器
下面介绍 TIM2/TIM3/TIM4/TIM5 的几个与定时器中断相关且重要的寄存器,其他的通用定时器的寄存器会有一些差异,需对照参考手册相关章节。
⚫ 控制寄存器 1(TIMx_CR1)
ARPE 用于控制自动重载寄存器是否进行缓冲。
CMS[1:0]位,中心对齐模式选择。00为边沿对齐模式,计数器根据方向位(DIR)递增或递减计数。另外有中心对齐模式1/2/3,计数器交替进行递增和递减计数,仅当计数器递增/递减/双边时,CCMRx的输出比较中断标志位才置1。Center-aligned mode selection
DIR 位,用于控制定时器的计数方向。0递增,1递减。配置为中心对齐模式或编码器模式时,该为为只读。
CEN 位,计数器使能。
OPM 位,单脉冲模式。计数器发生更新事件时是否停止计数(CEN位清零)One-pulse mode。
⚫ 从模式控制寄存器(TIMx_SMCR)
SMS 位,从模式选择。其实就是选择计数器输入时钟的来源。0000禁止从模式,则 PSC 预分频器的时钟直接来源内部时钟(CK_INT),也就是定时器挂载的APB总线。
⚫ 捕获/比较模式寄存器 1/2(TIMx_CCMR1/2)
TIM2/TIM3/TIM4/TIM5 的捕获/比较模式寄存器(TIMx_CCMR1/2)。TIMx_CCMR1 控制 CH1 和 CH2,而 TIMx_CCMR2 控制CH3 和 CH4。
该寄存器的有些位在输入/输出模式下,功能不一样。CCMR1/2的[7:0]和[15:8]分别对应通道1\2/3\4的配置。
CCyS[1:0]用于通道的配置。
00:通道配置为输出。01:通道配置为输入,ICy 映射到 TI1 上。02:通道配置为输入,ICy映射到 TI2 上。 03:通道配置为输入,ICy 映射到 TRC 上。此模式尽在通过SMCR寄存器选择内部触发输入时有效。
比如我们要让 TIM3 的 CH4 输出 PWM 波,该寄存器的模式设置位 OC4M[2:0]就是对应着通道 4 的模式设置。总共可以配置 8 种模式,我们使用的是 PWM 模式 1 或者 PWM 模式 2,所以位 OC4M[2:0]设置为 110 或者 111。这两种 PWM模式的区别就是输出有效电平的极性相反。
⚫ 捕获/比较使能寄存器(TIMx_ CCER)
该寄存器控制着各个输入输出通道的开关和极性。该寄存器比较简单,要让 TIM3 的 CH4 输出 PWM 波,这里我们要使能 CC4E 位,该位是通道 4 输入/输出使能位,要想 PWM 从 IO 口输出,这个位必须设置为 1。CC4P 位是设置通道 4 的输出比较极性,我们默认设置 0,也就是计数值<CCR寄存器的值时输出低电平,CNT>CCR时输出高电平。
⚫ 捕获/比较寄存器 1/2/3/4(TIMx_ CCR1/2/3/4)
捕获/比较寄存器(TIMx_ CCR1/2/3/4),该寄存器总共有 4 个,分别对应 4 个通道CH1~CH4。
只有 TIM2 和 TIM5 用到的 CCRy 是 32 位,其他都是 16 位。
在输出模式下,捕获/比较寄存器影子寄存器的值与 CNT 的值比较,根据比较结果产生相应动作,利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的占空比了。
如果通道 y 配置为输入,则 CCRy 存放上一次捕获的CNT的值;如果通道 y 配置为输出,则 CCRy 存放CCRy影子寄存器的预装载值。
通用定时器总结
通用定时器除了基本定时器的定时中断输入捕获、输出比较、输出 PWM 和单脉冲模式等。
通用定时器框图有6个部分,分别是
时钟源、控制器、时基单元、输入捕获、公共部分、输出比较。
时钟源总结
通用定时器时钟源可以是:
1)内部时钟,也就是APB总线时钟。
除了 TIM9 ~ TIM11 和高级定时器 TIM1、TIM8 挂载在 APB2 总线上,2倍频后是 180MHz,其他 TIM 都是挂载在 APB1 总线上,2倍频后是 90MHz。2)外部时钟模式1,也即外部输入引脚(TIx),x=1,2(即只能来自于通道 1 或者通道 2)。
3)外部时钟模式2,也即外部输入引脚ETR。
4)内部触发输入(ITRx):使用一个定时器作为另一定时器的预分频器。
外部时钟模式1,也就是引脚 TIx 作为 TIM 时钟源时,外部时钟源信号首先到达 IO口,复用后进入定时器通道 TIMx_CH1(或者CH2),再经过滤波器,如果信号来自通道1则可以选择不经过边沿检测器,直接双边沿触发,如果信号来自通道2,则必须经过边沿检测器,只能上升沿触发或者下降沿触发。最后经过 从模式选择器 SMCR判断设置的时钟源是什么,由定时器预分频器PSC分频后就能到达计数器CNT。
外部时钟模式2,也就是引脚 ETR 作为 TIM 时钟源时,外部时钟源信号先到达 IO口,复用后进入定时器的 ETR引脚口,接着进入 触发极性选择器 ETP,由 SMCR 的 ETP位来控制上升沿有效还是下降沿有效,下降沿有效的话信号会经过反相成上升沿。然后经过外部触发预分频器 ETPS,由SMCR的ETPS[1:0] 位来设置预分频系数。接着经过滤波器 ETF,由 ETF[3:0] 来设置滤波方式。最后经过从 模式选择器SMCR,由 ECE 位和 SMS[2:0]位来选择定时器时钟源,设置外部时钟模式 2,直接把 ECE 位置 1 即可。经过定时器预分频器 PSC 分频后,到达计数器CNT。
内部触发输入,也就是ITRx作为时钟源,指的时使用一个定时器作为另一个定时器的预分频器,即实现定时器的级联。例如 TIM3 作为 TIM2 的预分频器,需要完成的配置步骤有:
1,TIM3_CR2 寄存器的 MMS[2:0] 设置为010,即 TIM3 的主模式选择为更新,也就是 TIM3 的更新事件作为 触发输出TRGO。
2,TIM2_SMCR 寄存器的 TS[2:0] 位根据 TIMx内部触发连接表 设置为对应的触发选择。
3,TIM2_SMCR 寄存器的 SMS[2:0] 位设置为111,即从模式控制器选择外部时钟模式1。
4,TIM3 和 TIM2 的 CEN 位都要置1,启动计数器。
附录:
控制器总结
通用定时器的控制器包括 从模式控制器,编码器接口 和 触发控制器TRGO。从模式控制器可以控 制计数器复位、启动、递增/递减、计数。编码器接口针对编码器计数。触发控制器用来提供 触发信号给别的外设,比如为其它定时器提供时钟或者为 DAC/ADC 的触发转换提供信号。
时基单元总结
通用定时器的时基单元和基本定时器类似,由预分频器PSC、计数器CNT和自动重装载寄存器ARR构成。
不同的CNT的计数模式有递增、递减和中心对齐这三种。且TIM2和TIM5的计数器是32位,其他都是16位的。计数器的计数模式由CR1的CMS和DIR位决定。
PWM输出总结
开TIMx和对应GPIO口的时钟,配置IO口的复用功能输入。
初始化TIMx,配置ARR和PSC等参数。
通过CCMRy寄存器设置定时器为PWM输出模式,并设置通道的方向为输出。
通过CCER寄存器使能PWM通道输出。
通过CCRy设置比较值来控制占空比。
输入捕获总结
TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。
输入捕获常用来测量PWM输入信号的频率、占空比。每个通道都有对应的CCRy寄存器,y=1~4,SMCR的ETP设置极性后,检测到相应的上升沿或者下降沿输入信号后,定时器会把计数器CNT的值锁存在CCR里,两次检测的差值可得到信号的计数差,根据时钟频率可得持续时间。
总的来说,整个输入捕获的配置流程就是:
开TIMx和对应GPIO口的时钟,配置IO口的复用功能输入。
初始化TIMx,配置ARR和PSC等参数。
通过CCMRy寄存器设置定时器为输入捕获模式。
通过CCER寄存器使能捕获/比较。
通过DIER寄存器使能捕获/比较更新中断。
NVIC设置优先级,使能定时器中断。
每次中断发生读取CCRy寄存器的值。
脉冲计数总结
脉冲计数是以外部时钟1,也就是 引脚TIx 作为时钟源。前面都是内部时钟作为时钟源。
外部时钟模式 1 的外部输入引脚只能是通道 1 或者通道 2 对应的 IO,通道 3或者通道 4 是不可以的。
按键按一下,来一个脉冲,计数值加1。
配置 CCMRy 将 ICx 通道配置在对应的 按键引脚TIz 上。并配置滤波器采样频率、输入捕获预分频器。
CCER使能输入捕获。
DIER使能更新中断。
SMCR配置时钟源为外部时钟1。
高级定时器
高级定时器的框图和通用定时器框图很类似,只是添加了其它的一些功能,如:重复计数器、带死区控制的互补输出通道、断路输入等。这些功能在高级定时器框图的位置如下:
上图中,框出来三个部分,这是和通用定时器不同的地方,下面来分别介绍它们。
① 重复计数器
在 F4 系列中,高级定时器 TIM1 和 TIM8 都有重复计数器。下面来介绍一下重复计数器有什么作用?在学习基本定时器和通用定时器的时候,我们知道定时器发生上溢或者下溢时,会直接生成更新事件。但是有重复计时器的定时器并不完全是这样的,定时器每次发生上溢或下溢时,重复计数器的值会减一,当重复计数器的值为 0 时,再发生一次上溢或者下溢才会生成定时器更新事件。如果我们设置重复计数器寄存器 RCR 的值为 N,那么更新事件将在定时器发生 N+1 次上溢或下溢时发生。
重复计数器寄存器是具有影子寄存器的,所以 RCR 寄存器只是起缓冲的作用。RCR 寄存器的值会在更新事件发生时,被转移至其影子寄存器中,从而真正生效。
② 带死区控制的互补输出
高级定时器输出比较部分和通用定时器相比,多了带死区控制的互补输出功能。图 21.1.1 第②部分的 TIMx_CH1N、TIMx_CH2N 和 TIMx_CH3N 分别是定时器通道 1、通道 2 和通道 3 的互补输出通道,通道 4 是没有互补输出通道的。
DTG 是死区发生器,死区时间由 DTG[7:0] 位来配置。如果不使用互补通道和死区时间控制,那么高级定时器 TIM1/8,以及 TIM15/16/17和其它通用定时器的输出比较部分使用方法基本一样,只是要注意 MOE 位得置 1 定时器才能输出。
③ 断路功能
断路功能也称刹车功能,一般用于电机控制的刹车。F4 系列有一个断路通道。断路源可以是刹车输入引脚(TIMx_BKIN),也可以是一个时钟失败事件。时钟失败事件由复位时钟控制器中的时钟安全系统产生。系统复位后,断路功能默认被禁止,MOE 位为低。
不论何时,输出通道和互补输出通道不能同时处于有效电平。
当发生断路输入后,会怎么样?
1,MOE 位被异步地清零,OCx 和 OCxN 为无效、空闲或复位状态(由 OSSI 位选择)。
2,OCx 和 OCxN 的状态:由相关控制位状态决定,当使用互补输出时:根据情况自动控制输出电平。
3,BIF 位置 1,如果使能了 BIE 位,还会产生刹车中断;如果使能了 TDE 位,会产生DMA 请求。
4,如果 AOE 位置 1,在下一个 更新事件 UEV 时,MOE 位被自动置 1。
高级定时器寄存器
⚫ 事件产生寄存器(TIM8_ EGR)
该寄存器作用是让用户用软件方式产生各类事件。
UG 位是软件更新事件的控制位,只要开启了更新中断使能,在需要产生更新中断的时候把 UG 位置 1即可,会由硬件自动清零。
⚫ 重复计数器寄存器(TIM8_ RCR)
重复计数器寄存器用于设置重复计数器值,因为它具有影子寄存器,所以它本身只是起缓冲作用。当更新事件发生时,该寄存器的值会转移到其影子寄存器中,从而真正起作用。
该寄存器的 REP[7:0]位是低 8 位有效,即最大值 255。因为这个寄存器只是起缓冲作用,如果大家对该寄存器写入值后,想要立即生效,可以通过对 UG 位写 1,产生软件更新事件。
⚫ 捕获/比较寄存器 1/2/3/4(TIM8_ CCR1/2/3/4)
捕获/比较寄存器(TIM8_ CCR1/2/3/4),该寄存器总共有 4 个,对应 4 个通道 CH1~CH4。
在输出模式下,捕获/比较寄存器影子寄存器的值与 CNT 的值比较,根据比较结果产生相应动作,利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的占空比了。
⚫ 断路和死区寄存器(TIM8_ BDTR)
高级定时器 TIM1/8 在输出模式下,还需要配置:断路和死区寄存器(TIMx_BDTR)。
要想高级定时器的 PWM 正常输出,则必须设置主输出使能 MOE 位为 1,否则不会有输出。用到死区功能也是该寄存器配置DTG[7:0]来设置死区时间。
该寄存器控制定时器的断路和死区控制的功能。我们先看断路控制,高级定时器 TIM1/TIM8 有两个断路通道,均为GPIO复用引脚。要使用断路引脚就要使能断路位 BKE,置 1 即可。
位 BKP 选择断路输入信号有效电平。
位 AOE 是自动输出使能位,如果使能 AOE 位,那么在我们输入刹车信号后再断开了刹车号,互补的 PWM 会自动恢复输出,如果失能 AOE 位,那么在输入刹车信号后再断开了刹车信号,互补的 PWM 就不会恢复输出,而是一直保持刹车信号输入时的状态。
BKF[3:0]是断路输入信号的滤波器。
输出指定个数PWM总结
说白了就是搞个软件中断,次数到了用EGR寄存器设置UG标志位=1触发软件开启中断来关闭计数器。
配置步骤:
开 TIMx 和 输出通道对应的 GPIO 时钟,配置 IO口 的复用输出。
初始化 TIMx,设置 TIMx 的 ARR 和 PSC 等参数。
通过 CCMR 设置定时器为 PWM1/2 模式,设置通道为输出。
通过 CCER 设置输出比较极性,使能通道输入/输出。
通过CCRy设置比较值。
通过 BDTR 开主输出使能。
通过 DIER 使能定时器中断。
然后就是中断优先级配置NVIC中断使能一类的工作。
输出比较模式
高级定时器输出比较模式总结
CCMR 可以设置通道模式和选择通道作为输入/输出。
通道模式除了常用的PWM1/2,还有翻转模式
翻转模式下也能生成PWM,配置和直接产生PWM差不多,但是CCMRy配置成翻转模式,并设置通道为输出。到了比较值就输出电平极性翻转一下,也是个PWM波形。
其他的极性啊,比较值啊,输出使能啊,主输出使能啊都一样。
高级定时器互补输出带死区控制总结
带死区控制的互补输出经常被用于电机控制的H桥中。死区时间的存在是为了解决元器件延迟特性。CHx通道和CHxN通道不能同时导通,否则H桥短路。
CR1 的 CKD[1:0] 可设置死区发生器以及数字滤波器所使用的死区及采样时钟之间的分频比。
BDTR 可配置死区发生器的死区时间和主输出使能。
例程,配置通道 CHx输出PWM,CHxN输出互补PWM,给刹车输入引脚某种电平时停止输出PWM。
定时器互补输出带死区控制配置步骤:
死区控制就是CH1~CH3和它们的互补通道CH1N~CH3N,通道和对应的互补通道进行互补输出。
开启 TIMx 和通道输出以及刹车输入的 GPIO 时钟,配置该 IO 口的复用功能输出。
初始化 TIMx,设置 TIMx 的 ARR 和 PSC 等参数。
CR1 设置死区滤波分频。
CCMR 设置通道模式为 PWM 模式,通道输入/输出为输出。
CCER 设置比较输出极性,互补输出极性等参数,并使能通道输出。
BDTR 设置死区时间,断路使能,断路输入信号有效电平,自动输出使能,和主输出使能。
高级定时器PWM输入总结
PWM 输入是输入捕获模式的一个特例。PWM 输入模式经常被应用于测量 PWM 脉宽和频率。
第一,确定定时器时钟源。本实验中我们使用内部时钟(CK_INT),高级定时器挂载在
APB2 总线上,按照 sys_stm32_clock_init 函数的配置,定时器时钟频率为 2 倍 APB2 总线时钟
频率,即 180MHz。计数器的计数频率确定了测量的精度。
第二,确定 PWM 输入的通道。PWM 输入模式下测量 PWM,PWM 信号输入只能从通道
1(CH1)或者通道 2(CH2)输入。
第三,确定 IC1 和 IC2 的捕获边沿。这里以通道 1(CH1)输入 PWM 为例,一般我们习
惯设置 IC1 捕获边沿为上升沿捕获,IC2 捕获边沿为下降沿捕获。
第四,选择触发输入信号(TRGI)。这里也是以通道 1(CH1)输入 PWM 为例,那么我们就应该选择 TI1FP1为触发输入信号。如果是通道 2(CH2)输入 PWM,那就选择 TI2FP2为触发输入信号。可以看到这里并没有对应通道3(CH3)或者通道4(CH4)的触发输入信号,所以我们只选择通道 1 或者通道 2 作为 PWM 输入的通道。
第五,从模式选择:复位模式。复位模式的作用是:在出现所选触发输入 (TRGI) 上升沿时,重新初始化计数器并生成一个寄存器更新事件。
第六,读取一个 PWM 周期内计数器的计数个数,以及高电平期间的计数个数,再结合计数器的计数周期(即计一个数的时间),最终通过计算得到输入的 PWM 周期和占空比等参数。
以通道 1(CH1)输入 PWM,设置 IC1 捕获边沿为上升沿捕获,IC2 捕获边沿为下降沿捕获为例,那么 CCR1 寄存器的值+1 就是 PWM 周期内计数器的计数个数,CCR2 寄存器的值+1 就是PWM 高电平期间计数器的计数个数。通过这两个值就可以计算出 PWM 的周期或者占空比等数。