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

2024-05-10 16:36

本文主要是介绍【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

 

这篇关于【STM32+HAL】微秒级延时函数汇总的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/976974

相关文章

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

Java 枚举的常用技巧汇总

《Java枚举的常用技巧汇总》在Java中,枚举类型是一种特殊的数据类型,允许定义一组固定的常量,默认情况下,toString方法返回枚举常量的名称,本文提供了一个完整的代码示例,展示了如何在Jav... 目录一、枚举的基本概念1. 什么是枚举?2. 基本枚举示例3. 枚举的优势二、枚举的高级用法1. 枚举

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系