STM32CUBEMX系列教程之HAL库方式的微秒延时函数
宣传一下 ^_^
博主做的脱机烧录器:重磅来袭!CMSIS-DAP 脱机烧录器 EasyFlasher 发布~
某宝店铺:觉皇工作室
点此链接:https://item.taobao.com/item.htm?abbucket=18&id=841061310319
实物图,MINI版:
实物图,COOL版:
标准库一般是使用系统嘀嗒定时器来进行微妙级别的延时,而HAL库将SysTick定时器用做了库函数的超时定时器,使用的地方非常多,自己修改代码使用嘀嗒定时器的话就会引起错乱。所以此时就需要自己实现一个微秒级别延时函数。
方式一:系统滴答定时器
优点:全系列通用,只需要将宏定义CPU_FREQUENCY_MHZ
根据时钟主频修改即可。
缺点:系统滴答定时器是HAL库初始化的,且必须有HAL库初始化。
#define CPU_FREQUENCY_MHZ 72 // 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;
}
}
方式二:简单延时
优点: 实现简单,如果是F1系列,HAL_RCC_GetHCLKFreq()获取的值是72000000,此方式经过测试还是比较准的,如果不考虑通用性,F1系列建议使用此种方式。
缺点: 只适用F1系列72M主频。
void delay_us(uint32_t us)
{
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
while (delay--)
{
;
}
}
方式三:普通定时器
优点: STM32全系列通用
缺点: 占用一个定时器
该方法的思路是将定时器设置为1MHZ的计数频率,定时器计一个数就是1us,实现如下:
【F1系列】
#define DLY_TIM_Handle (&htim4)
void delay_us(uint16_t nus)
{
__HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);
__HAL_TIM_ENABLE(DLY_TIM_Handle);
while (__HAL_TIM_GET_COUNTER(DLY_TIM_Handle) < nus)
{
}
__HAL_TIM_DISABLE(DLY_TIM_Handle);
}
【F4系列】
#define DLY_TIM_Handle (&htim7)
void delay_us(uint16_t nus)
{
__HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);
__HAL_TIM_ENABLE(DLY_TIM_Handle);
while (__HAL_TIM_GET_COUNTER(DLY_TIM_Handle) < nus)
{
}
__HAL_TIM_DISABLE(DLY_TIM_Handle);
}