
是这样的,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的计算这个时候系统怎么处理呢?会直接解除死循环吗? 《我说的这种概率情况》 同时想起来刚刚做的笔试题目,是不是也是这个问题呢? ![]() |
这个是一个很好的例子:模仿kfifo实现的环形缓冲区
评分
查看全部评分
不是,是无符号数和有符号数的问题。http://www.cnblogs.com/hfyinsdu/p/4600052.html
评分
查看全部评分
HAL_Delay()函数的参数类型是uint32_t,即无符号32位int型。
如果超过32位的最大数(4亿多4294967296)的话,的确会有问题。那么延时会多长了呢,以标准的HAL_Delay()单位1ms计算,4294967296ms,4294967秒,1193小时。只能是人为判断,参数不要超过32位uint32_t。
评分
查看全部评分
2、一般这种有死循环多的,还是尽量开看门狗
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
哦 我传参是100 肯定OK
我说的是(猜测) 比如此时ucTick数值就是4294967290 那会发生什么事呢?它++100会回到0
time_t都没用完32位。
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
会的,溢出后,肯定回到0
就算移植到8位的系统,uwTick也应该定义为uint32_t,就是unsigned long,怎么能改成uint_8呢?
评分
查看全部评分
这个肯定会出现溢出,但是可以参考linux中的实现方法。下面是我的代码,只不过改了些名字,实现是一样的。
#define kernel_time_after(unknow, known) ((long)(know)-(long)(unknow)<0)
#define kernel_time_before(unknow, know) ((long)(unknow)-(long)(know)<0)
#define kernel_time_after_eq(unknow, know) ((long)(unknow)-(long)(know)>=0)
#define kernel_time_before_eq(unknow, know) ((long)(know)-(long)(unknow)>=0)
void kernel_delay_ms(kernel_msec_t millis)
{
unsigned long timeout = _kernel_wall_jiffies + millis/1000*KERNEL_HZ;
while(kernel_time_before(_kernel_wall_jiffies, timeout));
}