STM32学习笔记(10)——高级定时器TIM
前排提示:本笔记参考了野火PPT的大部分内容。
STM32F103系列有8个定时器,其中分为2个高级定时器,4个通用定时器、2个基本定时器。
下面为高级定时器TIM功能框图(来自野火PPT),由于高级定时器功能相当复杂,因此本文将大篇幅介绍每种功能(定时、输入捕获、输出比较、刹车输入)。我们将功能框图分为6个部分进行讲解:
一、时钟源
本部分内容可见STM32中文参考手册13.3.4时钟选择。
计数器时钟可由内部时钟源(CK_INT)、外部时钟模式1(外部的GPIO TIx(x = 1、2、3、4))、外部时钟模式2(外部的GPIO ETR)、内部触发模式(ITRx)提供。无论是由什么时钟源提供,最终都会成为CK_PSC
,经过预分频器,成为计数器时钟。
1. 内部时钟源
我们最常用的是内部时钟源,通常的频率为72MHz。这个数字是怎么来的呢?
内部时钟源来自 RCC 时钟的 TIMx_CLK
,可以查看 STM32 的时钟树,它是经过 APB2 预分频器后得到的,如果预分频因子等于 1,则时钟频率x 1,否则频率x 2。由于经过 APB1 和 APB2 预分频后得到的 PCLK1 和 PCLK2 的最大频率为 36MHz,且库函数中的预分频因子为2,所以最后的TIMx_CLK
= 72MHz。
2. 外部时钟模式 1
本内容我们分为以下部分进行讲解,如图所示:
(1)时钟输入引脚
时钟输入引脚对应于GPIO TIx,也就是对应 TIMx_CH1/2/3/4,具体由寄存器TIMx_CCMR1/2
的位CCxS[1:0]
来控制。下面是引脚的分布情况:
TIMx_CCMR1
寄存器控制(TI1/2)TIMx_CH1/2,TIMx_CCMR2
寄存器控制(TI3/4)TIMx_CH3/4。对于TIMx_CCMR1
寄存器,当CCxS[1:0]
= 01时映射在TI1上,10时映射在TI2上;对于TIMx_CCMR2
寄存器,当CCxS[1:0]
= 01 时映射在 TI3 上,10 时映射在 TI4 上。
(2)滤波器
(本段出自野火教程PPT)如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对 ETRP(外部触发预分频,External trigger prescaler) 信号重新采样,来达到降频或者去除高频干扰的目的。由TIMx_CCMRx
寄存器的位ICxF[3:0]
配置。
TIMx_CCMR1
寄存器控制位IC2F[3:0]
和位IC1F[3:0]
,TIMx_CCMR2
寄存器控制位IC4F[3:0]
和位IC3F[3:0]
。
现在我们来说明一下这个IC1F[3:0]
是个什么玩意。IC1F[3:0]
即输入捕获1滤波器 (Input capture 1 filter),它定义了 TI1 输入的采样频率及数字滤波器长度。比如设置0001
表示采样频率f(SAMPLING) = f(CK_INT) = 72MHz
;再比如设置0100
表示采样频率f(SAMPLING) = f(DTS)/2
。
注意这里的f(DTS)
又是从哪里来的呢?它是从TIMx_CR1
的位CKD[1:0]
(时钟分频因子,Clock division)来的,这2位定义在定时器时钟(CK_INT)频率、死区时间和由死区发生器与数字滤波器(ETR,TIx)所用的采样时钟之间的分频比例。
(3)边沿检测
边沿检测的信号来自滤波器的输出,它有两种检测方式:上升沿有效和下降沿有效。
边沿检测由TIMx_CCER
寄存器的位CCxP(位1)
和CCxNP(位3)
配置。当 CC1 通道配置为输入时,0 表示上升沿检测,1 表示下降沿检测。
(4)触发选择
当使用外部时钟模式 1 时,触发源有两个,一个是滤波后的定时器输入 1(TI1FP1)和滤波后的定时器输入 2(TI2FP2)。
由TIMx_SMCR
寄存器的位TS[2:0]
配置,这3位选择用于同步计数器的触发输入。
(5)从模式选择
(本段内容来自野火教程PPT)选定了触发源信号后,最后我们需把信号连接到 TRGI 引脚,让触发信号成为外部时钟模式 1 的输入,最终等于 CK_PSC
,然后驱动计数器 CNT 计数。
具体的配置在TIMx_SMCR
寄存器的位SMS[2:0]
设置为 000 即可选择外部时钟模式 1。
(6)使能计数器
经过上面的 5 个步骤之后,最后我们只需使能计数器开始计数,外部时钟模式 1 的配置就算完成。
使能计数器由TIMx_CR1
寄存器的位CEN
配置。
3. 外部时钟模式 2
本内容分为以下部分讲解,如图所示:
(1)时钟信号输入引脚
当使用外部时钟模式2的时候,时钟信号输入引脚对应的是引脚TIMx_ETR
。
(2)外部触发极性
通过TIMx_SMCR
寄存器的位ETP
选择外部触发极性(External trigger polarity),0 表示高电平或上升沿有效,1 表示低电平或下降沿有效。
(3)外部触发预分频器
由于 ETRP(外部触发预分频,External trigger prescaler) 的信号的频率不能超过 TIMx_CLK(180MHz)的 1/4,当触发信号的频率很高的情况下,就必须使用分频器来降频。
具体由TIMx_SMCR
寄存器的位ETPS[1:0]
配置。
(4)滤波器
(本段出自野火教程PPT)如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对 ETRP 信号重新采样,来达到降频或者去除高频干扰的目的。由TIMx_SMCR
寄存器的位ETF[3:0]
配置。
(5)从模式选择
经过滤波器滤波的信号连接到 ETRF(外部触发输入) 引脚后,触发信号成为外部时钟模式 2 的输入,最终等于CK_PSC
,然后驱动计数器 CNT 计数。
具体的配置在TIMx_SMCR
寄存器的位ECE
为 1即可选择外部时钟模式 2。
(6)使能计数器
经过上面的 5 个步骤之后,最后我们只需使能计数器开始计数,外部时钟模式 1 的配置就算完成。
使能计数器由TIMx_CR1
寄存器的位CEN
配置。
4. 内部触发输入
本部分仅作了解即可。
内部触发输入的方式是使用一个定时器作为另一个定时器的预分频器。硬件上高级控制定时器和通用定时器在内部连接在一起,可以实现定时器同步或级联。因此,采用内部触发输入的时候,必须要用到两个 TIM 定时器,一个设置为主模式,另一个设置为从模式。
由TIMx_SMCR
寄存器的位TS[2:0]
配置。如下图为TIM1为TIM2提供时钟:
二、控制器
控制器主要分为三大部分:触发控制器、从模式控制器和编码器接口,所涉及的寄存器主要是 CR1、CR2、SMCR、CCER。这些控制器将信号传到预分频器后作为计数器 CNT的时钟,同时也有 TRGO 信号传到其他定时器或 DAC/ADC。
三、时基单元
时基单元包括:预分频寄存器(TIMx_PSC)、计数器寄存器(TIMx_CNT)、自动装载寄存器(TIMx_ARR)和重复次数寄存器(TIMx_RCR)。下图为时基单元的结构:
1. 预分频寄存器
可参见STM32中文参考手册13.3.1时基单元。
预分频器可以将计数器的时钟频率按 1 至 65536 之间任意分频,因此TIMx_PSC
寄存器一共有16位,计数器的时钟频率f(CK_CNT) = f(CK_PSC) / (PSC[15:0]+1)
,计数一次的时间为1 / f(CK_CNT)
。
注意上面的公式中 PSC 多加了 1,所以如果想分频 72,那么实际配置写入的应该是 71,比如f(CK_PSC) = 72MHz
,则f(CK_CNT) = 72MHz / (71+1) = 1MHz
,也就是 1us。
2. 计数器寄存器
可参见STM32中文参考手册13.3.2计数器模式。
(1)向上计数模式
计数器从 0 开始,每来一个CK_CNT
脉冲计数加 1 ,一直加到与自动装载值(即TIMx_ARR
寄存器的值ARR,一共16位)相等,然后计数器又从 0 开始计数,并产生一次上溢事件。
如果使能了重复计数器,每生成一次上溢事件,重复计数器减 1 ,在向上计数的次数达到设置的重复计数次数(即TIMx_RCR
寄存器的值,高八位保留,低八位为重复计数器的值REP)之后,即重复计数器的值为 0 时,产生一次更新事件(UEV)。
如果禁用了重复计数器,第一次生成上溢事件之后立刻产生一次更新事件(UEV)。
(2)向下计数模式
计数器从 ARR 开始,每来一个CK_CNT
脉冲计数减 1 ,一直减到 0 ,然后计数器又从 ARR 开始计数,并产生一次下溢事件。
如果使能了重复计数器,每生成一次下溢事件,重复计数器减 1 ,在向下计数的次数达到设置的重复计数次数(即TIMx_RCR
寄存器的值,高八位保留,低八位为重复计数器的值REP)之后,即重复计数器的值为 0 时,产生一次更新事件(UEV)。
如果禁用了重复计数器,第一次生成下溢事件之后立刻产生一次更新事件(UEV)。
(3)中心对齐模式(向上/向下计数)
在中心对齐模式中,计数器从 0 开始递增计数到 ARR-1,同时产生上溢事件,然后从 ARR 开始递减计数到 0 ,同时产生下溢事件,然后又从 0 开始计数。每次上溢事件和下溢事件都会产生更新事件。
3. 自动装载寄存器
自动装载寄存器 ARR 是用来存放与计数器 CNT 比较的值,如果两个值相等就递减重复计数器的值。
4. 重复次数寄存器
可参见STM32中文参考手册13.3.3重复计数器。
前面已经介绍过,向上计数模式下每次计数器上溢时,或向下计数模式下每次计数器下溢时,或中央对齐模式下每次上溢和每次下溢时,重复计数器的值会减 1。当寄存器的值为 0 时,会产生一次更新事件。
5. 影子寄存器
预分频寄存器(TIMx_PSC)和自动装载寄存器(TIMx_ARR)都有影子寄存器。影子寄存器起到一个缓冲的作用,它是起到真正作用的寄存器,但用户无法看见、也无法对其读写操作;与之相对应的是自动预装载寄存器,用户可以进行读写操作。
影子寄存器是由TIMx_CR1
寄存器的位ARPE
控制的,配置成 0 为TIMx_ARR
寄存器没有缓冲(即影子寄存器不被使用),修改 ARR 的值马上生效;配置成 1 为TIMx_ARR
寄存器被装入缓冲器(即影子寄存器被使用),只有在事件更新时才会把 ARR 的值赋值给影子寄存器。
为什么要弄一个影子寄存器呢?因为计数器在进行计数的时候可能会对预装载寄存器写入新的值,如果没有影子寄存器(也就是 ARPE = 0),那么溢出事件就会发生在不恰当或者你不希望的时机。引入了影子寄存器后(也就是 ARPE = 1),即使再去修改预装载的值,也不会影响到正在计数的计数器。说白了,这就是一个安全机制。
四、输入捕获
可参见STM32中文参考手册13.3.6输入捕获模式。
输入捕获可对上升沿和下降沿或者双边沿进行捕获,输入捕获最常见的应用是测量输入信号的脉宽和测量 PWM 信号输入的频率和占空比。
PWM 是什么呢?学过模电的同学应该很熟悉了。脉宽调制(Pulse Width Modulation,PWM) 就是脉冲宽度调制,我们可以通过 PWM 改变周期和占空比(即正脉冲的持续时间与脉冲总周期的比值)达到控制充电电流的目的。
基本原理:当检测到TIMx_CHy
边沿信号发生时,将计数器TIMx_CNT
的值锁存到捕获/比较寄存器TIMx_CCRy
里面,这就完成了一次捕获。如果把前后两次得到的 CCR 值进行相减,就可以算出频率或者脉宽(指高电平持续的时间tON)。如果 tON 超过捕获定时器的周期,就会发生溢出。
下图为输入捕获的功能框图:
1. 输入通道
被测量的信号从输入通道(或输入信号)TIMx_CHy
(y = 1,2,3,4),通常我们简写为TIy
。
2. 输入滤波器和边沿检测器
如果输入信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对输入信号重新采样,来达到降频或者去除高频干扰的目的。由TIMx_CCMRy
寄存器的位ICxF[3:0]
配置。关于滤波的采样频率与之前我们介绍的外部时钟模式 1 和 2 是通用的。
边沿检测的极性可由TIMx_CCER
寄存器的位CCxP
和CCxNP
来配置。
3. 捕获通道
图中ICx
(x = 1,2,3,4)是捕获通道,每个捕获通道对应不同捕获/比较寄存器TIMx_CCRy
,发生捕获时计数器 CNT 的值就会锁存到里面。
需要注意的是,一个输入通道的信号可同时输入两个捕获通道。比如图中,输入通道 TI1 经过滤波器后产生了 TI1FP1 和 TI1FP2,之后又分别输入到捕获通道 IC1 和 IC2,即 TI1 同时占用了两个捕获通道。
输入通道和捕获通道的映射关系由TIMx_CCMRy
(y = 1,2)寄存器的位CCxS[1:0]
(x = 1,2,3,4)配置。
4. 预分频器
ICx
经过预分频器,由TIMx_CCMRy
(y = 1,2)寄存器的位ICxPSC[1:0]
(x = 1,2,3,4)配置。
如果希望捕获输入信号的每一个边沿,则不需要分频;如果需要每隔 1 个周期捕获一次,则分频系数为 2。
5. 捕获寄存器
经过预分频器得到的信号ICxPSC
成为捕获的最终信号,当发生第一次捕获时,CNT 值会锁存到 CCR 寄存器中,同时TIMx_SR
寄存器的位CCxIF
(捕获/比较x中断标记)置 1,通过软件或通过读取 CCR 的值进行清零。如果发生第二次捕获,则TIMx_SR
寄存器的位CCxOF
(捕获/比较x重复捕获标记)置 1,只能通过软件置0。
五、输出比较
可参见STM32中文参考手册13.3.9输出比较模式。
输出比较是通过定时器的外部引脚对外输出控制信号。由TIMx_CCMR1
寄存器的位OCxM[2:0]
(输出比较x模式)可知,输出比较模式分为8种:
- 冻结
- 匹配时设置通道x为有效电平
- 匹配时设置通道x为无效电平
- 翻转
- 强制为无效电平
- 强制为有效电平
- PWM1(使用较多),在向上计数时,若寄存器的值 CNT = CCR,则 CH 为无效电平(OCxREF = 0),否则为有效电平(OCxREF = 1)
- PWM2(使用较多),在向上计数时,若寄存器的值 CNT = CCR,则 CH 为有效电平(OCxREF = 1),否则为无效电平(OCxREF = 0)。因此 PWM1 和 PWM2 正好互补、互为反相
PWM 输出信号频率由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。
下图为输出比较的功能框图:
1. 输出比较寄存器
当计数器 CNT 的值与捕获/比较寄存器 CCR 的值相等时,输出参考信号 OCxREF 的极性就会改变,并会产生比较中断 CCxI,对应TIMx_SR
寄存器的位CCxIF
(捕获/比较x中断标记)置 1。OCxREF 可直接作为主输出 OCx 和互补输出 OCxN 信号(与主信号反相),亦可经过控制器后输出信号。
2. 死区发生器
可以在参考波形 OCxREF 插入一段死区时间,由TIMx_BDTR
(刹车和死区)寄存器的位DTG[7:0]
死区发生器设置 (Dead-time generator setup)。关于死区持续时间(DT)的配置方法可见参考手册。
死区时间是怎么来的呢?由于在使用 PWM 输出时,上下桥 IGBT (绝缘栅双极型晶体管)或 MOS 管并不是理想的开关器件,总有一段时间(一般为 us 级别)两管同时导通,这样就会造成电源直接接地,电流过大导致炸管。因此我们需要延迟一段时间避免这种情况发生,这段时间被称为死区时间,如图所示:
需要注意的是,死区的插入是以牺牲有效输出为代价来保障驱动电路的安全性,所以没有必要设置的过长。
3. 输出控制
参考信号 OCxREF 经过死区控制器后来到输出控制电路,在这里兵分两路:一路是原始信号,另一路是反相信号,至于是否输出信号由TIMx_CCER
(捕获/比较使能)寄存器来使能。
4. 输出引脚
输出通道分为原始信号 TIMx_CHy(y = 1,2,3,4)和互补信号 TIMx_CHyN(y = 1,2,3,需要注意没有4)。
六、刹车断路功能
刹车源既可以是刹车输入引脚又可以是一个时钟失败事件(这时会启动 CSS 时钟安全系统)。
当使用刹车功能时,依据相应的控制位(TIMx_BDTR
寄存器中的 MOE、OSSI 和 OSSR 位,TIMx_CR2
寄存器中的 OISx 和 OISxN 位),输出使能信号和无效电平都会被修改。但无论何时,OCx 和 OCxN 输出不能在同一时间同时处于有效电平上。
附:PWM 波形的边沿对齐和中心对齐
可参见STM32中文参考手册13.3.10 PWM模式。
PWM 边沿对齐模式可分为向上计数和向下计数,主要用于直流电机。
PWM 中央对齐模式即向上/向下计数,主要用于交流电机。