最近用到了定时器的定时功能,了解了下,stm32的定时器功能很强大,东西也挺多的,datasheet里也说了一大段,这个我就不详说了,这儿只说明下如何配置最简单的定时功能配置。
环境说明:MCU:stm32F4系列,用的是通用定时器TIM3
首先要知道的是TIM3 是挂载到APB1总线上的,这点详见STM32F417xx_datasheet-P.19,有个框图叫Device overview,算了,还是截个图
而APB1 的时钟是多少呢?这个得看你自己配置的多少了,一般是在SetSysClock()
函数里,我这儿是系统时钟的4分频,系统时钟这儿为168MHz,所以APB1上的时钟为42MHz,这儿不要以为TIM3的时钟就是42MHz了,因为APB1到TIM3还要经过一个倍频器,这个倍频器只有当前面系统时钟到APB1的分频系数不为1时才起作用,而我们前面说了APB1是系统时钟4分频得到的,故这儿倍频器生效,所以TIM3的时钟为APB1的倍频,即84MHz。
ok,得到了定时器的输入时钟,我们配置定时器的简单功能其实就只需要两个参数:预分频数和自动重载值
Tout = ((arr+1)*(psc+1))/Tclk;
其中arr就是自动重装值,psc为预分频值,Tclk就是定时器的时钟。
比如我想要1s钟的定时器,就可以设定:arr =9999;psc=8399;
这儿要注意下arr和psc的取值范围,前者是u32 的,后者是u16的。
NVIC_InitTypeDef NVIC_InitStructure;
// TIM3 clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// Enable the TIM3 gloabal Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//向上计数模式,就是从0计数到arr,计数到arr时,产生一个TIM_IT_Update中断,还有其他中断可选
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* TIM Interrupts enable */
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
这样定时器就开始工作了,然后再写上中断处理函数,
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
//your code
}
}
至此,TIM3的定时功能就完成了,由psc和arr值,我们可以设定想要的定时时间。
当然,这只是定时的一个很简单的功能,还有很多酷炫的东西,如有错误,还请指正!