定时器的原理在上篇博客有讲解,这里就不重复叙述了。
通用定时器
通用定时器主要用到下面几个寄存器:
计数器当前值寄存器CNT // 计数器的当前值
预分频寄存器TIMx_PSC
自动重装载寄存器TIMx_ARR
控制寄存器1 TIMx_CR1 // 位4 DIR(计数器计数方向)位0 使能计数器
DMA中断使能寄存器 TIMx_DIER // 位0 使能中断
通用定时器中断实现步骤:
1.使能定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMx,ENABLE); //使能TIMx时钟
2.初始化定时器,配置ARR,PSC
void TIM_TimeBaseInit(TIM_TypeDef* TIMx , TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
//第一个参数为使用的定时器,第二个参数为配置结构体的地址
结构体成员
typedef struct{
uint32_t TIM_Period; //定时器周期
uint16_t TIM_Prescaler; //定时器预分频器
uint16_t TIM_CounterMode; //计数模式
uint16_t TIM_ClockDivision; //时钟分频
}TIMx_TimeBaseInitTypeDef;
3.开启定时器中断,配置NVIC
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
TIM_IT这里如果是我们常用的定时器中断,用TIM_IT_Update较多,之后可能会用到TIM_IT_CCx(TIM捕获/比较x中断源)、TIM_IT_Trigger(TIM触发中断源)等。
NewState为ENABLE(使能)或DISABLE(失能)。
配置NVIC步骤和之前很相似,就不再写了。
4.使能定时器
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); //NewState为ENABLE
5.编写中断服务函数
void TIMx_IRQHandler(void){
if(TIM_GetITStatus(TIM4,TIM_IT_Update)){
//添加处理事件
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志
}
通用定时器程序示例
void TIM4_Init(u16 pre,u16 psc){
TIM_TimeBaseInitTypeDef TIM_InitStructure; //定时器配置结构体
NVIC_InitTypeDef NVIC_InitStructure; //中断优先级配置结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //使能TIM4的时钟
TIM_InitStructure.TIM_Period = arr;
TIM_InitStructure.TIM_Prescaler = psc;