介紹一個(gè)定時(shí)器的使用小技巧,今天寫(xiě)代碼需要用到一個(gè)功能,實(shí)時(shí)測(cè)量程序運(yùn)行時(shí)間,要求測(cè)量時(shí)間精度要高。
精度高就想到了硬件定時(shí)器,但是整個(gè)系統(tǒng)比較復(fù)雜,硬件定時(shí)器都被占用了,想了想只能和某項(xiàng)功能共用一個(gè)定時(shí)器了。系統(tǒng)中使用了一個(gè)systick定時(shí)器,systick定時(shí)器是一個(gè)自動(dòng)裝載遞減定時(shí)器,即,計(jì)數(shù)器從設(shè)定值開(kāi)始遞減,減到零時(shí)觸發(fā)systick中斷,然后計(jì)數(shù)器自動(dòng)裝載初值開(kāi)始下一個(gè)計(jì)數(shù)周期。這里配置為1ms產(chǎn)生一次中斷,中斷內(nèi)有一個(gè)全局變量加1,如果直接用這個(gè)變量計(jì)算時(shí)間,精度±1ms,太差了。于是乎又寫(xiě)了倆函數(shù),可以實(shí)現(xiàn)us級(jí)別測(cè)量,后面一一介紹。
void SysTick_Handler(void)
{
g_dwSysTickCnt++;//ms中斷,精度只有±1ms
}
函數(shù)1:測(cè)量開(kāi)始函數(shù):
//測(cè)量開(kāi)始函數(shù)
void drvMeasureUsStart(void)
{
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //關(guān)閉定時(shí)器
g_dwOldTime = SysTick->VAL; //記錄當(dāng)前計(jì)數(shù)值
g_dwStartTimeMs = g_dwSysTickCnt; //獲取當(dāng)前ms數(shù)
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //使能定時(shí)器
g_dwReload = SysTick->LOAD; //獲取重載值
}
函數(shù)2:測(cè)量結(jié)束函數(shù):
DWORD drvMeasureUsStop(void)
{
DWORD dwNowTime,dwpRunTimeUs;
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //關(guān)閉定時(shí)器
dwNowTime = SysTick->VAL;
g_dwStartTimeMs = g_dwSysTickCnt - g_dwStartTimeMs; //獲取ms數(shù)差值
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //使能定時(shí)器
if(g_dwStartTimeMs > 0u)
{
g_dwStartTimeMs--;
dwpRunTimeUs = g_dwReload - dwNowTime + g_dwOldTime;
}
else
{
dwpRunTimeUs = g_dwOldTime - dwNowTime;
}
g_dwStartTimeMs *= 1000u; //換算為us
dwpRunTimeUs = dwpRunTimeUs/(g_dwSysTickClockMhz); //換算為us
dwpRunTimeUs += g_dwStartTimeMs;
return dwpRunTimeUs;
}
使用方法:
//測(cè)量usercode()函數(shù)運(yùn)行時(shí)間
{
DWORD dwTime;
...
...
drvMeasureUsStart();
usercode();
dwTime = drvMeasureUsStop();
...
...
}
-
中斷
+關(guān)注
關(guān)注
5文章
898瀏覽量
41505 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3248瀏覽量
114833 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4331瀏覽量
62633 - 代碼
-
Systick
+關(guān)注
關(guān)注
0文章
62瀏覽量
13095
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論