STM32用定时器精确延时的方法(非SysTick)
2016-10-18 来源:eefocus
系统基础频率是8MHz*4=32MHz。
先配置定时器:
TIM_TimeBaseInitTypeDef timInitStruct;
timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 定时器基准频率32MHz
timInitStruct.TIM_Prescaler = 32000; // 计数频率为1KHz
timInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
timInitStruct.TIM_RepetitionCounter = 0;
timInitStruct.TIM_Period = 0; // 这个值实际上就是TIMX->ARR,延时开始时重新设定即可
TIM_TimeBaseInit(TIM2, &timInitStruct);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 计数溢出时触发中断
TIM_Cmd(TIM2, DISABLE);
把定时器的计数频率定为1KHz,这样每1ms计数一次,可以做1ms为基准的延时。
定义延时函数:
u8 _delayTimeOut;
void delay1ms(u16 delayTime)
{
_delayTimeOut = 0;
TIM2->ARR = delayTime;
TIM_Cmd(TIM2, ENABLE);
while(!_delayTimeOut)
{
}
TIM_Cmd(TIM2, DISABLE);
}
定义计数溢出时的中断函数:
extern u8 _delayTimeOut;
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
_delayTimeOut = 1;
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
}
}
原来的一个思路是配置定时器每1ms就中断一次(TIMX->ARR值固定),在延时前将全局的延时计数器清零(该值在中断中不断累加),然后比较计数器值与欲延时的值,超过了就停止,就像这样:
void delay1ms(u16 delayTime)
{
_delayTimer = 0; // 延时计数器
TIM_Cmd(TIM2, ENABLE);
while(_delayTimer < delayTime)
{}
TIM_Cmd(TIM2, DISABLE);
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
_delayTimer++;
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
}
}