STM32 - 定时器1 - 定时器详解
1. 什么是定时器
1.1 数量&来源
STM32F4具备总共14
个定时器(12个16bit定时器,2个32bit定时器)(递增、递减和递增/递减自动重载计数器),分别为:
- 基本定时器:TIM6 & TIM7
- 通用定时器:TIM2 ~ TIM5(TIM2 & TIM5位32bit计数器), TIM9 ~ TIM14
- 高级定时器:TIM1 & TIM8
定时器引脚皆由GPIO每个引脚配置为复用功能而来(GPIO每个引脚PA0-PA15 ... PG0-PG15, 最多可具有 16 个复用功能,输入/输出共用),如下图所示:
1.2 用途
定时器具备多种用途,包括:
- 输入捕获:测量输入信号的脉冲宽度
- 输出比较:计数器模式
- PWM:边缘或中间对齐模式
- 单脉冲模式输出
发生如下事件时生成中断/DMA 请求:
- 更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)
- 触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
- 输入捕获:
- 输出比较:
使用定时器预分频器和 RCC 时钟控制器预分频器,可将脉冲宽度和波形周期从 us → ms (调制)
2. 通用定时器框图
从如下定时的框图可以看出,定时器主要包括四个部分:
- 输入时钟源:选择不同的时钟源
- 时基单元:对时钟进行分频、计数等处理
- 输入捕获:4个输入通道
- 输出比较:输出控制
2.1 输入时钟
通用定时器的时钟来源通常有四种:
- 内部时钟: CK_INT
- 外部时钟模式 1:外部输入引脚TIx(x=1,2,3,4),计数器可在选定的输入信号上出现上升沿或下降沿时计数
- 外部时钟模式 2:外部触发输入 ETR (External TRigger),计数器可在外部触发输入 ETR 出现上升沿或下降沿时计数。
- 内部触发输入(ITRx,Internal TRigger(x=0,1,2,3))(编码器模式):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1作为另一个定时器Timer2的预分频器。
如上图,TIM1、TIM8、TIM10、TIM11使用的是APB2时钟,而其余定时器使用的是APB1时钟,具体可参考 STM32 - 时钟系统详解
2.2 时基单元
时基单元主要由三个寄存器组成:
● 计数器寄存器 (TIMx_CNT):记录分频后的时钟CK_CNT脉冲个数
● 预分频器寄存器 (TIMx_PSC):对计数器时钟频率进行分频,系数介于 1~65536 之间
● 自动重载寄存器 (TIMx_ARR):预装载,可选择立即生效或下一次发生更新事件时生效
工作流程:
- 输入时钟的脉冲信号CK_PSC,经过PSC分频后,生成CK_CNT脉冲时钟;
- 每个CK_CNT脉冲到来,寄存器TIMx_CNT计数 +1/-1(可设置为向上、向下、向上向下计数);
- 当TIMx_CNT的值等于TIMx_ARR时,产生更新事件(UEV)
下图为 预分频器分频由 1 变为 2 时的计数器时序图
2.3 输入捕获/输出比较通道
1)输入阶段:
- 输入阶段对相应的 TIx 输入进行采样,生成一个滤波后的信号 TIxF。
- 然后,带有极性选择功能的边沿检测器生成一个信号 (TIxFPx),该信号可用作从模式控制器的触发输入,也可用作捕获命令。
- 该信号先进行预分频 (ICxPS),而后再进入捕获寄存器
2)输出阶段:
- 捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。始终可通过读写操作访问预装载寄存器。
- 在捕获模式下,捕获实际发生在影子寄存器中,然后将影子寄存器的内容复制到预装载寄存器中。
- 在比较模式下,预装载寄存器的内容将复制到影子寄存器中,然后将影子寄存器的内容与计数器进行比较。
3. 模式配置
3.1 计数器模式
计数器模式,个人理解,就是时基电路中的工作模式,包括:
- 递增计数模式:计数器从 0 计数到自动重载值(TIMx_ARR),然后重新从 0 开始计数并生成计数器上溢事件
- 递减计数模式:计数器从自动重载值(TIMx_ARR)开始递减计数到 0,然后重新从自动重载值开始计数并生成计数器下溢事件
- 中心对齐模式:计数器从 0 开始计数到自动重载值(TIMx_ARR 寄存器的内容)— 1,生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从 0 开始重新计数。
递增计数器时序图,2 分频内部时钟(ARR=36):
递减计数器时序图,2 分频内部时钟(ARR=36)
中心对齐计数器时序图,2 分频内部时钟(ARR=36)
3.2 PWM模式
PWM,(Pulse Width Modulation,脉冲宽度调制),是利用处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,其原理如下(以定时器工作在向上计数的PWM模式为例):
- 当CNT<CCRx时,为低电平;当CNT>=CCRx时,为高电平
- 当CNT=ARR时,CNT重新归零,并重新计数,依次循环
使用定时器做PWM输出,需要如下的配置:
- 开启 TIMx 时钟,配置 GPIO引脚 选择复用功能 (如AF8)输出:AF8输出PWM波
- 设置 TIMx 的 ARR 和 PSC
- 设置 TIMx_CHx 的 PWM 模式:设置定时器为PWM
- 使能 TIMx 的 CHx 输出,使能 TIMx
- 修改 TIMx_CCRx 来控制占空比
使用到了如下几个寄存器:
1) TIMx_CR1:控制寄存器
2) TIMx_DIER:DMA/Interrupt Enable, 中断使能寄存器
单通道使能和整体使能:
3) TIMx_SR:TIMx 状态寄存器
4) TIMx_PSC:TIMx 预分频器
5) TIMx_ARR:TIMx 自动重载寄存器
6) TIMx_CCMR1:TIMx 捕获/比较模式寄存器 1
输出模式:
输入模式:
- 输入捕获 1 滤波器 IC1F[3:0],这个用来设置输入采样频率和数字滤波器长度。
Fck_int
是定时器的输入频率(TIMxCLK),一般为 84Mhz/168Mhz(看该定时器在那个总线上)FDTS
是根据TIMx_CR1的CKD[1:0]的设置来确定的,如果CKD[1:0]设置为00,那么 Fck_int = Fdts。- N 值就是滤波长度
共用:
7) TIMx_CCER:TIMx 捕获/比较使能寄存器
8) TIMx_CCR1:TIMx 捕获/比较寄存器 1
3.3 输入捕获模式
输入捕获模式可以用来测量脉冲宽度或者测量频率。我们以测量脉宽为例,用一个简图来说明输入捕获的原理
假定定时器工作在向上计数模式,图中 t1~t2 时间,就是我们需要测量的高电平时间。
测量方法如下:
- 首先设置定时器通道 x 为上升沿捕获,这样,t1 时刻,就会捕获到当前的 CNT 值,
- 然后立即清零 CNT,并设置通道 x为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。
- 这样,根据定时器的计数频率,我们就可以算出 t1~t2 的时间,从而得到高电平脉宽
在 t1~t2 之间,可能产生 N 次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。
t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2
,有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。
使用定时器做 输入捕获,需要如下的配置:
- 开启 TIMx 时钟,配置 GPIO引脚 选择复用功能 (如AF8)输出:AF8输出PWM波
- 设置 TIMx 的 ARR 和 PSC
- 设置 TIMx 的 CCMR1
- 设置 TIMx 的 CCER,开启输入捕获,并设置为上升沿捕获。
- 设置 TIMx 的 DIER,使能捕获和更新中断,并编写中断服务函数
- 设置 TIMx 的 CR1,使能定时器