定时器TIM
1 定时器基础知识
1.STM32F10X系列总共最多有八个定时器:
2.三种STM32定时器的区别:
3.STM32 的通用定时器功能:
- 16 位/32 位(仅 TIM2 和 TIM5)向上、向下、向上/向下自动装载计数器 (TIMx_CNT),注意:TIM9~TIM14 只支持向上(递增)计数方式
- 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~ 65535 之间的任意数值
- 4 个独立通道(TIMx_CH1~4,TIM9~TIM14 最多 2 个通道),这些通道可以用来作 为:
输入捕获
输出比较
PWM 生成(边缘或中间对齐模式) ,注意:TIM9~TIM14 不支持中间对齐模式
单脉冲模式输出
- 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外 一个定时器)的同步电路。
- 如下事件发生时产生中断/DMA(TIM9~TIM14 不支持 DMA):
更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
输入捕获
输出比较
支持针对定位的增量(正交)编码器和霍尔传感器电路(TIM9~TIM14 不支持)
触发输入作为外部时钟或者按周期的电流管理(TIM9~TIM14 不支持) 的
4.计数器模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式
向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且 产生一个计数器溢出事件
向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装 入的值重新开始,并产生一个计数器向下溢出事件
中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个 计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重 新计数
2 基本定时器
1.基本定时器的结构框图
1. 时钟源
2. 控制器
3. 时基单元
时钟源
时钟源来自RCC的TIMx_CLK(属于内部的CK_INIT)
控制器
控制器用于控制定时器:复位、使能、计数、触发ADC
涉及到的寄存器:CR1/2,DIER,EGR,SR
时基(定时器的心脏)
定时器最重要的就是时基部分:包括预分频器、计数器、自动重装载寄存器
预分频器:1-16位预分频器PSC对内部时钟CK_PSC进行分频之后,得到计数器时 钟CK_INT=CK_PSC/(PSC+1)
CNT在计数器时钟的驱动下开始计数,计数一次的时间为1/CK_INT
计数器、重装在寄存器:定时器使能(CEN置1)后,计数器CNT在CK_CNT驱动 下计数,当TNT值与ARR的设定值相等时就自动生成事件并CNT自动清零,然后 自动重新开始计数,如此重复以上过程。
影子寄存器
1.PSC和ARR都有影子寄存器,功能框图上有个影子
2.影子寄存器的存在起到一个缓冲的作用,用户值->寄存器->影子寄存器->起作用, 如果不使用影子寄存器则用户值在写到寄存器之后则里面起作用,ARR影子, TIMx_CR1:APRE位控制。
2.定时时间的计算
PSC=72-1,定时器的频率 = 72M/(PSC+1) = 1MHZ
ARR = 1000 -1,从0计数到999,则计了1000次
中断周期T = 1000 * 1 /1 000 000 = 1ms (ARR+1)*(PSC+1)/72M
如何实现500ms的定时?
PSC不变,ARR=500 000
T=500 000*1/1 000 000=500ms
PSC扩大一倍,PSC=144-1
定时器的频率 F =72M/(PSC+1)=500KHz
T=(ARR+1)*(PSC+1)/72M
ARR=250 000 -1
3 定时器控制LED
库函数定时器控制LED灯
常用函数
时基初始化结构体:
typedef struct
{
uint16_t TIM_Prescaler;
uint16_t TIM_CounterMode;
uint16_t TIM_Period;
//分频因子
//计数模式,基本定时器只能向上计数
//自动重装载值
uint16_t TIM_ClockDivision;
uint8_t TIM_RepetitionCounter; //重复计数值,基本定时器没有,高级定时器
专用
} TIM_TimeBaseInitTypeDef;
常用的库函数:
//外部输入时钟分频因子,基本定时器没有
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef*
TIM_TimeBaseInitStruct);
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef*
TIM_TimeBaseInitStruct);
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState
NewState);
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler,
uint16_t TIM_PSCReloadMode);
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState
NewState);
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
软件流程设计
- 初始化系统
初始化定时器和LED的IO时钟
初始化LED的引脚IO
- 定时器中断中驱动LED灯