单片机
返回首页

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

2018-07-24 来源:eefocus

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


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • 如何构建一个触摸传感器电路

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章