HAL_Delay(1000)是延时1秒吗
码虫 2024-11-22

我们在使用STM32F系列芯片编写程序中,经常会使用HAL库开发,它把所有我们关心的硬件都封装成了API,调调API就可以,使用方便。

比如HAL_Delay,经常用来延时一段时间。

HAL_Delay有几个注意事项,不知道你平时开发中有没有注意到。

HAL_Delay(1000)是延时1秒吗

假设我们配置的tick为1ms,那么HAL_Delay(1000)是延时1000ms吗?

其实不是延时1000ms。

实际延时是1001ms。

我们看下代码

typedef enum{ HAL_TICK_FREQ_10HZ         = 100U, HAL_TICK_FREQ_100HZ        = 10U, HAL_TICK_FREQ_1KHZ         = 1U, HAL_TICK_FREQ_DEFAULT      = HAL_TICK_FREQ_1KHZ} HAL_TickFreqTypeDef; HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ #define HAL_MAX_DELAY      0xFFFFFFFFU __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) { }}

注意第21行,wait =Delay+uwTickFreq

这个条件绝大多数情况下是成立的,也就是这里多加了一个1。

因此我们传入1000,实际延时是1001。

HAL_GetTick() - tickstart) < wait会溢出吗

不会

它执行的是差模运算

假设 tickstart 是 0xFFFFFF00,然后系统继续运行了一段时间,HAL_GetTick() 达到 0x00000050,此时它发生了溢出,变为 0x00000050。

此时差值应该是:

0xFFFFFFFF-0xFFFFFF00+0x00000050+1=0x150

差模运算也是0x150:

0x00000050-0xFFFFFF00=0x150



可以在中断中调用HAL_GetTick吗

HAL_GetTick()是一种阻塞式延时,不建议在其他中断函数中使用。

中断处理一般都是要求快进快出,不能阻塞太久,这是原因之一。

HAL_GetTick()使用的systick中断通常是优先级最低的一类中断,一般是给RTOS调度做时基使用的。

如果在其他中断服务函数中调用这个函数的话,就会导致中断函数一直在等待Delay中的死循环结束。

但是由于Delay的优先级不够,因此出现了一种高优先级任务等待低优先级任务的情况。这种现象被称作优先级翻转。这是原因之二。

如果实在需要调用,建议用其他硬件timer作为定时器的时基,并提高其中断优先级


好了,今天的笔记就分享到这,谢谢大家!


声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • C语言
  • 编程
  • 软件开发
  • 程序
下载排行榜
更多
评测报告
更多
广告