假設(shè)使用定時器3每1毫秒定時;保存至SD卡的函數(shù)是StartSave();
第一種情況:定時器快,主循環(huán)慢
1、代碼設(shè)計1(錯誤的設(shè)計)
[cpp] view plain copy
int cnt = 0; //計數(shù)
//TIM3中斷處理函數(shù)
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
cnt ++;
}
}
void main(void)
{
代碼段1
while(1)
{
代碼段2
if(cnt %100 == 0)
{
StartSave();
}
代碼段3
}
}
分析:第一種設(shè)計經(jīng)測試發(fā)現(xiàn)并沒有按照預(yù)期的100毫秒間隔保存;原因何在呢?
很明顯后臺程序運(yùn)行較快,當(dāng)cnt 變?yōu)?00的倍數(shù)時,主循環(huán)可能到達(dá)“代碼段3”,當(dāng)主循環(huán)再次到達(dá)
“代碼段2”時,定時器中斷已經(jīng)改變了cnt的值。
2、代碼設(shè)計2(在這種情況下正確)
[cpp] view plain copy
int cnt = 0; //計數(shù)
unsigned char isOK = 0;
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
if(cnt++ % 100 == 0)
isOK = 1;
}
}
void main(void)
{
代碼段1
while(1)
{
代碼段2
if(isOK == 1)
{
isOK = 0;
StartSave();
}
代碼段3
}
}
設(shè)計2避免了1中所出現(xiàn)的問題。
第二種情況:定時器慢,主循環(huán)快
在這種情況下上面的代碼設(shè)計2就出現(xiàn)問題了。出現(xiàn)保存多了的情況。
原因很明顯,isOK這個變量的變化相對于主循環(huán)來說變化太慢了。會出現(xiàn)isOK一直為1 的情況。
假設(shè)定時器定時1ms,主循環(huán)0.5ms周期
1、代碼設(shè)計1(錯誤的設(shè)計)
[cpp] view plain copy
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
cnt++;//該值理論保持時間僅1ms
}
}
void main(void)
{
unsigned char saveFin = 0;
代碼段1
while(1)
{
代碼段2
if(cnt%100 )
{
StartSave();//明顯出現(xiàn)100ms內(nèi)多次保存的情況,因為主循環(huán)快
}
代碼段3
}
}
2、代碼設(shè)計2(正確的設(shè)計)
[cpp] view plain copy
unsigned char saveFin = 0;
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
cnt++;//該值理論保持時間僅1ms
}
}
void main(void)
{
unsigned char saveFin = 0;
代碼段1
while(1)
{
代碼段2
if(cnt%100 == 0 && saveFin == 0 )
{
saveFin = 1;
StartSave();
}
else
{
saveFin = 0;
}
代碼段3
}
}
第三種情況:不能確定定時器和main循環(huán)周期哪個快的設(shè)計
當(dāng)然主循環(huán)的周期不能大于保存周期100ms
[cpp] view plain copy
unsigned char isOK = 0;
unsigned int clkCnt = 0;
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
if(clkCnt++ % 10 == 0)
cnt++;//該值理論保持時間10ms,需要在主循環(huán)中清零
}
}
void main(void)
{
unsigned char saveFin = 1;//注意這里的初始值為1,與前面設(shè)計不同
代碼段1
while(1) //循環(huán)周期不能大于10ms,否則丟失對cnt的判斷
{
代碼段2
if(cnt%10 == 0) //例如在100ms--110ms之間時將“保存標(biāo)志”清零
{
saveFin = 0;
}
else //例如在110ms--200ms之間時完成保存
{
if(saveFin == 0)//在110ms--200ms之間只能保存一次的代碼設(shè)計
{
startSave();
saveFin = 1;
}
}
代碼段3