一、定时器功能与特点
1.STM32根据型号不同,定时器数目不同,本开发板是 2个高级定时器、4个通用定时器、2个基本定时器。每个定时器都有四个独立的通道。
2.16 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。(1)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数值。(2)4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:① 输入捕获 ② 输出比③ PWM 生成(边缘或中间对齐模式) ④ 单脉冲模式输出 。(3)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
③中央对齐模式(向上/向下计数):事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。计数器从0开始计数到自动装入的值-1,产生一个计数器溢出
二、通用定时器工作过程
1.通用定时器总共分为四个部分,1.时钟产生部分。2.时基单元。3.输入捕获。4.输出比较。
2.定时器时钟来源主要来自1.内部时钟。2.外部触发输入(ETR),可根据引脚查看。3.内部触发输入(ITRx),主要来自定时器的级联,来自其他的定时器。4.外部输入脚(TIx),最终还是来自定时器外部通道,TIMx_CH1等。最常用的还是内部时钟。
3.时基单元,由时钟产生部分产生时钟源(ck_psc),经分频器产生最终的计数器时钟(CK_CNT),在触发控制器确定计数器的计数模式,并且自己设置自动重装载寄存器的值,当计数器到达值产生更新事件,如果开启中断就会进入中断函数。
4.输入捕获,主要是捕获对应的芯片引脚的电平进行捕获,可以设置上升沿/下降沿捕获,经过输入捕获寄存器可以把CNT计数器的值记下来。
5.输出比较,可以在捕获/比较寄存器里面设置数值,当计数器里的值高于比较寄存器的值可以在输出通道输出高电平,低于则可以输出低电平,最终可以产生一个固定占空比的波形。
三、定时器相关库函数及其功能
1.void TIM_DeInit(TIM_TypeDef* TIMx);
对TIMx进行初始化,采用RCC_APB2PeriphResetCmd()函数进行初始化。
2.void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
对定时器进行初始化配置,1.选择那个定时器。2.对定时器参数进行配置,主要包括(1)TIM_Prescaler设置分频系数。(2)TIM_CounterMode计数方式:向上/向下/3种中央对齐模式。(3)TIM_Period设置自动重载计数周期值。(4)TIM_ClockDivision设置时钟分频因子1/2/4。
3.viod TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
输出通道初始化函数,1.选择那个定时器。2.对输出通道参数进行配置,主要包括(1)TIM_OCMode设置模式。输出比较时间模式 、 输出比较主动模式、输出比较非主动模式、输出比较翻转触发模式、PWM1 、PWM2。(2)TIM_OutputState设置输出比较使能,设置模式使能到端口。(3)TIM_OCPolarity 用来设置极性是高还是低。(4)TIM_Pulse设置输入捕获寄存器的值。
4.void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
输入捕获初始化函数,1.选择那个定时器。2.对输入捕获通道进行配置,主要包括(1)TIM_Channel通道选择,共有四种选择。(2)TIM_ICPolarity选择捕获形式,上升沿/下降沿。(3)TIM_ICSelection设置映射关系,通道之间可以互相映射。(4)TIM_ICPrescaler设置分频因子1/2/4/8。(5)TIM_ICFilter设置滤波器长度。
5.void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
定时器使能函数。
6.void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
定时器中断函数,1.选择定时器。2.选择中断形式,可在事件产生寄存器(TIMx_EGR)中查看触发形式。3.使能。
7.void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
内部时钟配置,选择内部时钟给定时器提供时钟源。
8.void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
输出通道预装载设置
9.void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
设置比较值。
10.void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)
设置计数器值
11. void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
设置输入捕获通道分频因子。
12.uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
获取捕获通道的值。
13.uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
获取计数器的值。
14.ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
获取中断标志位。
15.void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
清除中断标志位。
16.void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
计数器预装载。
四、定时器中断实验
1.采用的是默认时钟72MHz,因此倍频数为2,CK_INT也为 72MHz,计数器最终时钟的确定根据倍频因数CK_PSC的值确定。
定时器Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk,其中Tclk是默认的72MHz。
2.定时器实验配置步骤:
② 初始化定时器,配置ARR,PSC。 TIM_TimeBaseInit();
④ 使能定时器。TIM_Cmd();
⑥ 编写中断服务函数。TIMx_IRQHandler();
五、PWM输出实验
1.周期由TIMx_ARR决定,TIMx_CCRx决定占空比
2.CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。
CCMR1: OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】
CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。
PWM波形与两个寄存器有关,CCMR决定有效电平,CCER决定有效电平是高电平还是低电平
3.在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设
置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预
装载寄存器,最后还要设置TIMx_CR1寄存器的ARPE位, (在向上计数或中心对称模式中)使能
自动重装载的预装载寄存器。
自动重装载的预装载寄存器:ARPE=1,ARR立即生效;ARPE=0,ARR下个周期生效。主要是为了在计数器在自动装载值前改变了ARR的值,该值在什么时候生效。
4.PWM实验配置步骤:
①使能定时器3和相关IO口时钟。
使能定时器3时钟:RCC_APB1PeriphClockCmd();
使能GPIOB时钟:RCC_APB2PeriphClockCmd();
② 初始化IO口为复用功能输出。函数:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
③这里我们是要把PB5用作定时器的PWM输出引脚,所以要重映射配置,所以需要开启AFIO时钟。同时设置重映射。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
④ 初始化定时器:ARR,PSC等:TIM_TimeBaseInit();
⑤ 初始化输出比较参数:TIM_OC2Init();
⑥ 使能预装载寄存器: TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
⑦ 使能定时器。TIM_Cmd();
⑧ 不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare2();
六、定时器输入捕获实验
1.通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。
2.步骤分析输入通道
1.
2.
3.
3.输入捕获实验一般配置步骤
① 初始化定时器和通道对应IO的时钟。
② 初始化IO口,模式为输入:GPIO_Init();GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入
③初始化定时器ARR,PSCTIM_TimeBaseInit();
④初始化输入捕获通道TIM_ICInit();
⑤如果要开启捕获中断,TIM_ITConfig();NVIC_Init();
⑥使能定时器:TIM_Cmd();
⑦编写中断服务函数:TIMx_IRQHandler();