新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)C51編程幾個(gè)有用的模塊

單片機(jī)C51編程幾個(gè)有用的模塊

作者: 時(shí)間:2012-07-04 來源:網(wǎng)絡(luò) 收藏

KeilC51常用功能模塊使用說明

說明
本文檔包括系統(tǒng)中常用到的時(shí)鐘中斷、通訊及鍵盤掃描等模塊(見所附源程序)的說明。這些模塊使用前后臺(tái)系統(tǒng)模型。為達(dá)到最大的靈活性,需要在用戶工程中定義config.h文件,在其中定義各模塊可選參數(shù)的設(shè)置,而不是直接更改源代碼。
這些可選內(nèi)容大部分為宏定義,如果不定義宏相應(yīng)的功能在編譯時(shí)被屏蔽,不會(huì)增加代碼長度。具體可選內(nèi)容見各模塊中的說明。
在Config.h文件中還要包含一個(gè)硬件的資源頭文件。
各模塊使用了定義在Common.h中的一些數(shù)據(jù)類型。如:BIT(bit)BYTE(unsignedchar)等,具體請參見源程序。

時(shí)鐘模塊
軟件設(shè)計(jì)中,時(shí)鐘是重要資源,為了充分利用時(shí)鐘資源,故設(shè)計(jì)本時(shí)鐘模塊。本模塊使用定時(shí)器0,在完成用戶指定功能的同時(shí),還能夠自動(dòng)處理一些其它模塊中與時(shí)鐘相關(guān)的信息。
時(shí)鐘模塊由聲明文件Timer.h以及實(shí)現(xiàn)文件Timer.c組成。
用戶應(yīng)該在Config.h中定義宏TIMER_RELOAD來設(shè)定定時(shí)器0的重裝載初值。推薦的定時(shí)器0的中斷時(shí)間大于1毫秒。

在程序的初始化階段調(diào)用時(shí)鐘模塊的初始化函數(shù)InitTimerModule()之后,就可以使用時(shí)鐘模塊所以支持的各種功能。具體描述如下:
延時(shí):當(dāng)用戶需要進(jìn)行一定時(shí)間的延時(shí)時(shí),可以通過調(diào)用Delay()來進(jìn)行,參數(shù)為時(shí)鐘中斷的次數(shù)。如時(shí)鐘中斷周期為1ms,想進(jìn)行100ms的延時(shí),則可以調(diào)用Delay(100)。
注意:
如果延時(shí)的絕對時(shí)間小于時(shí)鐘中斷的周期,則不能夠用本方法做到延時(shí)。

定時(shí):當(dāng)程序中需要使用定時(shí)功能時(shí),如等待某外部事件,如果在一定時(shí)間內(nèi)發(fā)生則繼續(xù)執(zhí)行,如果在這段時(shí)間內(nèi)發(fā)生,則認(rèn)為出現(xiàn)錯(cuò)誤,轉(zhuǎn)向錯(cuò)誤處理機(jī)制。
在此推薦一種編程模式,但用戶可以用自己認(rèn)為更合理的方式處理此類問題。
這里簡單說明一下關(guān)于阻塞式函數(shù)及非阻塞式函數(shù)。簡單說,阻塞式函數(shù)就是當(dāng)檢測完成條件,如果不能夠完成則等待,如:
voidCheckSomething()
{
//gbitSuccessFlagisaglobalvariable
while(gbitSuccessFlag==FALSE)
{
//donothingbutwaiting
}
}
可以看到,當(dāng)bitSuccessFlag沒有被設(shè)置為TRUE時(shí),函數(shù)保持等待狀態(tài)不返回,這樣就是阻塞式的函數(shù)。
另外一種情況:
BITCheckSomething()
{
if(gbitSuccessFlag==TRUE)
{
//…
returnTRUE;
}
returnFALSE;
}
在這里,如果所檢測的事件有沒有完成,函數(shù)進(jìn)行檢測之后,立刻返回,通過返回值報(bào)告完成情況,如果沒有完成,則等待調(diào)用者分配再次執(zhí)行的機(jī)會(huì)。這樣的函數(shù)就是非阻塞函數(shù)。
在應(yīng)用定時(shí)功能時(shí),首先要將檢測函數(shù)定義成非阻塞函數(shù)。如上面的第二個(gè)版本的CheckSomething。
然后下面模式:
BITbitDone=FALSE;
ResetClock();//cleartimerinterrupttimescounter
while(GetClock()MAX_WAITINGTIME)
{
if(CheckSomething()==TRUE)
{
bitDone=TRUE;
break;
}
}
if(bitDone==FALSE)
{
//processtimeout
}

