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));
}
 

 

posted @ 2020-05-21 11:12  一梦一人生  阅读(1758)  评论(0编辑  收藏  举报