Introduction
TIM 定时器可以用来做下面事情:
定时中断:定一个时间,让定时器每隔一个时间产生一个中断,来实现每隔一个固定时间执行一段程序。比如时钟、秒表;
输出比较:产生PWM波形来驱动电机;
输入捕获:测量方波频率;
编码器接口:方便读取正交编码器的输出波形;
定时器说明:
1、它可以对输入的时钟进行计数,并在计数值达到设定值时触发中断;
2、它有16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时;
3、它不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能;
4、根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型;
START
如何使用
仔细阅读上图
第一步 打开定时器外设时钟,之后定时器的基准时钟和整个外设的工作时钟都会同时打开;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
第二步 选择时基单元的时钟源,时钟源有内部时钟模式、外部时钟模式1、外部时钟模式2、编码器模式,这里学习定时中断就使用内部时钟模式;
TIM_InternalClockConfig(TIM2);
定时器上电后默认就是使用内部时钟,可以不调用上面函数
第三步 配置时基单元,包括预分频器、自动重装器、计数模式等,使用结构体配置即可;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//时钟分频,1分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数器模式,向上计数模式
TIM_TimeBaseInitStructure.TIM_Period=10000-1;//ARR自动重装器的值
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;//PSC预分频器的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//重复计数器的值,它是高级定时器才有。这里不需要用给0
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
说明:时钟分频,目的为了采样滤波,定时器的外部信号输入引脚一般都会有一个滤波器来滤掉信号的抖动干扰,它会在一个固定的频率f下进行采样,如果连续N个采样点都为相同的电平,那就代表输入信号稳定没有抖动,频率f来自内部时钟或者内部时钟加上时钟分频而来;选择内部时钟用不到输入滤波模块,所以随便配一下;
时间=1/定时频率;
定时频率=72Mhz/[(PSC+1)*(ARR+1)];
PSC和ARR取值范围0~65535之间 ;
定时1s就是定时频率1Hz;
第四步 配置输出中断控制,允许更新中断输出到NVIC;
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//避免初始化就进入中断问题
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能更新中断
第五步 配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级;
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//定时器2在NVIC里的通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
第六步 运行控制,使能计数器运行。
TIM_Cmd(TIM2,ENABLE);//启动定时器,当产生更新时,就会触发中断
当定时器使能后,计数器就开始计数了,当计数器更新时,触发中断,然后定时器的中断函数,这样这个中断函数每搁一段时间就能自动执行一次。
中断函数
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)//判断获取标志位是否为高电平
{
Num++;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
END
完整代码
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_InternalClockConfig(TIM2);
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_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
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);
TIM_Cmd(TIM2, ENABLE);
}
补充
主要使用的库函数说明
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
TIM_TimeBaseInit
时基单元初始化,第一个TIMx选择某个定时器,第二个结构体,包含配置时基单元一些参数;
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
TIM_TimeBaseStructInit
该函数会给时基单元结构体赋一个默认值;
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
TIM_Cmd
该函数使能计数器,参数:选择定时器,使能或失能;
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
TIM_ITConfig
该函数使能中断输出信号,对应图里中断输出控制,中间参数选择要配置哪个中断输出;
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
TIM_InternalClockConfig
用于将定时器配置为使用内部时钟,并禁用了从模式
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
TIM_ITRxExternalClockConfig
参数1选择ITRx其他定时器的时钟,参数2选择接入其他的定时器
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);
ETR
TIM_TIxExternalClockConfig
参数1选择TIx捕获通道的时钟,参数2选择TIx具体某个引脚,后面是输入极性和滤波器
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
配置为ETR外部时钟模式1
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
配置为ETR外部时钟模式2
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
根据传入的参数配置ETR引脚的预分频器极性、滤波器