TIM(Timer)定时器: 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 ,16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
定时器功能:定时中断功能,内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
定时器分类:根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
定时器框图:
UI为更新中断,U为更新事件,更新中断通向NVIC,更新事件通向内核外其他外设
基本定时器只能向上计数,通用和高级定时器可向上向下及对应计数
影子寄存器:保证更新事件与值同步变化
定时器中断基本结构:
溢出频率计算:频率=CK_SPC/(PSC+1)/(ARR+1)
其中 PSC为预分频器预分频值,ARR为自动重装寄存器溢出值
定时器中断配置过程:
RCC(开启外设时钟)→时钟源选择→配置时基单元(计数器 预分频器 自动重装寄存器)→中断控制→NVIC→运行控制
相关函数:
TIM_TimeBaseInit 时基单元初始化
TIM_Cmd 使能计数器(运行控制)
TIM_ITConfing 使能中断控制
TIM_InterClockConfing 时钟选择为内部时钟
TIM_ITRXExternalConfing 时钟选择为其他定时器
TIM_TIXExternalClockConfing 时钟选择为TIX时钟捕获通道
TIM_ETRClockMode1Confing 时钟选择为ETR外部时钟模式1
TIM_ETRClockMode2Confing 时钟选择为ETR外部时钟模式2
TIM_ETRConfing 配置ETR引脚预分频器等参数
TIM_GetITStatus 判断是否中断
TIM_ClearITPendingBit 清除中断标志位
单独修改参数:
TIM_PrescalerConfing 单独写预分频器
TIM_CounterModeConfing 计数器模式修改
TIM_ARRreloadConfing 是否预装
TIM_SetCounter 计数器写值
TIM_SetAutoreload 写自动重装值
TIM_GetCounter 读计数器值
TIM_GetPrescaler 读预分频器值
内部时钟模式:
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_InternalClockConfig(TIM3); //内部时钟(默认,也可以不用)
TIM_TimeBaseInitTypeDef TIM_TimerBaseInitStruct;
TIM_TimerBaseInitStruct.TIM_ClockDivision=0; //滤波采样频率
TIM_TimerBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimerBaseInitStruct.TIM_Period=10000-1; //自动重装周期,ARR
TIM_TimerBaseInitStruct.TIM_Prescaler=7200-1; //预分频器,PSC
TIM_TimerBaseInitStruct.TIM_RepetitionCounter=0; //高级定时器才有
TIM_TimeBaseInit(TIM3,&TIM_TimerBaseInitStruct);
TIM_ClearFlag(TIM3,TIM_FLAG_Update); //清楚更新标志位,防止一来就自动产生自动更新
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3,ENABLE);
}
ETR时钟模式:
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
TIM_TimeBaseInitTypeDef TIM_TimerBaseInitStruct;
TIM_TimerBaseInitStruct.TIM_ClockDivision=0; //滤波采样频率
TIM_TimerBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimerBaseInitStruct.TIM_Period=10-1; //自动重装周期,ARR
TIM_TimerBaseInitStruct.TIM_Prescaler=1-1; //预分频器,PSC
TIM_TimerBaseInitStruct.TIM_RepetitionCounter=0; //高级定时器才有
TIM_TimeBaseInit(TIM3,&TIM_TimerBaseInitStruct);
TIM_ClearFlag(TIM3,TIM_FLAG_Update); //清楚更新标志位,防止一来就自动产生自动更新
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3,ENABLE);
}
中断函数:
void TIM3_IRQHandler()
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}