STM32F407VET6 基於滴答定時器實現精確延時功能


  在這個實驗中,我們基於滴答定時器實現精確延時功能,當然想要實現精確的延時功能也不一定非得使用滴答定時器,使用其它定時器一樣可以實現,其實現的原理是一樣的。這里我們雖然借用了滴答定時器,但是不占用滴答定時器的中斷,只是不斷的去讀取滴答定時器的寄存器,從而實現延時功能。如果想要在項目中移植實時操作系統,下面的延時功能代碼也無需做什么改變,同時也不會對系統內核產生影響(注:這里的不會影響是基於大部分系統的時鍾節拍為1ms)。

代碼如下:

#include "stm32f4xx.h"
#include "delay.h"
 
/********************************************************
 * 函數功能:初始化滴答定時器
 * 形    參:無
 * 返 回 值:無
 ********************************************************/
void systick_init(void)
{
   // Reload為24位寄存器,最大值:16777216,在168M下,約合0.0998s左右
   SysTick->LOAD = SystemCoreClock / 1000UL; // 配置中斷時間為1ms
   SysTick->CTRL |= SysTick_CLKSource_HCLK; // 內部時鍾配置為168MHz
   SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 開啟SYSTICK
   SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // 開啟SYSTICK中斷
}

/********************************************************
 * 函數功能:使用滴答定時器做的微秒級延時函數(強阻塞)
 * 形    參:nus:延時時間,單位:微秒
 * 返 回 值:無
 ********************************************************/
void delay_us(unsigned short nus)
{
   unsigned int wait_time = 0UL;
   unsigned int check_time = 0UL;
   unsigned int start_time = SysTick->VAL; // 計數器值
   unsigned int total_time = (SystemCoreClock / 1000000UL) * nus;
   // 注:SysTick是一個遞減的計數器
   while(wait_time < total_time)
   {
      start_time = check_time;
      check_time = SysTick->VAL;
  
      if(check_time < start_time)
      {
         wait_time += start_time - check_time;
      }
      else if(check_time > start_time)
      {
         wait_time += SysTick->LOAD - check_time + start_time;
      }
   }
}

/********************************************************
 * 函數功能:使用滴答定時器做的毫秒級延時函數(強阻塞)
 * 形    參:nms:延時時間,單位:毫秒
 * 返 回 值:無
 ********************************************************/
void delay_ms(unsigned short nms)
{
   delay_us((unsigned int)(nms * 1000UL));
}
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM