质疑HAL库的延时函数HAL_Delay
是这样的,M3内核的滴答定时器一般用来做系统的时基,最频繁的变现就是延时函数了HAL_Delay。看一下延时函数的实现:__weak void HAL_Delay(__IO uint32_t Delay)
{
uint32_t tickstart = 0;
tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{
}
}
是一个空空死循环,只要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的计算这个时候系统怎么处理呢?会直接解除死循环吗?
《我说的这种概率情况》
同时想起来刚刚做的笔试题目,是不是也是这个问题呢?
无符号的回环问题:(uint8_t)(0x00) - (uint8_t)(0xFF) = (uint8_t)(0x01)
这个是一个很好的例子:模仿kfifo实现的环形缓冲区 与龙共舞 发表于 2018-4-20 16:29
所以你的这思路就是把U32提升到U64 再次降低出现溢出的可能吗?
不是,是无符号数和有符号数的问题。http://www.cnblogs.com/hfyinsdu/p/4600052.html 本帖最后由 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、楼主说的这种情况的确有的,但是你要考虑实际,谁会延迟u32 那么大的时间啊
2、一般这种有死循环多的,还是尽量开看门狗 uwTick是32位变量。不会出现楼主说的情况。 32位的一般不会出现长时间的延时的 toofree 发表于 2018-4-20 09:13
HAL_Delay()函数的参数类型是uint32_t,即无符号32位int型。
如果超过32位的最大数(4亿多4294967296)的话 ...
哦 我传参是100 肯定OK
我说的是(猜测) 比如此时ucTick数值就是4294967290 那会发生什么事呢?它++100会回到0 有什么好担心的,u32你知道需要等多少年吗?
time_t都没用完32位。 按照楼主所说,此时uwTick是220,那么uwTick会随着时间脉冲++,理论到320的时候解除死循环,
而在255的时候,我擦,u8到了尽头了,会变到0!实际上会加到64。再看死循环while((HAL_GetTick() - tickstart) < Delay)里,此时HAL_GetTick()为64,tickstart为220,因为都是无符号数,因而64-220=100 即可退出循环。 楼主可以多分析一下,建议你看下该链接https://www.stmcu.org.cn/module/forum/thread-608277-1-1.html,同样是讨论Hal_Delay的溢出问题,其实你就会发现ST把uwTick设计成为32位无符号型是有意义的,至于你说的把它改成u8类型其实适用于8位单片机系统,但stm32是32位的单片机系统,所以溢出问题不影响你的延时 HAL代码只是一个事例,具体情况具体分析,U32的循环完了,判断FF后又从0开始计数,或者直接忽略掉此处的溢出中断。循环往复了~~