【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

五、HAL库延时函数

1、Delay_us.c
#define CPU_FREQUENCY_MHZ 168				/* CPU主频,根据实际进行修改 */


/**
 * 此延时函数代码适用于HAL库
 */
void delay_us(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;
    }
}

测试结果与方式一相似

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值