STM8L1xx利用定时器实现毫秒和微妙延时

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hpr1992/article/details/50729381

    采用单片机的定时计数器进行毫秒和微妙级延时,精度较准。检测溢出时产生的标志位来判断延时到达。下面以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。               

    

展开阅读全文

没有更多推荐了,返回首页