虞益龍
(常州劉國鈞高等職業(yè)技術(shù)學(xué)校,江蘇 常州 213000)
傳統(tǒng)的單片機(jī)程序設(shè)計(jì)多為單任務(wù)系統(tǒng),其業(yè)務(wù)邏輯順序安排在主函數(shù)中,主函數(shù)一般為死循環(huán),循環(huán)過程中通過調(diào)用函數(shù)來完成相應(yīng)的操作,而對于一些較短的實(shí)時任務(wù)則通過中斷方式進(jìn)行處理。此種程序結(jié)構(gòu)簡單、直觀,易于實(shí)現(xiàn),但對于較復(fù)雜的應(yīng)用此種結(jié)構(gòu)實(shí)現(xiàn)不了,并且不能滿足實(shí)時性要求較高的場合,因此必須考慮一種新的結(jié)構(gòu)模式。
本文提出的方法也是按時間片切換任務(wù)的,但不同的是,執(zhí)行任務(wù)的時間不是由定時器平均分配的,而是按照執(zhí)行任務(wù)中一個完整過程的時間來自動分配的。在單片機(jī)系統(tǒng)程式設(shè)計(jì)中,可按系統(tǒng)的功能或模塊劃分為任務(wù),而每個任務(wù)可按具體作業(yè)細(xì)分為各個過程??梢娙蝿?wù)由過程組成。按時間片分配任務(wù)的設(shè)計(jì),系統(tǒng)效率就會更高。
多任務(wù)輪循程序架構(gòu)就是一個系統(tǒng)由多個任務(wù)構(gòu)成,各任務(wù)之間相對獨(dú)立。本文提出一種基于定時器中斷的多任務(wù)輪循程序架構(gòu),如圖1所示。在主程序中,根據(jù)任務(wù)延時量判斷任務(wù)是否就緒,各任務(wù)輪循占用CPU時間,由任務(wù)延時量控制任務(wù)執(zhí)行頻度及CPU關(guān)照度,而任務(wù)延時量又由定時器T0中斷控制。
圖1 定時中斷的多任務(wù)輪循程序架構(gòu)流程圖
基于定時器中斷的多任務(wù)輪循架構(gòu)中,子任務(wù)的執(zhí)行依靠主程序任務(wù)調(diào)度來實(shí)現(xiàn),子任務(wù)不能設(shè)計(jì)成死循環(huán)流程。正因?yàn)楦魅蝿?wù)不搶占CPU,所以程序設(shè)計(jì)不用考慮現(xiàn)場保護(hù)問題,簡化了程序設(shè)計(jì)。程序整體架構(gòu)有定時器固定節(jié)拍中斷,該節(jié)拍需滿足最快任務(wù)執(zhí)行頻度需要。定義定時中斷頻度,由執(zhí)行頻度要求最快的任務(wù)確定,太高會降低CPU運(yùn)行效率,太低任務(wù)頻度不好分配,一般低于200Hz即可。本文采用50Hz。對于按鍵掃描程序模塊,每秒按50次頻度執(zhí)行即可,LCD1602和實(shí)時時鐘數(shù)據(jù)讀取模塊可以按每秒3次頻度執(zhí)行即可。
/*代碼說明:這里通過宏定義,在頭文件中把易變參數(shù)進(jìn)行定義,這樣使得程序容易修改,一改全改,便于移植。*/
/*代碼說明:定時中斷在這里就是心臟,依靠定時中斷完成任務(wù)延時量的修改,從而實(shí)現(xiàn)不同任務(wù)運(yùn)行頻度控制。*/
任務(wù)執(zhí)行頻度由任務(wù)延時量task_delay[ID]控制,各任務(wù)延時量在定時中斷中減一,直到延時量為零,相關(guān)任務(wù)就緒?!癐D”表示各任務(wù)代號。任務(wù)調(diào)度過程就是對任務(wù)延時量檢測過程,只有任務(wù)延時量為零時,CPU從其它任務(wù)中返回后立即執(zhí)行相應(yīng)的任務(wù),由于不同任務(wù)延時量不同,從而實(shí)現(xiàn)不同任務(wù)具有不同的執(zhí)行頻度而相互不受時間影響。這里必須滿足一個條件,就是每個任務(wù)執(zhí)行一次的時間不能太長,不能超過一次定時中斷時間,否則任務(wù)之間執(zhí)行頻度會有影響,對于50Hz的中斷頻率,每個任務(wù)執(zhí)行時間最好不超過20ms,即CPU光顧一次任務(wù)時間要在20ms以內(nèi),這樣就可以保證任務(wù)之間相互完全不受影響。
定時器中斷服務(wù)等待任務(wù)就緒代碼如下:
/*代碼說明:在定時中斷服務(wù)中,執(zhí)行的任務(wù)必須很簡短,重置定時器初值,把大于0的任務(wù)延時量減1,該定時中斷作為心臟跳動,不斷進(jìn)出運(yùn)行,為了節(jié)省CPU時間,該中斷任務(wù)越簡單越好。*/
任務(wù)切換在主程序main()中完成,系統(tǒng)初始化之后,在一個大循環(huán)中,判斷各任務(wù)的延時量是否為零,當(dāng)任務(wù)延時量為零時,表示該任務(wù)就緒,當(dāng)前一個任務(wù)主動放棄CPU之后,馬上啟動就緒的新任務(wù)。各任務(wù)之間不具有搶占功能,因此不用考慮堆棧與保護(hù)。
主程序服務(wù)及任務(wù)切換代碼如下:
/*代碼說明:根據(jù)任務(wù)延時量是否為零選擇執(zhí)行就緒任務(wù),任務(wù)執(zhí)行完成后返回再恢復(fù)設(shè)定的延時量;下劃線表示任務(wù)執(zhí)行的頻度,即每秒鐘執(zhí)行多少次。各個不同的任務(wù),根據(jù)需要,設(shè)定不同的延時量,延時量在定時中斷中逐步減一歸零,每個任務(wù)必須主動放棄CPU,正因此,各任務(wù)執(zhí)行時間最好不要超過定時中斷節(jié)拍時間單位,本文為20ms,否則將影響其它任務(wù)運(yùn)行。*/
/*代碼說明:任務(wù)延時量為零時,就緒任務(wù)執(zhí)行,任務(wù)過程可以根據(jù)需求設(shè)置若干個。例:數(shù)碼管顯示模塊可以放在任務(wù)0執(zhí)行,按鍵掃描程序模塊放在任務(wù)1執(zhí)行。*/
由此可見,系統(tǒng)按完整過程(最小作業(yè)單元)自動切換任務(wù),不需保留臨時現(xiàn)場數(shù)據(jù),不需定時被動切換,不需額外的調(diào)度表。與單任務(wù)編程相比,多任務(wù)編程也沒有占用系統(tǒng)任何額外資源,其結(jié)構(gòu)和代碼的可讀性也沒有較大的改變。
單片機(jī)多任務(wù)編程方法可歸納為:(1)在單片機(jī)多任務(wù)編程中,各任務(wù)依次排成隊(duì)列輪流執(zhí)行;(2)每次執(zhí)行任務(wù)只調(diào)用其一個過程來執(zhí)行,可保證各任務(wù)間最快速地切換;(3)各任務(wù)、過程間使用全局變量共享或交換數(shù)據(jù),避免各種參數(shù)傳遞。
在過去采用傳統(tǒng)方法設(shè)計(jì)復(fù)雜的單片機(jī)系統(tǒng)過程中,人們?nèi)菀装l(fā)現(xiàn)系統(tǒng)交叉調(diào)用多,重復(fù)代碼多,系統(tǒng)運(yùn)行效率差,邏輯容易混亂且難以調(diào)試。鑒于此,需要探索一個結(jié)構(gòu)清晰,易調(diào)試,任務(wù)明確且可重用、提高開發(fā)效率,無相互調(diào)用,無重復(fù)代碼的系統(tǒng)。采用定時中斷的多任務(wù)輪循程序架構(gòu),與傳統(tǒng)設(shè)計(jì)相比,基于該架構(gòu)的系統(tǒng)產(chǎn)品消耗硬件資源少,運(yùn)行效率高,其硬件功能更多以軟件取代,所以運(yùn)行更穩(wěn)定,易維護(hù),性價比高,取得了更高的經(jīng)濟(jì)效益。
[1]劉明路,王亮生,李世煜.基于RTX51的單片機(jī)軟件設(shè)計(jì)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2002(3).
[2]歐偉明.面向嵌入式系統(tǒng)設(shè)計(jì)的RTX51[J].應(yīng)用技術(shù)研究,2007(5).
[3]周程.RTX51 Tiny在核數(shù)據(jù)采集系統(tǒng)中的應(yīng)用[J].核電子學(xué)與探測技術(shù),2008,599-610.
[4]劉光德,林莘,王群.基于RTX51嵌入式實(shí)時操作系統(tǒng)的智能稱重儀表的研究[J].科技應(yīng)用,2004,7-9.
[5]KEIL Software,Inc.《RTX51 Real-time Kernel》[EB/OL].http://www.keil.com/rtx51,2004.