嵌入式开发--STM32延时函数重构

在做嵌入式开发的时候,经常需要用到延时函数,STM32为我们提供了一个标准的毫秒级延时函数:HAL_Delay()。这个函数用起来很方便,括号内的数就是延时的毫秒数。

但是程序中如果需要用到看门狗的话呢,这玩意需要经常喂的,否则一旦超时就会复位。

所以很容易想到,在延时函数中增加喂狗的代码,如下:

c 复制代码
void delay_ms(u32 time)
{
  u32 i;
  for(i=0; i<time; i++)
  {
	  HAL_Delay(1);
      HAL_IWDG_Refresh(&hiwdg);
  }
}

这样当然可以运行,但是不完美,比如在程序调试的时候,我们经常需要关闭看门狗,还有就是这样一来延时会很不准确,特别是系统频繁要进中断的话,实际延时会比预期长不少。

我相信很多人都没有看过这个HAL_Delay()函数实现的代码。具体如下:

c 复制代码
__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;

  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }

  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

最前面的__weak表明它是一个弱函数,也就是说我们可以自己编程来实现它,把喂狗的功能集成到这个函数内,从外部看,仍然用的是HAL_Delay()这个函数名,代码风格可以和HAL库保持一致。

实现也很简单,自己建一个延时函数LL_delay.c,如下:

c 复制代码
void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;

  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }

  while ((HAL_GetTick() - tickstart) < wait)
  {
    HAL_IWDG_Refresh(&hiwdg);   //自己添加的喂狗函数
  }
}

就是在最后的while循环中增加一行喂狗的代码,再相应添加LL_delay.h,如下:

c 复制代码
#ifndef _LL_DELAY_H_
#define _LL_DELAY_H_

void HAL_Delay(uint32_t Delay);

这样就几乎不用再操心喂狗的事了

相关推荐
yutian06061 小时前
Keil MDK下载程序后MCU自动重启设置
单片机·嵌入式硬件·keil
析木不会编程4 小时前
【小白51单片机专用教程】protues仿真独立按键控制LED
单片机·嵌入式硬件·51单片机
枯无穷肉8 小时前
stm32制作CAN适配器4--WinUsb的使用
stm32·单片机·嵌入式硬件
不过四级不改名6778 小时前
基于HAL库的stm32的can收发实验
stm32·单片机·嵌入式硬件
嵌入式科普9 小时前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长
嵌入式大圣9 小时前
单片机UDP数据透传
单片机·嵌入式硬件·udp
云山工作室9 小时前
基于单片机的视力保护及身姿矫正器设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
嵌入式-老费9 小时前
基于海思soc的智能产品开发(mcu读保护的设置)
单片机·嵌入式硬件
qq_3975623111 小时前
MPU6050 , 设置内部低通滤波器,对于输出数据的影响。(简单实验)
单片机
liyinuo201711 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范