STM8L1xx利用定時器實現毫秒和微妙延時

    採用單片機的定時計數器進行毫秒和微妙級延時,精度較準。檢測溢出時產生的標誌位來判斷延時到達。下面以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。               

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章