本文用STM32F205芯片中的TIM3为例,写了两种定时器延时函数。本人所知的延时函数方式有3种,通过定时器中断方式的延时函数在本文中暂时不提及。为方便自己记忆,以下均为自己总结,如有错误,欢迎大家讨论。
TIM3挂载在APB1上,30MHz,故TIM3的始终频率为60MHz。
方法一:1. 先配置定时器的单次定时时长,定时器分频为1M,即每计一个数需要1us。
2. 写延时函数,当计数器的计数值大于给定的计数值时,停止计数。
void TIM3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3时钟
TIM_TimeBaseInitStructure.TIM_Period = 50000-1; //自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = 60-1; //定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
}
//微秒级延时
void TIM3_Delayus(u16 xus)
{
TIM_Cmd(TIM3,ENABLE); //启动定时器
while(TIM3->CNT < xus);
TIM3->CNT = 0;
TIM_Cmd(TIM3,DISABLE); //关闭定时器
}
//毫秒级延时
void TIM3_Delayms(u16 xms)
{
int i;
for(i=0;i<xms;i++)
{
TIM3_Delayus(1000);
}
}
注意:通过这个方法写的定时器延时函数,微秒级延时时长必须小于单次定时时长,即自动重装载值必须设置大一点,但也不能超过最大值。
方法二:将定时时长跟自动重装载值联系在一起,当检测SR寄存器发生计数溢出,关闭定时器。
//毫秒级延时
void TIM3_Delayms(u16 xms)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3时钟
TIM_TimeBaseInitStructure.TIM_Period = xms*10-1; //自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = 6000-1; //定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
TIM3->SR = 0;
TIM_Cmd(TIM3,ENABLE); //启动定时器
while((TIM3->SR & TIM_FLAG_Update)!=SET);
TIM_Cmd(TIM3,DISABLE); //关闭定时器
TIM3->CNT = 0;
}
注意:在使用方法二的延时时,在启动定时器前需要先将SR寄存器清空,否则会出问题。