
void HAL_IncTick(void) { uwTick++; } 中断函数是1ms进来一次,也就是说uwTick+1就代表1ms void SysTick_Handler(void) { HAL_IncTick(); } void HAL_Delay(__IO uint32_t Delay) { __IO uint32_t timingdelay; timingdelay = uwTick + Delay; //while(HAL_GetTick() < timingdelay) while(uwTick < timingdelay) {; } } 在HAL库里 我就没看到哪里对uwTick溢出进行处理,也就是说uwTick=0xffffffff的时候 再加1就是uwTick=0了 那这一时刻的延时不就延时不准确了吗? |
一楼的写法的确是有BUG的,并非是溢出问题,假设延时 30ms 0x1E:
void HAL_Delay(__IO uint32_t Delay)
{
__IO uint32_t timingdelay;
timingdelay = uwTick + Delay; //假设此时uwTick=0xFFFFFFF0 Delay=0x1E 则 timingdelay=0x1 0000000E,溢出后保留32位=0x0000000E。
//while(HAL_GetTick() < timingdelay)
while(uwTick < timingdelay) //此时的uwTick仍是0xFFFFFFF0或任何小于0xFFFFFFFF的值,则 if(0xFFFFFFF0<0x0000000E) 为假,立即退出,并没有延时30ms。
{;
}
}
正确的写法应该是这样,仍然假设延时 30ms 0x1E:
__weak void HAL_Delay(__IO uint32_t Delay)
{
uint32_t tickstart = 0;
tickstart = HAL_GetTick(); //假设此时uwTick=0xFFFFFFF0 Delay=0x1E 则 tickstart=0xFFFFFFF0。
while((HAL_GetTick() - tickstart) < Delay) //此时的uwTick仍是0xFFFFFFF0或任何小于0xFFFFFFFF的值时,假如是0xFFFFFFF5-0xFFFFFFF0=0x05,if(0x05<0x1E)为真,继续等待。
//如果溢出后 uwTick=0x0000000D,则0x0000000D-0xFFFFFFF0=0x1D,if(0x1D<0x1E)为真,继续等待。
//继续 uwTick=0x0000000E,则0x0000000E-0xFFFFFFF0=0x1E,if(0x1E<0x1E)为假,延时完成,退出。
{
}
}
个人感觉这个解答很好,新版本的HAL也确实是按照他说的这个改的。改了后uwTick的溢出对这个延迟函数没有任何影响。但这个uwTick的溢出是否在别的地方有影响还不好说。得看具体情况了。
uwTick的值范围是不是 0- 0xffffffff;uwTick每1ms加1
当uwTick=0xfffffff0;的时候 延时0xff ms 你就会发现延时不了
void HAL_Delay(__IO uint32_t Delay) // Delay=0xff
{
__IO uint32_t timingdelay;
timingdelay = uwTick + Delay; //假如此刻uwTick =0xfffffff0 Delay=0xff timingdelay=0xef;
//while(HAL_GetTick() < timingdelay)
while(uwTick < timingdelay) //这里不会等待延时 直接跳出去
{;
}
}
不知道你看懂了没有
很费解 求解答
这里的滴答定时器 只是1ms中断一次 就是说1ms uwTick加1 这并没有把我的问题解决
{
return uwTick;
}
这函数,很多库文件调用,用来timeout 延时
我觉得调用了uint32_t HAL_GetTick(void)函数的延时都是有问题的
不过我算了一下 要连接上电46天多才会出现bug (0xffffffff个ms)
所有文件都涉及到这延时 延时的bug
äºååèæ°ï½å¤§éª
滴答定时器到0后,自动+载的吧,另外滴答是的24位计数器,uwTick++达不到uwTick=0xffffffff的吧