定时器中断实现步骤
-
使能定时器时钟。 RCC_APB1PeriphClockCmd();
-
初始化定时器,配置ARR,PSC。 TIM_TimeBaseInit();
-
开启定时器中断,配置NVIC。 void TIM_ITConfig(); NVIC_Init();
-
使能定时器。 TIM_Cmd();
-
编写中断服务函数。 TIMx_IRQHandler();
定时器3初始化函数及中断服务函数(含上述步骤1-5)void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//使能APB1时钟 对应步骤1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//初始化定时器 对应步骤2
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//开启定时器中断并设置中断优先级等 对应步骤3
TIM_ITConfig(TIM3, TIM_IT_Update ,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//使能定时器 对应步骤4
TIM_Cmd(TIM3, ENABLE);
}
void TIM3_IRQHandler(void)
{
//获取定时器3的状态值(判断是否为更新中断)
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
//清除定时器3的中断标志
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
LED1=!LED1; //翻转LED灯1
}
}
int main(void) //效果展示主函数
{
delay_init(); //延时初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //初始化中断优先级分组
LED_Init(); //初始化LED
TIM3_Int_Init(4999,7199); //初始化定时器3
while(1) { LED0=!LED0; delay_ms(200);} //使LED0与LED1展示对比效果
}
注:LED函数参见正点原子程序源码 “位操作跑马灯”
定时器的参数计算
上图为系统时钟框图,由此可知APB1的预分频系数可以有1、2、4、8、16共五种选择,而其下挂的定时器时钟在APB预分频系数为1时乘1,否则乘2,即APB1时钟为36MHz(systemInit系统初始化函数中默认的)或者72MHz时,TIM2,3,4的时钟为72MHz,APB1时钟为其他频率时,TIM2,3,4的时钟频率为APB1时钟频率的2倍。
定时器溢出时间的计算:
Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk
Tclk = APB1时钟倍频后的频率(72000000)
PSC = TIMx的预分频系数(默认设置为72000-1比较好计算,但正点原子实验设置为7200-1)
ARR = TIMx的重装载值
(PSC+1)/Tclk计算的结果为定时器寄存器的当前值更新一次的时间(计数周期),ARR+1即为要计数的次数,最后可以得出定时的时间。
可以将上述函数的参数传递进行如下更改(仅含有修改的部分):
void TIM3_Int_Init(u16 arr) //输出参数为要定时的毫秒数
{
TIM_TimeBaseStructure.TIM_Period = arr-1;
TIM_TimeBaseStructure.TIM_Prescaler =71999;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
}
TIM3_Int_Init(500);
文中函数和部分内容摘自正点原子stm32资料与官方库函数
自学新手,个人总结,如有出入,请多指教!