你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

质疑HAL库的延时函数HAL_Delay  

[复制链接]
与龙共舞 提问时间:2018-4-20 08:55 /
是这样的,M3内核的滴答定时器一般用来做系统的时基,最频繁的变现就是延时函数了HAL_Delay。看一下延时函数的实现:
__weak void HAL_Delay(__IO uint32_t Delay)
{
  uint32_t tickstart = 0;
  tickstart = HAL_GetTick();
  while((HAL_GetTick() - tickstart) < Delay)
  {
  }
}


1.png

是一个空空死循环,只要HAL_GetTick() - tickstart 值没有大于你设置的Delay数值。
在看一下
__weak void HAL_IncTick(void)
{
  uwTick++;
}

__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}


其实这个HAL_GetTick()是一个全局变量。
static __IO uint32_t uwTick;
【预计上电以后默认是初始化为0的】

那么我的问题是:
比如我调用HAL_Delay(100),
此时uwTick是120,那么uwTick会随着时间脉冲++,
等uwTick到220的时候我的延时就从死循环出来了。
而如果【u32比较大 我就暂时当做u8吧 那就是255了】
我调用HAL_Delay(100),
此时uwTick是220,那么uwTick会随着时间脉冲++,理论到320的时候解除死循环,
而在255的时候,我擦,u8到了尽头了,会变到0!怎么办?


我想了一下 如果这样的话在255->0的时候回出现0-220的计算这个时候系统怎么处理呢?会直接解除死循环吗?
《我说的这种概率情况》
同时想起来刚刚做的笔试题目,是不是也是这个问题呢?
QQ截图20180420084329.png
收藏 2 评论25 发布时间:2018-4-20 08:55

举报

25个回答
XinLiYF 回答时间:2018-4-20 20:13:33
无符号的回环问题:(uint8_t)(0x00) - (uint8_t)(0xFF) = (uint8_t)(0x01)

这个是一个很好的例子:模仿kfifo实现的环形缓冲区

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

黑皮男 回答时间:2018-4-20 18:14:49
与龙共舞 发表于 2018-4-20 16:29
所以你的这思路就是把U32提升到U64 再次降低出现溢出的可能吗?

不是,是无符号数和有符号数的问题。http://www.cnblogs.com/hfyinsdu/p/4600052.html

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

toofree 回答时间:2018-4-20 09:13:49
本帖最后由 toofree 于 2018-4-20 09:15 编辑

HAL_Delay()函数的参数类型是uint32_t,即无符号32位int型。
如果超过32位的最大数(4亿多4294967296)的话,的确会有问题。那么延时会多长了呢,以标准的HAL_Delay()单位1ms计算,4294967296ms,4294967秒,1193小时。只能是人为判断,参数不要超过32位uint32_t。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

freeelectron 回答时间:2018-4-20 09:09:17
1、楼主说的这种情况的确有的,但是你要考虑实际,谁会延迟u32 那么大的时间啊
2、一般这种有死循环多的,还是尽量开看门狗

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

wenyangzeng 回答时间:2018-4-20 09:46:13
uwTick是32位变量。不会出现楼主说的情况。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

wudianjun2001 回答时间:2018-4-20 09:50:25
32位的一般不会出现长时间的延时的

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

与龙共舞 回答时间:2018-4-20 10:15:33
toofree 发表于 2018-4-20 09:13
HAL_Delay()函数的参数类型是uint32_t,即无符号32位int型。
如果超过32位的最大数(4亿多4294967296)的话 ...

哦 我传参是100 肯定OK  
我说的是(猜测) 比如此时ucTick数值就是4294967290 那会发生什么事呢?它++100会回到0
jjbboox 回答时间:2018-4-20 10:20:11
有什么好担心的,u32你知道需要等多少年吗?
time_t都没用完32位。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

dsjsjf 回答时间:2018-4-20 10:22:42
按照楼主所说,此时uwTick是220,那么uwTick会随着时间脉冲++,理论到320的时候解除死循环,
而在255的时候,我擦,u8到了尽头了,会变到0!实际上会加到64。再看死循环while((HAL_GetTick() - tickstart) < Delay)里,此时HAL_GetTick()为64,tickstart为220,因为都是无符号数,因而64-220=100 即可退出循环。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

anobodykey 回答时间:2018-4-20 10:23:10
楼主可以多分析一下,建议你看下该链接https://www.stmcu.org.cn/module/forum/thread-608277-1-1.html,同样是讨论Hal_Delay的溢出问题,其实你就会发现ST把uwTick设计成为32位无符号型是有意义的,至于你说的把它改成u8类型其实适用于8位单片机系统,但stm32是32位的单片机系统,所以溢出问题不影响你的延时

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

wolfgang2015 回答时间:2018-4-20 10:49:21
HAL代码只是一个事例,具体情况具体分析,U32的循环完了,判断FF后又从0开始计数,或者直接忽略掉此处的溢出中断。循环往复了~~

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

123下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版