1、TIM简介
1.1 基本定时器
时基单元:由自动重装载寄存器、预分频器、计数器组成。
来自RCC的TIMxCLK:一般是系统的主频,72MHz。
预分频器(16位):对进来的频率进行分频,写0,不分频,输出72MHz。写1,2分频,输出36MHz。以此类推。
计数器(16位):对预分频器后的计数时钟进行计数。
自动重装载寄存器(16位):写入的计数目标。
向上的箭头(UI):表示这里会产生中断信号。计数值等于自动重装值产生的中断,一般叫做“更新中断”,更新中断之后会通往NVIC,再配置好NVIC的定时器通道,那定时器的更新中断就可以得到CPU的响应。
向下的箭头(U):表示这里会产生一个事件。对应的事件叫做“更新事件”,更新事件不会触发中断,但会触发内部的其他电路的工作。
主模式触发DAC功能:定时器设计了一个主模式,使用主模式可以把定时器的更新事件映射到触发输出TRGO(Trigger Out)的位置,TRGO直接接到DAC的触发转换引脚上。定时器的更新就不需要通过中断来触发DAC转换了。
基本定时器仅支持向上计数模式。
1.2 通用定时器
基本定时器支持向上计数、向下计数、中央对齐的计数模式。
时钟源选择:可以选择内部时钟,也可以选择外部时钟。外部时钟:TIMx_ETR(Externala)引脚上的外部时钟。
外部时钟模式2。ETRF:经过ETRF进入触发控制器,就可以选择作为时基单元的时钟了。这一路叫做“外部时钟模式2”。
外部时钟模式1。TRGI:主要用作触发输入。当TRGI当作外部时钟来使用时,这一路叫做“外部时钟模式1”。通过这一路的时钟有:①ETR的引脚信号,②ITR信号,ITR0-ITR3分别来自其他4个定时器的TRGO输出。可以用作定时器的级联。③TI1F_ED(Edge,边沿)信号:连接的是输入捕获单元的CH1引脚。④TI1FP1信号:连接到CH1引脚的时钟。TI2FP2信号:连接到CH2引脚的时钟。
ITR信号:
编码器接口:可以读取正交编码器的输出波形。
TRGO:定时器的主模式输出,可以把内部的一些事件映射到TRGO引脚上。
输出比较电路:图右下角,有四个通道,CH1--CH4。可以用于输出PWM波形,驱动电机等。
输入捕获电路:图左下角,有四个通道,CH1--CH4。可以用于测量输入方波信号的频率等。
捕获/比较寄存器:是输入捕获和输出比较电路共用的。输入捕获和输出比较不能共用,因此寄存器和引脚也是共用的。
输入滤波器原理:可以滤掉信号的抖动干扰。在一个固定的时钟频率f下进行采样,如果连续N个采样点都为相同的电平,代表输入信号稳定,即可输出采样值。如果N个采样值不全都相同,说明信号有抖动,此时保持上一次的输出或者直接输出低电平。采样频率f和采样点数N都是滤波器的参数。采样频率f可以是由①内部时钟直接而来,也可以是②内部时钟+分频而来,分配多少,由参数TIM_ClockDivision 决定。TIM_ClockDivision 见5.3配置时基单元代码。
1.3 高级定时器
重复次数计数器:可以实现每隔几个周期,才发生一次更新事件和更新中断。
DTG(Dead Time Generate):死区生产电路。右边输出控制有两个互补的信号,可以输出一对互补的PWM波,可以用于驱动三相无刷电机。如:四轴飞行器、电动车的后轮、电钻等。
BRK:刹车输入功能,为了给电机驱动提供安全保障。如果外部引脚BKIN(Break IN)产生了刹车信号,或者内部时钟失效,产生了故障,控制电路会自动切断电机的输出。
2、定时中断基本结构
PSC(Prescaler):预分频器
CNT(Counter):计数器
ARR(Auto Reload Register):自动重装载寄存器
运行控制:控制寄存器的一些位。如启动停止、向上或向下计数等。
计时时间到产生中断的去向:中断信号会先在状态寄存器里置一个中断标志位,这个标志位会通过中断输出控制,到NVIC申请中断。
中断输出控制:因为定时器很多地方需要申请中断,如:更新申请中断,触发信号也会申请中断,输入捕获和输出比较匹配时也会申请中断。就是中断输出的允许位,需要某个中断,就允许一下。
3、时序图
3.1 预分频器时序图
CK_PSC:预分频器的输入时钟,内部时钟一般是72MHz。
CNT_EN:计数器使能,高电平计数器正常运行,低电平计数器停止。
CK_CNT:预分频器的时钟输出,也是计数器时钟的输入。
一个计数周期的工作流程:开始时,计数器不使能,定时器时钟不运行。计数器使能后,前半段,预分频器系数为1,定时器时钟等于预分频前的时钟;后半段,预分频器系数为2,定时器时钟等于预分频前时钟的一半。在定时器时钟的驱动下,计数器寄存器跟随时钟的上升沿不断自增,ARR自动重装值为FC。当计数值计到和重装值相等,并且下一个时钟来临时,计数器寄存器的值才清0。同时产生一个更新事件(UEV)。
下三行时序:预分频控制寄存器,供我们读写用的,并不直接决定分频系数。预分频缓冲器或者影子寄存器:真正起作用的寄存器。当在计数中间改变预分频器的值(预分频控制寄存器),不会马上更新,要等到计数到自动重装值,并产生更新事件后,才会更改预分频器的值(预分频缓冲器)。
3.2 计数器时序
CK_INT:内部时钟72MHz。
计数器无预装时序:没有缓冲寄存器的情况。
计数器有预装时序:有缓冲寄存器的情况。
通过设置ARPE位,可以选择是否使用预装功能。
4、 RCC时钟树
左边是时钟的产生电路,右边是时钟的分配电路。
4.1 时钟产生电路
有四个震荡源:
①内部的8MHz高速RC振荡器;
②OSC_OUT,OSC_IN:外部的4-16MHz高速石英晶体振荡器,也就是晶振,一般都是接8MHz;外部的石英振荡器比内部的RC振荡器更加稳定。一般使用外部晶振。
③OSC32_IN,OSC32_OUT:外部的32.768KHz低速晶振,一般给RTC提供时钟。
④LSI RC:内部的40KHz低速RC振荡器,可以给看门狗提供时钟。
高速时钟晶振用于提供系统时钟,如AHB、APB2、APB1都是来源于这两个高速晶振。
在SystemInit函数里,ST配置时钟:①首先启动内部时钟,选择内部8MHz为系统时钟,暂时以内部8MHz的时钟运行。②然后再启动外部时钟,经过PLLXTPRE、PLLSRC,进入PLLMUL(PLL锁相环)进行倍频,8MHz倍频9倍,得到72MHz。等到锁相环输出稳定后,选择锁相环输出为系统时钟。系统时钟就从8MHz切换成了72MHz。
CSS(Clock Security System):时钟安全系统,负责切换时钟。可以监测外部时钟的运行状态,一但外部时钟失效,就会自动把外部时钟切换回内部时钟,保证系统时钟的运行,防止程序卡死造成事故。
4.2 时钟分配电路
①AHB总线有个预分频器,在SystemInit里配置的分频系数为1,故AHB总线的时钟为72MHz。
②然后进入APB1总线,这里配置的分频系数为2,故APB1总线的时钟为36MHz。
故基本定时器、通用定时器的时钟都为72MHz。
③APB2总线,在这里配置的分频系数为1,故APB1总线的时钟为72MHz。
故高级定时器的时钟都为72MHz。
④外设时钟使能,就是程序中RCC_APB2/1PeriphClockCmd的地方。
5、TIM中断初始化代码
根据定时中断基本结构来一步一步初始化定时器中断代码:
(1)开启外部时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
(2)选择时基单元的时钟
①选择内部时钟作为时基单元时钟
TIM_InternalClockConfig(TIM2);
定时器上电后默认使用的就是内部时钟,可以省略。
②选择ETR外部时钟作为时基单元时钟
TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
选择外部时钟作为时基单元时钟,可能需要配置GPIO,视情况而定。配置GPIO就需要开启外部时钟以及引脚等配置。
(3)配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_Period ,ARR自动重装器的值
TIM_Prescaler ,PSC预分频器的值
TIM_RepetitionCounter ,重复计数器的值
因为TimeBaseInit里面有上述那句话,为啥要上述那句?
因为预分频器是有缓冲寄存器的,写的值只有在更新事件时,才会真正起作用,这里为了让值立刻起作用,手动生成了一个更新事件,这样预分频器的值就有效了。但同时带来了副作用:更新事件和更新中断是同时发生的,更新中断会置更新中断标志位,一旦程序初始化完,更新中断就会立刻进入,会导致刚一上电,就立刻进中断。
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
因此需要增加上述手动清除更新中断标志位代码。
(4)使能更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
(5)配置NVIC文章来源:https://www.toymoban.com/news/detail-813610.html
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
(6)启动定时器文章来源地址https://www.toymoban.com/news/detail-813610.html
TIM_Cmd(TIM2, ENABLE);
到了这里,关于STM32笔记----5、TIM定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!