或者簡單寫成:
BITbitDone=FALSE;
ResetClock();
while(GetClock()MAX_WAITINGTIME(bitDone=CheckSomething));
if(bitDone==FLASE)
{
//…
}

軟件看門狗:實(shí)現(xiàn)具有局限性的看門狗功能。在程序中合適的地方加入對軟件看門狗的復(fù)位函數(shù)ResetWatchDog(),在Config.h中加入宏TIMER_WATCHDOGTIMEOUT。當(dāng)程序運(yùn)行時(shí),如果在發(fā)生TIMER_WATCHDOGTIMEOUT次時(shí)鐘中斷之內(nèi)沒有復(fù)位軟件看門狗,則系統(tǒng)復(fù)位。
注意:
如果沒有加入TIMER_WATCHDOGTIMEOUT宏,程序中的ResetWatchDog沒有任何用處,不用刪除。
如果系統(tǒng)不能實(shí)現(xiàn)時(shí)鐘中斷,則軟件看門狗也同時(shí)失去功能。
目前版本的的時(shí)鐘模塊的復(fù)位功能并不是完全復(fù)位,主要表現(xiàn)在當(dāng)復(fù)位之后,系統(tǒng)將不再響應(yīng)任何中斷。所以軟件看門狗只是一個(gè)程序的調(diào)試功能,不應(yīng)該將它用于正式工作的程序,此時(shí)應(yīng)該使用硬件看門狗。

用戶自定義任務(wù):如果想在時(shí)鐘中斷內(nèi)執(zhí)行一些耗時(shí)較短的任務(wù),可以定義回調(diào)函數(shù)OnTimerInterrupt。函數(shù)原形為:voidOnTimerInterrupt();
如果想在發(fā)生時(shí)鐘中斷時(shí)執(zhí)行一些功能,而這些功能又耗時(shí)相對較長,不合適放在中斷響應(yīng)函數(shù)內(nèi)部,則可以在程序中的主循環(huán)中的任意地方添加:ImpTimerService(),同時(shí)提供原形為voidOnTimerEvent()的回調(diào)函數(shù)。具體的程序如下所示:
voidmain()
{
Initialize();
while(TRUE)
{
//…working
ImpTimerService();
//…working
}
}

voidOnTimerEvent()
{
//dosometask
}

對通訊模塊提供支持:如通訊中的各種超時(shí)等,見通訊模塊中的詳細(xì)說明。
對鍵盤掃描模塊提供支持:可以自動(dòng)調(diào)用鍵盤掃描模塊,見鍵盤掃描模塊中的詳細(xì)說明。
對程序調(diào)試提供支持:在程序開發(fā)過程中,有時(shí)為了判斷程序是不是在工作,常用利用單片機(jī)系統(tǒng)的某一空閑引腳通過一個(gè)限流電阻接一個(gè)發(fā)光二極管,在程序中間隔固定時(shí)間交替控制發(fā)光管的明暗。實(shí)現(xiàn)這個(gè)功能只要在Config.h文件中定義TIMER_FLASHLED宏,如:
#defineTIMER_FLASHLEDP1_0
則當(dāng)時(shí)鐘中斷發(fā)生256次之后,改變發(fā)光管的狀態(tài)。


上一頁 1 2 3 下一頁

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