【STM32+HAL】微秒级延时函数汇总

一、调用Arduino中的micros函数

1、micros.c
#include "micros.h"


__STATIC_INLINE uint32_t GXT_SYSTICK_IsActiveCounterFlag(void)
{
  return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk));
}


static uint32_t getCurrentMicros(void)
{
  /* Ensure COUNTFLAG is reset by reading SysTick control and status register */
  GXT_SYSTICK_IsActiveCounterFlag();
  uint32_t m = HAL_GetTick();
  const uint32_t tms = SysTick->LOAD + 1;
  __IO uint32_t u = tms - SysTick->VAL;
  if (GXT_SYSTICK_IsActiveCounterFlag()) {
    m = HAL_GetTick();
    u = tms - SysTick->VAL;
  }
  return (m * 1000 + (u * 1000) / tms);
}


//获取系统时间,单位us
uint32_t micros(void)
{
  return getCurrentMicros();
}



//微秒级延时函数
void Delay_us(uint16_t nus)
{
    int temp = micros();
    while(micros() - temp < nus){}
}
2、micros.h
#ifndef __MICROS_H__
#define __MICROS_H__

#include "stm32f4xx_hal.h"

uint32_t micros(void);
void Delay_us(uint16_t nus);

#endif

3、测试结果

波形较不稳定,周期准确度较高

 

 

二、定时器中断延时函数

1、HAL库开启定时器

已知TIM1挂载在APB2总线上

配置参数值 

2、延时函数
/**
  * @brief  定时器延时us,Prescaler -> 168-1
  * @param  us: <= 65535
  * @retval None
  */

void Delay_us(uint16_t nus)
{
	__HAL_TIM_SetCounter(&htim1,0);
	__HAL_TIM_ENABLE(&htim1);
	while (__HAL_TIM_GET_COUNTER(&htim1) < nus)
	{
	}
	__HAL_TIM_DISABLE(&htim1);
}

3、测试结果

波形较稳定,周期稳定地偏长0.3-0.4us

 

 

 

三、纯代码1

1、Delay_us.c
__IO float usDelayBase;

void PY_usDelayTest(void)
{
  __IO uint32_t firstms, secondms;
  __IO uint32_t counter = 0;

  firstms = HAL_GetTick()+1;
  secondms = firstms+1;

  while(uwTick!=firstms) ;

  while(uwTick!=secondms) counter++;

  usDelayBase = ((float)counter)/1000;
}



void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}



void PY_usDelayOptimize(void)
{
  __IO uint32_t firstms, secondms;
  __IO float coe = 1.0;

  firstms = HAL_GetTick();
  PY_Delay_us_t(1000000) ;
  secondms = HAL_GetTick();

  coe = ((float)1000)/(secondms-firstms);
  usDelayBase = coe*usDelayBase;
}



void Delay_us(uint16_t nus)
{
  __IO uint32_t delayReg;

  __IO uint32_t msNum = nus/1000;
  __IO uint32_t usNum = (uint32_t)((nus%1000)*usDelayBase);

  if(msNum>0) HAL_Delay(msNum);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}

2、测试结果

波形较稳定,周期稳定地偏长0.3-0.4us

四、纯代码2

1、Delay_us.c
#define CPU_FREQUENCY_MHZ    168        //STM32主频

void Delay_us(__IO uint32_t delay)
{
    int last, curr, val;
    int temp;
    while (delay != 0)
    {
        temp = delay > 900 ? 900 : delay;
        last = SysTick->VAL;
        curr = last - CPU_FREQUENCY_MHZ * temp;
        if (curr >= 0){
            do{
                val = SysTick->VAL;
            }
            while ((val < last) && (val >= curr));
        }
        else{
            curr += CPU_FREQUENCY_MHZ * 1000;
            do{
                val = SysTick->VAL;
            }
            while ((val <= last) || (val > curr));
        }
        delay -= temp;
    }
}

 

 2、测试结果

波形较稳定,偏差稳定0.5us

 

上一篇:Python | Leetcode Python题解之第80题删除有序数组中的重复项II-题解:


下一篇:常见的前端框架-模型