简介
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。 它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。 使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 每个定时器都是完全独立的,没有互相共享任何资源。
时基单元
软件可以读写计数器CNT、自动重装载寄存器ARR和预分频寄存器PSC,即使计数器运行时也可以操作。
更新事件UEV的使能与来源
- 更新事件UEV的使能位
TIMx_CR1寄存器的UDIS位 UDIS位为0则将不再产生更新事件,但计数器和预分频器的计数器依然会在应产生更新事件时重新从0开始计数 UDIS位为1,当发生一次更新事件时所有影子寄存器会被更新 - 更新事件UEV的来源
更新中断和DMA请求的来源 TIMx_CR1寄存器的URS位
软件触发更新事件
写入事件产生寄存器TIM_EGR寄存器的UG位 置位UG位则产生更新事件 如果设置了TIMx_CR1寄存器中的URS位(选择更新请求) ,设置UG位可以产生一次更新事件UEV,但不设置UIF标志(即没有中断或 DMA请求)。 这是为了避免在捕获模式下清除计数器时,同时产 生更新和捕获中断。
计数模式
设置TIMx_CR1中的DIR方向位来选择计数方向
-
向上计数模式 在向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。 -
向下计数模式 在向下模式中,计数器从自动装入的值(TIMx_ARR计数器的值)开始向下计数到0,然后从自动装入的值重新开始并且产生一个计数器向下溢出事件。 -
中央对齐计数模式(向上/向下计数) 在中央对齐模式,计数器从0开始计数到自动加载的值(TIMx_ARR寄存器)?1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。在每次计数上溢和每次计数下溢时产生更新事件 在这个模式,不能写入TIMx_CR1中的DIR方向位。它由硬件更新并指示当前的计数方向。 可以通过(软件或者使用从模式控制器)设置TIMx_EGR寄存器中的UG位产生更新事件。然后,计数器重新从0开始计数,预分频器也重新从0开始计数。
时钟源
定时器时钟来源CK_PSC:
- 内部时钟(CK_INT)
- 外部时钟模式1:外部输入脚(TIx)
- 外部时钟模式2:外部触发输入(ETR)
- 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
CNT计数器的时钟由CK_CNT提供,CK_CNT的时钟频率等于fCK_PSC/(PSC[15:0]+1)
-
内部时钟(CK_INT) 如果禁止了从模式控制器(TIMx_SMCR寄存器的SMS=000),则CEN、DIR(TIMx_CR1寄存器)和UG位(TIMx_EGR寄存器)是事实上的控制位,并且只能被软件修改(UG位仍被自动清除)。只要CEN位被写成’1’,预分频器的时钟就由内部时钟CK_INT提供。 -
外部时钟模式1:外部输入脚(TIx) 当TIMx_SMCR寄存器的SMS=111时,此模式被选中。计数器可以在选定输入端的每个上升沿或下降沿计数。
输入捕获
输入部分对相应的TIx(引脚上的电平)输入信号采样,并产生一个滤波后的信号TIxF(逻辑信号0/1)。然后,一个带极性(上升沿/下降沿)选择的边缘检测器产生一个信号(TIxFPx),它可以作为从模式控制器的输入触发或者作为捕获控制。该信号(TIxFPx)通过预分频(预分频器内部含有一个预分频计数器,用来计TIxFPx的数目)进入捕获寄存器(ICxPS)。
通道1为例的输入捕获通道框图 通过CC1S来选择IC1的信号来源 通过ICPS来选择几个IC1信号等效于IC1PS信号。
在捕获模式下,捕获发生在影子寄存器上,然后再复制到预装载寄存器中。 在发生捕获时候,计数器CNT的值会被复制到捕获/比较影子寄存器中,然后从影子寄存器中再复制到捕获/比较预装载寄存器中。
在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存器(TIMx_CCRx)中。当捕获事件发生时,相应的CCxIF标志(TIMx_SR寄存器)被置’1’,如果使能了中断或者DMA操作,则将产生中断或者DMA操作。如果捕获事件发生时CCxIF标志已经为高,那么重复捕获标志CCxOF(TIMx_SR寄存器)被置’1’。写CCxIF=0可清除CCxIF,或读取存储在TIMx_CCRx寄存器中的捕获数据也可清除CCxIF。写CCxOF=0可清除CCxOF。
配置过程
fDTS的时钟频率通过控制寄存器 1(TIMx_CR1) 的CKD位控制
输入捕获-下降沿捕获-软件触发更新事件CNT
采用STM32F103C8T6单片机,KeilMDK5.32版本
定时器的使用内部时钟源 CK_PSC = CK_INT = 72MHz CK_CNT = 10KHz 计数器每计数一个数耗时0.0001s = 100us = 0.1ms 预分频器为72MHz / 10KHz = 7200 - 1 = 7199 计数器重装载值为65535 故最长计数为6.5535秒 PA0为定时器输入捕获通道1(CH1),下降沿捕获,CH1连接IC1 根据实际需求PA0配置PA0的模式 输入模式 上/下拉电阻 PC13控制LED灯,用杜邦线连接PA0与PC13,捕获LED的亮灭时间 开启更新中断,输入捕获通道1中断。在输入捕获回调函数中将计数CNT寄存器的值清零(在向上计数模式下)。也可以软件触发更新事件,但是需要将URS位置位(仅只有计数器溢出/下溢才产生更新中断或DMA请求)
发生捕获将flag |= 0x02,主函数中检查并复位flag,并输出信息到串口 延时1000ms,LED亮灭时间各持续一秒,下降沿捕获,故串口输出的值为2000ms左右。
回调函数 如果高电平/低电平的持续时间,需要写定时器溢出的逻辑代码 定时器初始化函数中,添加用户代码 置位USR位,在开启中断前西安清零相应标志位 定时器初始化注意点: 因为预分频PSC寄存器和重装载ARR寄存器有影子寄存器,真正起作用的是影子寄存器,在发生更新事件时,才将其值更新到其影子寄存器中,故在配置定时器后,需要软件触发更新时间(置位TIMx_EGR寄存器的UG位,此时URS位需为0)。重装载ARR寄存器也可以根据(TIMx_CR1寄存器的ARPE位来确定有没有缓冲,没有缓冲则立刻将其值更新到其影子寄存器中。 HAL库中TIM_Base_SetConfig()的代码也是这样写的,如下 STM32CubeMX配置 工程文件下载链接
串口使用了DMA,必须先初始化DMA再初始化串口,其他外设类似。 STM32CubeMX的BUG
PWM输入捕获
PWM输入捕获,用来测量PWM信号的周期与占空比,如下图:
复位模式 – 选中的触发输入(TRGI)的上升沿重新初始化计数器,并且产生一个更新寄存器的信号。
-
IC1上升沿捕获发生时,会产生一个TRGI信号,但是TRGI信号有一定延时,CCR1捕获寄存器复制CNT寄存器的值的时候,CNT寄存器还未复位。 -
IC2下降沿捕获,不会产生TRGI信号,CCR2捕获寄存器复制CNT寄存器的值 -
同1
通过URS位来确定是否需要使用复位模式产生的中断 不需要则置位URS位
由于只有TI1FP1和TI2FP2连到了从模式控制器,所以PWM输入模式只能使用TIMx_CH1 /TIMx_CH2信号。
配置过程
PWM输入捕获-复位模式demo
采用STM32F103C8T6单片机,KeilMDK5.32版本
定时器的使用内部时钟源 CK_PSC = CK_INT = 72MHz CK_CNT = 10KHz 计数器每计数一个数耗时0.0001s = 100us = 0.1ms 预分频器为72MHz / 10KHz = 7200 - 1 = 7199 计数器重装载值为65535 故最长计数为6.5535秒 PA0为定时器输入捕获通道1(CH1),上升沿捕获,CH1连接IC1 根据实际需求PA0配置PA0的模式 输入模式 上/下拉电阻 IC2连接CH1,下降沿捕获 复位模式,选择TRGI触发源选择TI1PF1 PC13控制LED灯,用杜邦线连接PA0与PC13,捕获LED的亮灭时间
复位模式会产生更新事件,根据URS位来确定是否要使用这个更新事件
定时器初始化函数用户添加的代码 回调函数
主函数
STM32CubeMX配置 也可以使能触发中断
__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_TRIGGER);
回调函数如下 工程文件下载链接
输出比较
此项功能是用来控制一个输出波形,或者指示一段给定的的时间已经到时。
输出模式如下图:
OCxM位的值:
- 000:CCR与CNT寄存器的值进行比较不能影响OC引脚的电平状态,被冻结,对OCxREF也没影响。
- 001:仅当CCR与CNT寄存器的值相等的这一时刻起作用(其他时刻不进行比较),将OC引脚的电平状态设置位有效电平,OCxREF为高电平。OC有效电平由捕获/比较使能寄存器(TIMx_CCER) 的CCxP位进行设置。
- 010:仅当CCR与CNT寄存器的值相等的这一时刻起作用(其他时刻不进行比较) ,将OC引脚的电平状态设置位无效电平,OCxREF为低电平。
- 011:仅当CCR与CNT寄存器的值相等的这一时刻起作用(其他时刻不进行比较),OC引脚电平状态进行翻转,OCxREF也翻转。
- 100:不介绍
- 101:不介绍
- 110:PWM1,
在向上计数模式下,TIMx_CNT<TIMx_CCR1,将OC引脚设置为有效电平,OCxREF设置为高电平;TIMx_CNT>TIMx_CCR1,OC引脚设置为无效电平,OCxREF设置为低电平。 在向下计数模式,TIMx_CNT<TIMx_CCR1,将OC引脚设置为有效电平,OCxREF设置为高电平;TIMx_CNT>TIMx_CCR1,OC引脚设置为无效电平,OCxREF设置为低电平。 - 111:PWM2与PWM相反
配置过程
PWM输出
脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。
配置过程
- 选择计数器时钟(内部,外部,预分频器)
- 将相应的数据写入TIMx_ARR和TIMx_CCRx寄存器中
- 如果要产生一个中断请求和/或一个DMA请求,设置CCxIE位和/或CCxDE位。
- 选择输出模式(PWM1/PWM2),设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器(捕获/比较寄存器CCRx也有影子寄存器,置位OCxPE位来使能缓冲),设置TIMx_CR1寄存器的ARPE位(使能重装载寄存器的缓冲),OCx的有效极性在TIMx_CCER寄存器中的CCxP位设置
- 设置TIMx_CCER寄存器中的CCxE位控制OCx输出使能,设置TIMx_CR1寄存器的CEN位启动计数器
在PWM模式(模式1或模式2)下,TIMx_CNT和TIMx_CCRx始终在进行比较。 当发生一个更新事件的时候,预装载寄存器才能被传送到影子寄存器,因此在计数器开始计数之前,必须通过设置TIMx_EGR寄存器中的UG位来初始化所有的寄存器。
计数模式
PWM输出-呼吸灯demo
采用STM32F103C8T6单片机,KeilMDK5.32版本
定时器的使用内部时钟源 CK_PSC = CK_INT = 72MHz CK_CNT = 10KHz 计数器每计数一个数耗时0.0001s = 100us = 0.1ms 预分频器为72MHz / 10KHz = 7200 - 1 = 7199 计数器重装载值为100 故计数周期为10ms PWM周期为10ms,计数器计一个数为0.1ms ,每25ms调整一次占空比(5~95%) PA6为定时器PWM捕获通道1(CH1),捕获/比较寄存器的值初始化为5 PC13控制LED灯,用杜邦线连接PA6与PC13
在HAL库的定时器初始化函数中添加用户代码
主函数中每25ms调整一次占空比
STM32CubeMX配置 工程文件下载链接
单脉冲模式
单脉冲模式(OPM)是前述众多模式的一个特例。这种模式允许计数器响应一个激励,并在一个程序可控的延时之后,产生一个脉宽可程序控制的脉冲。 定时器仅运行一次,产生一次更新事件后,失能定时器。
可以在PWM输出模式下,设置定时器的分频,重装载值,捕获/比较寄存器的值,来输出PWM波。如下图,设置PWM的周期与占空比,输出一个长度可设置的脉冲信号。
单脉冲模式-PWM输出demo
采用STM32F103C8T6单片机,KeilMDK5.32版本
采用2个定时器 定时器2 为PWM输入捕获,复位从模式(触发则复位CNT寄存器),通道1(PA0)上升沿触发,IC1上升沿捕获,IC2下降沿捕获,开启IC1捕获中断。IC1和IC2连接到通道1(PA0),PA设置为下拉输入。分频为7200 计一个数为0.1ms,重装载值为65535。 定时器3为PWM输出模式,触发从模式(触发则使能定时器),通道2(PA7)下降沿触发,OC1(PA6)为PWM输出模式。分频为7200 计一个数为0.1ms,重装载值为100,CCR1寄存器为50,故OC1(PA6)PWM波周期为10ms,占空比为50%。 定时器3在单脉冲模式(发生更新事件则失能定时器,也就10ms后失能定时器)。 单脉冲模式负责失能定时器,触发从模式(通道2 PA7检测到上升沿信号)负责使能定时器。 PC13控制LED灯,每50ms亮灭一次。 用杜邦线连接PA0和PA6,连接PA7和PC13。 则输出的PWM波高电平持续时间为95ms,低电平为5ms,可以自己画一下波形图分析。
STM32CubeMX配置 定时器2设置 定时器3设置
HAL库的TIM2初始化函数添加用户代码 捕获回调函数 HAL库的TIM3初始化添加用户代码 主函数 工程文件下载链接
|