通用定时器是在基本定时器的基础上扩展而来,增加了输入捕获与输出比较等功能。高级定时器又是在通用定时器基础上扩展而来,增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能主要针对工业电机控制方面。 本篇博客我们主要来学习通用定时器,通过上一次的学习,我们知道 STM32F407 有 10 个通用定时器(TIM2~TIM5 和 TIM9~TIM14)。这些定时器彼此完全独立,不共享任何资源。
目录
一、STM32F4 通用定时器简介
STM32F407 的通用定时器有 10 个,为了更好的区别各个定时器的特性,我们列了一个表 格,如下所示:
定时器类型 | 主要功能 |
基本定时器 | 没有输入输出通道,常用作时基,即定时功能 |
通用定时器 | 具有多路独立通道,可用于输入捕获/输出比较,也可用作时基 |
高级定时器 | 除具备通用定时器所有功能外,还具备带死区控制的互补信号输出、刹车输入等功能(可用于电机控制、数字电源设计等) |
STM32F4 的通用定时器包含一个 16 位或 32 位自动重载计数器(CNT),该计数器由可编程预分频器(PSC)驱动。STM32F4 的通用定时器可以被用于:测量输入信号的脉冲长度(输入 捕获)或者产生输出波形(输出比较和 PWM)等。 STM32F4 的每个通用定时器都是完全独立的,没有互相共享的任何资源。
STM32 的通用 TIMx (TIM2~TIM5 和 TIM9~TIM14)定时器功能包括:
- 16 位/32 位(仅 TIM2 和 TIM5)向上、向下、向上/向下自动装载计数器(TIMx_CNT),注意:TIM9~TIM14 只支持向上(递增)计数方式。
- 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~ 65535 之间的任意数值。
- 4 个独立通道(TIMx_CH1~4,TIM9~TIM14 最多 2 个通道),这些通道可以用来作为:
- A.输入捕获 B.输出比较 C.PWM 生成(边缘或中间对齐模式) ,注意:TIM9~TIM14 不支持中间对齐模式 D.单脉冲模式输出
- 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外 一个定时器)的同步电路。
- 如下事件发生时产生中断/DMA(TIM9~TIM14 不支持 DMA):
- A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
- B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
- C.输入捕获
- D.输出比较
- E.支持针对定位的增量(正交)编码器和霍尔传感器电路(TIM9~TIM14 不支持)
- F.触发输入作为外部时钟或者按周期的电流管理(TIM9~TIM14 不支持)
由以上分析知道:该 STM32 芯片的计数器都是 16 位/32位的。通用定时器和高级定时器其实也就是在基本定时器的基础上,添加了一些其他功能,如:输入捕获、输出比较、输出 PWM 和单脉冲模式等。而通用定时器数量较多,其特性也有一些的差异,但是基本原理都一样。
二、通用定时器框图(重点)
下面先来学习通用定时器框图,通过学习通用定时器框图会有一个很好的整体掌握,同时对之后的编程也会有一个清晰的思路。如下图,通用定时器的框图比基本定时器的框图复杂许多,为了方便介绍,我们将其分成六个部分讲解:
①时钟源
②控制器
③时基单元
④输入捕获
⑤捕获/比较(公共)
⑥输出比较
2.0 预备知识
2.0.1 触发信号
触发信号:可以理解为脉冲信号。在STM32中触发信号分为两大类:TRGI 和 TRGO,即触发输⼊信号和触发输出信号。
- 触发输入信号TRGI : 可以理解为从外部引入到定时器中的信号。
- 触发输出信号TRGO:定时器输出给其它定时器或外设的信号。
触发输入信号:
- 第⼀类:TI1F_ED/TI1FP1/TI2FP2,来自定时器输入通道1或通道2的触发信号,连接到从模式控制器,从而控制计数器的工作。
- 第⼆类:来自外部触发脚[ETR]的信号经过处理后,连接到从模式控制器。
- 第三类:来自其他定时器的触发信号(ITR),通过内部线路连接到从模式控制器。
触发输出信号:
触发输出信号是定时器自身产生的,那么他是如何产生的并有哪些触发输出信号
- 定时器更新事件;
- 定时器的输入捕获和输出比较事件;
- 复位;
- 使能;
- 更新:选择更新事件作为触发输出 (TRGO)。例如,主定时器可⽤作从定时器的预分频器。
2.0.2 从模式控制器
从模式控制器的几种模式:
- 复位模式:当有效触发信号出现时,将会复位计数器,并产生更新事件。向上计数的将会复位到0,向下计数的将会复位到ARR的值。
- 门控模式:定时器根据触发输入信号的电平来启动或停止计数器的计数;
- 触发模式:当有效触发输入信号出现时,会将本来处于未使能状态的计数器使能激活,让计数器开始计数;
- 外部时钟模式1:由所选触发输入信号 (TRGI) 的上升沿提供计数器时钟。
- 小结:
- (1)不论来自本定时器外部的哪⼀类触发输入信号,它们有个共同特点,就是都要经过触发输入选择器而连接到从模式控制器,从而使得计数器的工作受到从模式控制器的控制或影响。从模式控制器可以对定时器作如下操控:对计数器复位、启动或停止计数动作、使能计数器、通过触发输入信号为计数器提供时钟源。
2.1 时钟源(重要)
定时器的时钟源这部分内容是非常重要的,因为这计数器工作的基础。虽然定时器有四类时钟源之多,但是我们最常用的还是内部时钟。 通用定时器时钟可以选择下面四类时钟源之一:
①内部时钟(CK_INT),来自外设总线APB提供的时钟
②外部时钟模式1:外部输入引脚(TIx),来自定时器通道1或者通道2引脚的信号
③外部时钟模式2:外部触发输入(ETR),来自可以复用为TIMx_ETR的IO引脚
④内部触发输入(ITRx),用于与芯片内部其它通用/高级定时器级联
通用定时器时钟源的设置方法如下表所示:
2.1.1 内部时钟(CK_INT)
STM32F4 系列的定时器 TIM2/TIM3/TIM4/TIM5/ TIM6/TIM7/ TIM12/ TIM13/ TIM14 都是挂载在 APB1 总线上,这些定时器的内部时钟(CK_INT)实际上来自于 APB1 总线提供的时钟。 但是这些定时器时钟不是由 APB1 总线直接提供,而是要先经过一个倍频器。在源码中,已经设置 APB1 总线时钟频率为 42MHz,APB1 预分频器的预分频系数为4,所以这些定时器时钟源频率为 84MHz。因为 当 APB1 预分频器的预分频系数≥2 分频时,挂载在 APB1 总线上的定时器时钟频率是该总线时钟频率的两倍。这个和基本定时器一样,可回顾基本定时器这部分内容。APB2 总线上挂载的通用定时器 TIM9/TIM10/TIM11,以及高级定时器 TIM1 和 TIM8,它 们的情况是上面的描述是一样的,不同点是:定时器挂载的总线变成了 APB2,在系统时钟初始化函数已经设置 APB2 总线时钟频率为 84MHz,预分频器的预分频系数为 2,所以上述的定时器时钟源频率为168MHz。
内部时钟:
- TIM2/TIM3/TIM4/TIM5/ TIM6/TIM7/ TIM12/ TIM13/ TIM14定时器挂载在APB1上:84MHZ;
- TIM9/TIM10/TIM11,以及高级定时器 TIM1 和 TIM8挂载在APB2上:168MHZ;
2.1.2 外部时钟模式 1(TI1、TI2)
外部时钟模式 1 这类时钟源,顾名思义时钟信号来自芯片外部。
时钟源进入定时器的流程如下:外部时钟源信号→IO→TIMx_CH1(或者 TIMx_CH2);
注意:外部时钟模式 1 下,时钟源信号只能从 CH1 或者 CH2 输入到定时器,CH3 和 CH4 都是不可以的。
从 IO 到 TIMx_CH1(或者 TIMx_CH2),就需要我们配置 IO 的复用功能,才能使 IO 和定时器通道相连通。时钟源信号来到定时器 CH1 或 CH2 后,需要经过什么“关卡”才能到达计数器作为计数的时钟频率的,下面通过外部时钟模式 1 框图给大家解答。
图 21.1.2 中是以 CH2(通道 2)为例的,时钟源信号到达 CH2 后,那么这里我们把这个时钟源信号用 TI2 表示,因为它只是个信号,来到定时器内部,那我们就按定时器内部的信号来命名,所谓入乡随俗。
- TI2首先经过一个滤波器,由 ICF[3:0]位来设置滤波方式,也可以设置不使用滤波器。(如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对 ETRP 信号重新采样,来达到降频或者去除高频干扰的目的)
- 接着经过边沿检测器,由 CC2P 位来设置检测的边沿,可以上升沿或者下降沿检测。
- 然后经过触发输入选择器,由 TS[4:0]位来选择 TRGI(触发输入信号)的来源。可以看到图 21.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.1.3 外部时钟模式 2(ETR)
外部时钟模式 2,顾名思义时钟信号来自芯片外部。
时钟源进入定时器的流程如下:外部时钟源信号→IO→TIMx_ETR。
从 IO 到 TIMx_ETR,就需要我们配置 IO 的复用功能,才能使IO和定时器相连通。 时钟源信号来到定时器 TIMx_ETR 后,需要经过什么“关卡”才能到达计数器作为计数的时钟频率的,下面通过外部时钟模式 2 框图给大家解答。
图 21.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 需要经过定时器的预分频器分频后, 最终就能到达计数器进行计数了。
2.1.4 内部触发输入(ITRx)
内部触发输入是使用一个定时器作为另一个定时器的预分频器,即实现定时器的级联。
下 面以 TIM1 作为 TIM2 的预分频器为例,给大家介绍。
上图中,TIM1 作为 TIM2 的预分频器,需要完成的配置步骤如下:
- TIM1_CR2 寄存器的 MMS[2:0]位设置为 010,即 TIM1 的主模式选择为更新(选择更新事件作为触发输出信号 (TRGO))。
- TIM2_SMCR 寄存器的 TS[2:0]位设置为 000,即使用 ITR1 作为内部触发。
- TIM2_SMCR 寄存器的 SMS[2:0]位设置为 111,即从模式控制器选择外部时钟模式 1。
- TIM1 和 TIM2 的 CEN 位都要置 1,即启动计数器。
TS[2:0]位用于配置触发选择,除了 ITR1,还有其他的选择,详细描述如下图所示:
上图中的触发选择中,我们在讲解外部时钟模式 1 的时候说过 TI1F_ED、TI1FP1 和 TI2FP2, 以及外部时钟模式 2 讲的 ETRF,它们都是属于外部的,其余的都是内部触发了。那么这内部触发都代表什么意思呢?如下表所示:
在步骤 2 中,TS[2:0]位设置为 000,使用 ITR0 作为内部触发,这个 ITR0 什么意思?由表 21.1.3 可以知道,当从模式定时器为 TIM2 时,ITR0 表示主模式定时器就是 TIM1。这里只是 TIM2~5 的内部触发连接情况,其他定时器请查看参考手册的相应章节。
2.2 控制器
控制器包括:从模式控制器、编码器接口和触发控制器(TRGO)。
- 从模式控制器:可以控制计数器复位、启动、递增/递减、计数。
- 编码器接口:针对编码器计数而设计。
- 触发控制器:用来针对片内外设提供触发信号给别的外设,比如为其它定时器提供时钟或者为 DAC/ADC 的触发转换提供信号。
2.3 时基单元
时基单元包括:计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器 (TIMx_ARR)。这部分内容和基本定时器基本一样的,大家可以参考基本定时器的介绍。不同点是:通用定时器的计数模式有三种:递增计数模式、递减计数模式和中心对齐模式
- 递增计数模式下,计数器从 0 开始计数,每来一个 CK_CNT 脉冲计数器就增加 1,直 到计数器的值与自动重载寄存器 ARR 值相等,然后计数器又从 0 开始计数并生成计数 器上溢事件,计数器总是如此循环计数。如果禁用重复计数器,在计数器生成上溢事 件就马上生成更新事件(UEV);如果使能重复计数器,每生成一次上溢事件重复计数器内容就减 1,直到重复计数器内容为 0 时才会生成更新事件。
- 递减计数模式下,计数器从自动重载寄存器 ARR 值开始计数,每来一个 CK_CNT 脉 冲计数器就减 1,直到计数器值为 0,然后计数器又从自动重载寄存器 ARR 值开始递 减计数并生成计数器下溢事件,计数器总是如此循环计数。如果禁用重复计数器,在 计数器生成下溢事件就马上生成更新事件;如果使能重复计数器,每生成一次下溢事 件重复计数器内容就减 1,直到重复计数器内容为 0 时才会生成更新事件。
- 中心对齐模式下,计数器从 0 开始递增计数,直到计数值等于(ARR-1)值生成计数器上 溢事件,然后从 ARR 值开始递减计数直到 1 生成计数器下溢事件。然后又从 0 开始计 数,如此循环。每次发生计数器上溢和下溢事件都会生成更新事件。
计数器的计数模式的设置请参考 TIMx_CR1 寄存器的位 CMS 和位 DIR。 下面通过一张图给大家展示定时器工作在不同计数模式下,更新事件发生的情况。定时器溢出就会伴随着更新事件的发生。
上图中,纵轴表示计数器的计数值,横轴表示时间,ARR 表示自动重载寄存器的值,小红点就是更新事件发生的时间点。举个例子,递增计数模式下,当计数值等于 ARR 时,计数器的值被复位为 0,定时器溢出,并伴随着更新事件的发生,后面继续递增计数。递减计数模式和中心对齐模式请参考前面的描述。 上表的描述属于硬件更新事件发生条件,我们还可以通过 UG 位产生软件更新事件。 关于影子寄存器和定时器溢出时间计算公式等内容可以参考基本定时器的相关内容。
使用通用定时器也可以完成定时中断,与基本定时器的不同点在于:基本定时器只能递增计数,而通用定时器计数模式有三种,它的基本结构如下:
2.4 输入捕获(重要)
图 21.1.1.1 中的第④部分是输入捕获,一般应用是要和第⑤部分一起完成测量功能。 TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通过复用功能与这些通道相连。配置好 IO 端口的复用功能后,将需要测量的信号输入到相应的 IO 端口,输入捕获部分可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常见的测量有:测量输入信号的脉冲宽度、测量 PWM 输入信号的频率和占空比等。后续有相应的实验。
简单介绍:测量高电平脉冲宽度的工作原理,方便大家的理解:
一般先要设置输入捕获的边沿检测极性,如:我们设置上升沿检测,那么当检测到上升沿时,定时器会把计数器 CNT 的值锁存到相应的捕获/比较寄存器 TIMx_CCRy 里,y=1~4。然后我们再设置边沿检测为下降沿检测,当检测到下降沿时,定时器会把计数器 CNT 的值再次锁存到相应的捕获/比较寄存器TIMx_CCRy 里。最后,我们将前后两次锁存的 CNT 的值相减,就可以算出高电平脉冲期间内计数器的计数个数,再根据定时器的计数频率就可以计算出这个高电平脉冲的时间。低电平脉冲捕获同理。如下图所示:
上面的描述是第④部分输入捕获整体上的一个应用情况,下面我们来看第④部分的细节。 当需要测量的信号进入通道后,需要经过哪些“关卡”?我们用图 21.1.7 给大家讲解。
图 21.1.7 是图 21.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 就是分频后的捕获信号。这个信号将会到达图 21.1.1 的第⑤部分。
下面我们接着看图 21.1.1 的第⑤部分的“放大版”,如下图所示:
图 21.1.8 中,灰色阴影部分是输出比较功能部分,讲到第⑥部分输出比较的时候再介绍。 左边没有阴影部分就是输入捕获功能部分了。
首先看到捕获/比较预装载寄存器,我们以通道 1 为例,那么它就是 CCR1 寄存器,通道 2、 通道 3、通道 4 就分别对应 CCR2、CCR3、CCR4。在图 21.1.1 中就可以看到 CCR1~4 是有影子寄存器的,所以这里就可以看到图 21.1.8 中有捕获/比较影子寄存器,该寄存器不可直接访问。
图 21.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 寄存器,得到计数器的计数值。检测下降沿同理。
2.5 输入捕获和输出比较公共部分
该部分需要结合第④部分或者第⑥部分共同完成相应功能
2.6 输出比较(重要)
输出比较整体框图如下:
图21.1.1.1中的第⑥部分是输出比较,一般应用是要和第⑤部分一起完成定时器输出功能。 TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通 过复用功能与这些通道相连。 下面我们按照输出信号产生过程顺序给大家介绍定时器如何实现输出功能的?首先看到第 ⑤部分的“放大版”图,如下图所示:
图 21.1.9 中,灰色阴影部分是输入捕获功能部分,前面已经讲过。这里我们看到右边没有 阴影部分就是输出比较功能部分了。下面以通道 1 输出比较功能为例给大家介绍定时器如何实 现输出功能的。
首先程序员写 CCR1 寄存器,即写入比较值。这个比较值需要转移到对应的捕获/比较影子 寄存器后才会真正生效。什么条件下才能转移?图 21.1.9 中可以看到 compare_transfer 旁边的与门,需要满足三个条件:CCR1 不在写入操作期间、CC1S[1:0] = 0 配置为输出、OC1PE 位置 0(或者 OC1PE 位置 1,并且需要发生更新事件,这个更新事件可以软件产生或者硬件产生)。 当 CCR1 寄存器的值转移到其影子寄存器后,新的值就会和计数器的值进行比较,它们的比较结果将会通过第⑥部分影响定时器的输出。
下面来看看第⑥部分通道 1 的“放大版”,如下图所示
上图中,可以看到输出模式控制器,由 OC1M[2:0]位配置输出比较模式,F4 系 列有 8 种输出比较模式之多。oc1ref 是输出参考信号,高电平有效,为高电平时称之为有效电平,为低电平时称之为无效电平。它的高低电平受到三个方面的影响:OC1M[3:0]位配置的输出比较模式、第⑤部分比较 器的比较结果、还有就是 OC1CE 位配置的 ETRF 信号。ETRF 信号可以将 oc1ref 电平强制清 零,该信号来自 IO 外部。 一般来说,当计数器的值和捕获/比较寄存器的值相等时,输出参考信号 oc1ref 的极性就会根据我们选择的输出比较模式而改变。如果开启了比较中断,还会发生比较中断。 CC1P 位用于选择通道输出极性。 CC1E 位置 1 使能通道输出。 OC1 信号就会从 TIMx_CH1 输出到 IO 端口,再到 IO 外部。
输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
2.6.1 通用定时器输出PWM原理
2.6.2 PWM模式
至此,对通用定时器做了基本介绍,这一节我们就讲解到这里,希望能对大家的开发有帮助。下一节,我们将通过实验深入理解如何运用通用定时器, 如有兴趣,感谢点赞、关注、收藏,若有不正地方,还请各位大佬多多指教!