STM32F4 的定时器功能一十四个,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~ TIME5 ,TIM9~TIM14 等通用定时器,还有 TIME6 和 TIME7 等基本定时器
STM32F4 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等
定时器功能:
①16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。
②4 个独立通道(TIMx_CH1~ 4,TIM9~TIM14 最多 2 个通道),这些通道可以用来作为:
a.输入捕获
b.输出比较
c.PWM 生成(边缘或中间对齐模式) ,注意:TIM9~TIM14 不支持中间对齐模式
d.单脉冲模式输出
③可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路
④如下事件发生时产生中断/DMA(TIM9~TIM14 不支持 DMA):
a.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
b.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
c.输入捕获
d.输出比较
e.支持针对定位的增量(正交)编码器和霍尔传感器电路(TIM9~TIM14 不支持)
f.触发输入作为外部时钟或者按周期的电流管理(TIM9~TIM14 不支持)
通用定时器的原理框图
定时器的计数器模式
●递增计数模式:计数器从 0 计数到自动重载值(TIMx_ARR 寄存器的内容),然后重新从 0 开始计数并生成计数器上溢事件即生成更新事件
●递减计数模式:计数器从自动重载值(TIMx_ARR 寄存器的内容)开始递减计数到 0,然后重新从自动重载值开始计数并生成计数器下溢事件
●中心对齐模式(递增/递减计数):在中心对齐模式下,计数器从 0 开始计数到自动重载值(TIMx_ARR 寄存器的内容)-1,生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从0 开始重新计数。
计数器时钟可由下列时钟源提供:
● 内部RCC提供的时钟 (CK_INT),会经过预分频PSC
● 外部时钟模式 1:外部输入引脚 (TI1FP1和TI2FP2)
● 外部时钟模式 2:外部触发输入 (ETR),仅适用于 TIM2、TIM3 和 TIM4。
● 内部触发输入 (ITR1~ITR4):使用一个定时器作为另一个定时器的预分频器
时基单元包括:
● 计数器寄存器 (TIMx_CNT) //计数方式
● 预分频器寄存器 (TIMx_PSC) //设置时钟频率1~65536
● 自动重载寄存器 (TIMx_ARR) //设置ARR寄存器的内容何时装入影子寄存器
定时器中断实现:
①使能定时器时钟
RCC_APB1PeriphClockCmd();
②初始化定时器配置ARR和PSC
TIM_TimeBaseInit(TIM_TypeDefTIMx, TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct);
③开启定时器中断,并且配置NVIC
TIM_ITConfig(TIMx,TIM_IT_xxxxx,ENABLE);
NVIC_Init();
④使能定时器
TIM_Cmd();
⑤编写中断服务函数:
TIMx_IRQHandler();
==定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us. ==
定时器PWM输出原理:
定时器工作在向上计数 PWM模式,且当 CNT《CCRx 时,输出无效电平(也可能有效电平,依模式而定),当CNT》=CCRx 时输出 有效电平(也可能无效电平,依模式而定)。
当 CNT 值小于 CCRx 的时候,IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率
CCMR1:OC1M[2:0]位:在作为PWM输出时,用于设置PWM模式1【110】或者PWM模式2【111】
CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1低电平有效
CCER:CC1E位:输入/捕获1输出使能。0:关闭,1打开
定时器PWM输出实现:
①使能定时器xx和相关IO口时钟
RCC_APB1PeriphClockCmd(); //使能定时器xx
RCC_AHB1PeriphClockCmd(); //使能IO口时钟
②初始化IO口为复用功能输出
GPIO_Init();
③GPIOx复用映射到定时器xx
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
④初始化定时器:ARR,PSC
TimeBaseInit();
⑤初始化输比较参数:
TIM_OC1Init();
⑥使能预装载寄存器:
TIM_ARRPreloadConfig(TIMx,ENABLE);
⑦使能定时器
TIM_Cmd(TIMxx,ENABLE);
⑧改变CCRx值,达到不同的占空比效果
TIM_SetCompare1();
其中要注意初始化输出比较函数时,一般只写这几个
定时器输入捕获工作过程:
通过检测TIMx_CHx上的边沿信号,再边沿信号发生跳变(上升沿/下降沿)时,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获
定时器输入捕获的配置实现:
①使能定时器和通道对应的IO口时钟
②初始化IO口,模式为复用
GPIO_Init();
③设置引脚复用映射
GPIO_PinAFConfig();
④初始化定时器ARR,PSC
TIM_TimeBaseInit();
⑤初始化输入捕获通道
TIM_ICInit();
⑥开启捕获中断,如果有设置捕获后的中断事件
TIM_ITConfig();
NVIC_Init(); //输入捕获通道初始函数
⑦使能定时器
TIM_Cmd();
⑧编写中断服务函数 //获取通道捕获值函数:TIM_GetCapture1();
TIMx_IRQHandler(); //通道极性设置独立函数:TIM_OCxPolarityConfig();
详解:~捕获高电平脉宽的思路:首先,设置 TIM5_CH1 捕获上升沿,这在TIM5_Cap_Init 函数执行的时候就设置好了,然后等待上升沿中断到来,当捕获到上升沿中断,此时如果 TIM5CH1_CAPTURE_STA 的第 6 位为 0,则表示还没有捕获到新的上升沿,就先把TIM5CH1_CAPTURE_STA、TIM5CH1_CAPTURE_VAL 和计数器值 TIM5-》CNT 等清零,然后再设置 TIM5CH1_CAPTURE_STA 的第 6 位为 1,标记捕获到高电平,最后设置为下降沿捕获,等待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出(对 32 位定时器来说,很难溢出),就在 TIM5CH1_CAPTURE_STA 里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置TIM5CH1_CAPTURE_STA 的第 7 位为 1,标记成功捕获一次高电平,然后读取此时的定时器值到 TIM5CH1_CAPTURE_VAL 里面,最后设置为上升沿捕获,回到初始状态。~
通道1输入捕获状态寄存器