采用单片机的定时计数器进行毫秒和微妙级延时,精度较准。检测溢出时产生的标志位来判断延时到达。下面以STM8L101芯片为例及配合代码说明。
一、实现原理:
1、初始化Timer2时钟源(附上相应代码)
void TIM2Init (void)
{
TIM2_DeInit ();
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
TIM2->CR1 &= ((uint8_t)(~TIM_CR1_CMS)) & ((uint8_t)(~TIM_CR1_DIR));
TIM2->CR1 |= ( (TIM2_CounterMode_Up) | (TIM_CR1_ARPE) ); /*counter up, enable Auto-Reload*/
TIM2_SetCounter(0x00);
TIM2->IER &= (~TIM2_IT_Update); /*disable timer2 interrupt*/
TIM2->CR1 &= (~TIM_CR1_CEN); /*disable timer2*/
}
打开外设时钟源;
选择向上计数模式和打开自动重加载功能;
填装计数器的初始值;
关闭Timer2中断功能;
关闭Timer2;
2、毫秒延时代码示例
void DelayMs (uint16_t timeVal)
{
uint16_t i = 0;
TIM2_TimeBaseInit(TIM2_Prescaler_64, TIM2_CounterMode_Up, 124); /*AutoReload Value = 124, 1ms*/
TIM2->CNTRH = (uint8_t)0; /*counter value = 0*/
TIM2->CNTRL = (uint8_t)0;
TIM2->CR1 |= (TIM_CR1_CEN); /*enable timner2*/
for(i = 0; i < timeVal; i++)
{
TIM2->SR1 &= (~TIM2_FLAG_Update); /*clear timer2 update flag*/
while( ((TIM2->SR1) & TIM2_FLAG_Update) != TIM2_FLAG_Update ); /**/
}
TIM2->CR1 &= (~TIM_CR1_CEN); /*disable timer2*/
}
设置Timer2分频,向上加1计数模式,填装自动重载寄存器目标值。这里每经过8us计数器加1,从0一直到124,共延时1ms,这时Timer2产生溢出标志位。通过检查寄存器TIM2->SR1的位[0]判断。
for(i = 0; i < timeVal; i++)
{
TIM2->SR1 &= (~TIM2_FLAG_Update); /*clear timer2 update flag*/
while( ((TIM2->SR1) & TIM2_FLAG_Update) != TIM2_FLAG_Update ); /**/
}
先软件清除TIM2->SR1位[0],再等待判断TIM2->SR1位[0]。这里加上for循环,表示延时多少毫秒。
关闭Timer2。
3、微妙延时代码示例
void DelayUs (uint16_t timeVal)
{
TIM2->PSCR = (uint8_t)(TIM2_Prescaler_8);
TIM2->CR1 |= (uint8_t)(TIM2_CounterMode_Up);
TIM2->EGR = TIM2_EventSource_Update;
TIM2->CNTRH = (uint8_t)0;
TIM2->CNTRL = (uint8_t)0;
TIM2->ARRH = (uint8_t)0xff;
TIM2->ARRL = (uint8_t)0xff;
TIM2->SR1 &= (~TIM2_FLAG_Update); /*clear timer update flag*/
TIM2->CR1 |= (TIM_CR1_CEN); /*enable timner*/
while(1)
{
if( (TIM2->CNTRH == (uint8_t)((timeVal - 1) >> 8)) &&
(TIM2->CNTRL == ((uint8_t)(timeVal - 1) & 0x00ff)) )
{
break;
}
}
TIM2->CR1 &= (~TIM_CR1_CEN); /*disable timer*/
}
设置Timer2分频系数,向上加1计数模式,计数器初始值和自动重装载目标值。这里计数器每经过1us自动做加1计数。
清除溢出标志位,并打开Timer2;
while(1)
{
if( (TIM2->CNTRH == (uint8_t)((timeVal - 1) >> 8)) &&
(TIM2->CNTRL == ((uint8_t)(timeVal - 1) & 0x00ff)) )
{
break;
}
}
这里不是检测溢出标志位,而是检测计数器当前的计数值。比较是否等于预定设置值。
关闭Timer2。
上一篇:STM8的TIM1定时器简单使用
下一篇:STM8L之timer2产生PWM - CSDN博客
推荐阅读最新更新时间:2024-03-16 16:10