紀客老白【每日答疑】白紀龍老師每日6點更新一題目,歡迎各位關(guān)注!

答疑方向:半導(dǎo)體設(shè)計,職場規(guī)劃、項目管理、硬件設(shè)計、高速PCB設(shè)計,高速電路設(shè)計,EMC設(shè)計,仿真等等!
答疑講師:白紀龍? ?飛利浦技術(shù)專家、上市公司研發(fā)經(jīng)理、資深硬件教育講師!
1、資歷深厚:10余年消費類電子,汽車電子以及醫(yī)療電子一線項目研發(fā)經(jīng)驗。
2、熱門項目經(jīng)驗:致力于目前熱門物聯(lián)網(wǎng)技術(shù)以及人工智能以及IVD領(lǐng)域醫(yī)療器械的研究與實踐!
3、口碑講師:為多家上市公司與行業(yè)高校進行電子行業(yè)知識講座、技術(shù)內(nèi)訓(xùn)!
學生提問:老師,我手上有個stc51單片機,現(xiàn)在用的延時是軟件延時,但實時性不好,弊端已經(jīng)顯露出來的,所以,我現(xiàn)在打算用定時器0進行延時,但是我現(xiàn)在不知道該怎么實現(xiàn)比較好,
我選擇的思路是:把定時器配置成1ms,已經(jīng)配置完成,然后在定義20ms,50ms,100ms,500ms的變量和標志位,打算當變量達到相對應(yīng)的時間后,對應(yīng)的標志位置1,
我現(xiàn)在疑惑不知道怎么辦的是:我在主函數(shù)中,不知道該如何去實現(xiàn)這些延時
我原來的代碼如下,我想修改成用定時器來延時,但我不知道該怎么實現(xiàn),實時性比較差的代碼如下:
Y07=1;
delay_ms(20);
Y01=0:
if (x01==0)
{
? ? ? Y02=0;
? ? ? delay_ms(500);
? ? ? if (x05 == 0)
? ? ? {
? ? ? ?Y04=0;
? ? ? ? delay_ms(100);
? ? ? ? Y06=1;
? ? ? ?
? ? ? ?}
}
白老師答:A.一般解決思路有兩種:一是改變定時器中斷初始化的值,而是利用全局變量,而定時器初始化的值不變的這種方式;但是改變初始化的值會牽扯進來很多東西,而且如果你的單片機運行的任務(wù)比較多的時候,你還想要通過定時器來實現(xiàn)時間片輪的控制的話,就會變得非常復(fù)雜,所以一般情況下我們?nèi)绻獙崿F(xiàn)精確延時的話,我們都會采取全局變量+定時固定的方式來實現(xiàn),換一種思路就是你可以把延時也看做是MCU運行的所有任務(wù)的其中一個任務(wù)這就要求大家對時間片輪方式去控制不同任務(wù),最簡單的方式其實是用一個全局變量的數(shù)組,數(shù)組中的每個元素代表了一個任務(wù),然后每個任務(wù)的時間片輪是多少可以通過這個數(shù)組來調(diào)整。
B.我們還是回歸到我們精確延時的問題上來,我們使用全局變量的方式來實現(xiàn),其思路如下:
(1)我們需要兩個全局變量:一個全局變量用來實現(xiàn)你要多長時間的延時,另外一個全局變量用來實現(xiàn)你的延時是否已經(jīng)結(jié)束。
(2)具體配合定時器的中斷函數(shù)如何實現(xiàn)呢?我們可以這樣考量,比如說我們要實現(xiàn)ms級的延時我們怎么做呢?
a.首先我們做好延時的初始化,由于我們要做ms級延時,所以我們最好是以1ms做初始化。
b.然后我們每次用延時函數(shù)的時候,我們改變的是全局變量:
u16 global_delay; //.全局變量
……;
delay_ms(285);
/ *
那么當我們在延時函數(shù)中輸入285的時候,我們延時函數(shù)內(nèi)部要做的事情第一步就是首先給全局變量賦值;
然后緊接著中斷函數(shù)中的這個值就會重新賦值,然后每次進入中斷函數(shù)以后就會對改變量減一;
當該全局變量減為0的時候,就讓標志位置一
?
*/
?
void delay_ms(u16 ms)
{
global_delay=ms;
while(!DELAY_FLAG);
?
DELAY_FLAG=0;
}
void Timer_Intterupt()
{
global_delay--;
if(0==global_delay)
DELAY_FLAG=1;