简单的通用定时器
通用定时器TIMx(2,3,4,5)
TIMx简介
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它实用与很多场合,如:测试输出信号的脉冲长度(输入捕获),产生输出波形(输出比较和PWM)。
注:每个定时器都是独立工作的。
TIMx主要功能
1: 16位的向上,向下,向上/向下自动装载计数器。(TIMx_CR1的DIR位)
2:16位可编程预分频器,计数器时钟的频率系数在1~65536。(TIMx_PSC)
3:4个独立通道 (配置TIMx_CCMRx的CC2S[1:0]和OCxM[2:0])
A. 输入捕获
B. 输出比较
C. PWM生成
D. 单脉冲模式输出
4:支持针对定位的增量(正交)编程器和霍尔传感器比较。
时基单元
计数器寄存器(TIMx_CNT)
预分频寄存器(TIMx_PSC)
自动装载寄存器(TIMx_ARR)
自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在
TIMx_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在每次的更新事件UEV时传送到影子寄存器 。
预分频器可以将计数器的时钟频率按1到65526之间的任意值分频。它是基于一个(在TIMx_PSC寄存器中的)位寄存器控制的16位计数器,这个寄存器由一个缓冲器,在寄存器工作时当出现更新记录新的预分频数,在下一次事件更新时对TIMx_PSC进行更新。
计数器时对分频后时时钟进行计数。
计数器模式
这个很好理解,计数器向上计数时,计数器的数值0开始计数直到预定数值(TIMx_ARR中的值)。然后产生一个计数器溢出事件。向下计数是从预定值(TIMx_ARR)到0,然后产生一个(下)溢出事件。
在中央对齐模式,计数器从0开始计数到自动加载的值-1(TIMx_ARR-1),产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。
设置计数器计数模式在TIMx_CR1的DIR位,但是对于中央对齐模式该位只用于读。对于中央对齐模式设置的是TIMx_CR1的CMS[1:0]位。
更新事件的产生可以是在一个溢出事件到来的时候,也可以是设置TIMx_EGR寄存器的UG位。
产生事件更新时,所有寄存器被更新。(预分频器被更新,自动装载影子寄存器被重新置入预装载寄存器的值 )
设置TIMx_CR1寄存器中的UDIS位,可以禁止更新事件;这样可以避免在向预装载寄存器中的入新值时更新影子寄存器。
如果设置了TIMx_CR1寄存器中的URS位(选择更新请求),设置UG位将产生一个更新事件UEV,但硬件不设置UIF标志(即不产生中断或DMA请求);这是为了避免在捕获模式下清除计数器时,同时产生更新和捕获中断 。
时钟选择
- 内部时钟(CK_INT) SMS=000;
- 外部时钟模式1:外部输入脚(TIx) SMS=111;
- 外部时钟模式2:外部触发输入(ETR)
- 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器。
在设内部时钟和外部时钟模式1时:设置TIMx_SMCR寄存器的SMS[3;0]位可以选着时钟模式。
在设置外部时钟模式2时:设置TIMx_SMCR寄存器中的ECE=1
设置位内部触发输入时: 配置定时器x1为主模式,它可以在每一个更新事件UEV时输出一个周期性的触发信号。在TIMx1_CR2寄存器的MMS=’010’时,每当产生一个更新事件时在TRGO1上输出一个上升沿信号 设置TIMx2_SMCR寄存器的TS=’000’,配置定时器x2为使用ITR1作为内部触发的从模式 然后把从模式控制器置于外部时钟模式x1(TIMx2_SMCR寄存器的SMS=111);这样定时器x2即可由定时器x1周期性的上升沿(即定时器x1的计数器溢出)信号驱动
定时器几种常用用法(参考资料)
输入捕获
在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存器(TIMx_CCRx)中。当捕获事件发生时,相应的CCxIF标志(TIMx_SR寄存器)被置’1’,如果使能了中断或者DMA操作,则将产生中断或者DMA操作。如果捕获事件发生时CCxIF标志已经为高,那么重复捕获标志CCxOF(TIMx_SR寄存器)被置’1’。写CCxIF=0可清除CCxIF,或读取存储在TIMx_CCRx寄存器中的捕获数据也可清除CCxIF。写CCxOF=0可清除CCxOF。
以下例子说明如何在TI1输入的上升沿时捕获计数器的值到TIMx_CCR1寄存器中,步骤如下:
● 选择有效输入端: TIMx_CCR1必须连接到TI1输入,所以写入TIMx_CCR1寄存器中的CC1S=01,只要CC1S不为’00’,通道被配置为输入,并且TM1_CCR1寄存器变为只读。
● 根据输入信号的特点,配置输入滤波器为所需的带宽(即输入为TIx时,输入滤波器控制位是TIMx_CCMRx寄存器中的ICxF位)。假设输入信号在最多5个内部时钟周期的时间内抖动,我们须配置滤波器的带宽长于5个时钟周期。因此我们可以(以fDTS频率)连续采样8次,以确认在TI1上一次真实的边沿变换,即在TIMx_CCMR1寄存器中写入IC1F=0011。
● 选择TI1通道的有效转换边沿,在TIMx_CCER寄存器中写入CC1P=0(上升沿)。
● 配置输入预分频器。在本例中,我们希望捕获发生在每一个有效的电平转换时刻,因此预分频器被禁止(写TIMx_CCMR1寄存器的IC1PS=00)。
● 设置TIMx_CCER寄存器的CC1E=1,允许捕获计数器的值到捕获寄存器中。
● 如果需要,通过设置TIMx_DIER寄存器中的CC1IE位允许相关中断请求,通过设置
TIMx_DIER寄存器中的CC1DE位允许DMA请求。当发生一个输入捕获时:
● 产生有效的电平转换时,计数器的值被传送到TIMx_CCR1寄存器。
● CC1IF标志被设置(中断标志)。当发生至少2个连续的捕获时,而CC1IF未曾被清除,
CC1OF也被置’1’。
● 如设置了CC1IE位,则会产生一个中断。
● 如设置了CC1DE位,则还会产生一个DMA请求。
为了处理捕获溢出,建议在读出捕获溢出标志之前读取数据,这是为了避免丢失在读出捕获溢出标志之后和读取数据之前可能产生的捕获溢出信息。
在捕获/比较使能寄存器的(CC1E)位配置通道为输入还是输入
输入捕获模式可以用来测量脉冲宽度或者测量频率。 我们以测量脉宽为例,用一个简图来
说明输入捕获的原理,如图 所示:
输入捕获脉宽测量原理
如图 所示,就是输入捕获测量高电平脉宽的原理,假定定时器工作在向上计数模式,
图中 t1~t2 时间,就是我们需要测量的高电平时间。测量方法如下:首先设置定时器通道 x 为上升沿捕获,这样, t1 时刻,就会捕获到当前的 CNT 值,然后立即清零 CNT,并设置通道 x为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。 这样,根据定时器的计数频率,我们就可以算出 t1~t2 的时间,从而得到高电平脉宽。在 t1~t2 之间,可能产生 N 次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。如图 15.1.1所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。
输入/捕获模式相关的寄存器(TIMx_CCMRx,TIMx_CCER,TIMx_CR1)
配置过程:
基本设置:
配置相应的时钟使能(定时器时钟,和GPIO时钟)
配置相应映射关系,IC映射到不同的地方,GPIO的设置也并不相同(在
TIMx_CCMRx中)
设置相应的捕获分频
设置相应滤波器
对相应的定时器进行基本的设置(ARR,PSC)
设置相应中断使能(更新中断)
打开相应捕获/比较使能寄存器(设置捕获使能和捕获信号极性)
设置配置寄存器。打开计数器使能
配置中断服务函数。
中断服务函数
对于一个输入\捕获来说,当一个中断到来时需要检测信号(溢出后的中断,和输入\捕获的中断)对于一个溢出后的中断,记录中断次数,同时要检测捕获是否超时(捕获时间太长久认为一次输入\捕获发生),对于一个输入\捕获引起的中断,判断捕获的信号的类型(一次捕获,清空计数器和溢出数标志,同时设置新的捕获边沿(先上升后下降,先下降后上升)),当第二次捕获到第二个输入引起的中断时,设置一次完整的捕获完成,同时设置新的捕获边沿。对于一个中断服务函数最后还要清除中断标志。
PWM模式
脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,最后还要设置TIMx_CR1寄存器的ARPE位, (在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。
仅当发生一个更新事件的时候,预装载寄存器才能被传送到影子寄存器,因此在计数器开始计数之前,必须通过设置TIMx_EGR寄存器中的UG位来初始化所有的寄存器。
OCx的极性可以通过软件在TIMx_CCER寄存器中的CCxP位设置,它可以设置为高电平有效或低电平有效。 TIMx_CCER寄存器中的CCxE位控制OCx输出使能。
PWM的原理图:
上图 就是一个简单的 PWM 原理示意图。图中,我们假定定时器工作在向上计数 PWM
模式,且当 CNT<CCRx 时,输出 0,当 CNT>=CCRx 时输出 1。那么就可以得到如上的 PWM
示意图:当 CNT 值小于 CCRx 的时候, IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。
配置PWM:
设置相应时钟使能(GPIO和辅助时钟)
配置相应的的GPIO口为输出模式
配置相应的自动装载寄存器和预分频寄存器
配置PWM模式。(CCMR)
{
在OCxM位设置PWM模式一般为110或111
配置CCxE位,这一位是输入\捕获使能位,在(CCER)中,想要PWM从IO输出,改为要设置位1
}
打开相应ARPE(CR1)
打开相应的计数器使能位。
对TIMx_CCRn寄存器写入相应的值来控制脉宽长度
时间长度(s)=PSC/P(外)*(ARR-CCR)
PSC为预分频时间,P(外)为外部时钟,ARR自动装载寄存器的值,CCR为捕获/比较寄存器的值。