思考:如果中斷函數(shù)HAL_IncTick中的uwTick一直增加導(dǎo)致溢出會(huì)不會(huì)導(dǎo)致延時(shí)不準(zhǔn)?
下面展示一些 STM32的官方庫文件stm32f1xx_hal.c部分摘錄
。
__weak void HAL_IncTick(void)
{
uwTick += uwTickFreq;
}
__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}
__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)
{
}
}
1.問題:
系統(tǒng)Tick頻率設(shè)置為1毫秒中斷一次,每1ms產(chǎn)生一次Tick中斷,
在Tick中斷中uwTick++; 那么當(dāng)自增到0xFFFFFFFF后就會(huì)溢出,再從0開始自增 。
0xFFFFFFFF毫秒大約為49.71天,也就是49天以后會(huì)產(chǎn)生第一次溢出
如果恰巧在延時(shí)時(shí)有溢出會(huì)導(dǎo)致不準(zhǔn)嗎?
2.分析:
每1ms產(chǎn)生一次Tick中斷,在Tick中斷中uwTick++;
uint32_t HAL_GetTick()函數(shù)返回的是當(dāng)前uwTick的值。
假設(shè)uwTick已經(jīng)計(jì)數(shù)到65530,調(diào)用HAL_Delay(10);
tickstart = 65530,但是wait是11,那么當(dāng)uwTick=65535+1,就會(huì)溢出uwTick= 0,
執(zhí)行while((HAL_GetTick() - tickstart) < wait){}
當(dāng)HAL_GetTick()返回0時(shí)的情況:(HAL_GetTick() - tickstart) =(0-65530)
可能認(rèn)為這是個(gè)負(fù)數(shù),此時(shí)會(huì)導(dǎo)致((HAL_GetTick() - tickstart) < Delay) = ((0 - 65530) < 10)=FALSE
事實(shí)并非如此,因?yàn)镠AL_GetTick()的返回值、tickstart和Delay都是uint32_t 型數(shù)據(jù),這樣HAL_GetTick() - tickstart的結(jié)果不可能是負(fù)數(shù)!(重點(diǎn))
此時(shí)計(jì)算uwTick-tickstart=0-65530=-65530:二進(jìn)制表示0000 0000 0000 0110,無符號(hào)十進(jìn)制=6,
那么當(dāng)uwTick=5(0000 0000 0000 0101)時(shí),
uwTick-tickstart=5-65530=-65525,二進(jìn)制表示0000 0000 0000 1011,
延時(shí)還是11ms(0000 0000 0000 1011),所以無符號(hào)的uwTick溢出并不會(huì)導(dǎo)致延遲錯(cuò)亂,此處差值不存在負(fù)數(shù),要考慮好無符號(hào)數(shù)的計(jì)算方法。
這個(gè)問題的主要依據(jù)是使用了計(jì)算機(jī)的原碼,反碼,補(bǔ)碼的知識(shí)??梢詤⒖既缦骆溄?寫的非常好
鏈接: https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html
反轉(zhuǎn)
后來我看到有人評(píng)論uint32_t是32位,最大數(shù)位4294967295,就突然覺得上面舉例不成立了,后來仔細(xì)想了想,其實(shí)原理都一樣,只不過是到4294967295才會(huì)溢出,上面舉的例子把65530改為4294967290就合理了。
uwTick-tickstart=5-4294967290=-4294967285,十六進(jìn)制表示FFFF 0000 000B,
延時(shí)還是11ms(0000 000B),文章來源:http://www.zghlxwxcb.cn/news/detail-842065.html
3.拓展
編碼器計(jì)算速度
使用定時(shí)器編碼器模式計(jì)數(shù)編碼器的脈沖,當(dāng)計(jì)數(shù)值達(dá)最大溢出時(shí),相減仍然可以得到差值,用來計(jì)算速度。文章來源地址http://www.zghlxwxcb.cn/news/detail-842065.html
到了這里,關(guān)于關(guān)于STM32的hal庫中滴答定時(shí)器uwTick溢出的思考和分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!