單片機(jī)中斷應(yīng)用的C語(yǔ)言編程
C51編譯器支持在C源程序中直接開(kāi)發(fā)中斷程序,從而減輕了采用匯編語(yǔ)言編寫(xiě)中斷服務(wù)程序的繁瑣程度。為了滿(mǎn)足在C語(yǔ)言源程序中直接編寫(xiě)中斷服務(wù)程序的需要,C51編譯器對(duì)函數(shù)的定義進(jìn)行了擴(kuò)展,增加了一個(gè)擴(kuò)展關(guān)鍵詞interrupt。他是函數(shù)定義式的一個(gè)選項(xiàng),加上這個(gè)選項(xiàng)即可以將一個(gè)函數(shù)定義成中斷服務(wù)函數(shù)。定義中斷服務(wù)函數(shù)的語(yǔ)法格式如下:
返回值類(lèi)型 函數(shù)名( )interrupt m [using n]<?XML:NAMESPACE PREFIX = O />
{
函數(shù)體
}
關(guān)鍵詞interrupt后面的m是中斷號(hào),m的取值為0~31的正整數(shù),編譯器從8m+3處產(chǎn)生中斷向量,具體的中斷號(hào)m和中斷向量取決于80C51,80C51中斷源編號(hào)見(jiàn)表。80C51單片機(jī)可以在片內(nèi)RAM中使用4個(gè)不同的工作寄存器組,每個(gè)寄存器組中包含8個(gè)寄存器(R0~R7)。C51編譯器擴(kuò)展了一個(gè)關(guān)鍵字using,專(zhuān)門(mén)用來(lái)選擇不同的工作寄存器組。using
表 80C51單片機(jī)中斷源編號(hào)
編號(hào) | 中斷源 | 入口地址 | 編號(hào) | 中斷源 | 入口地址 |
0 | 外部中斷0 | 0003H | 3 | 定時(shí)/計(jì)數(shù)器1 | 001BH |
1 | 定時(shí)/計(jì)數(shù)器0 | 000BH | 4 | 串行口中斷 | 0023H |
2 | 外部中斷1 | 0013H | | | |
后面的n是一個(gè)0~3的常整數(shù),分別選中4個(gè)不同的工作寄存器組。在定義一個(gè)函數(shù)時(shí),using是一個(gè)選項(xiàng),如果不用該選項(xiàng),則由編譯器自動(dòng)選擇一個(gè)寄存器組訪(fǎng)問(wèn)。需要注意的是,關(guān)鍵字using和interrupt的后面都不允許跟帶運(yùn)算符的表達(dá)式。
關(guān)鍵字using對(duì)函數(shù)目標(biāo)代碼的影響如下:
在函數(shù)的入口處將當(dāng)前工作寄存器組保護(hù)到堆棧中,指定的工作寄存器內(nèi)容不會(huì)改變;函數(shù)退出之前將被保護(hù)的工作寄存器組從堆棧中恢復(fù)。
使用關(guān)鍵字using在函數(shù)中確定一個(gè)工作寄存器組時(shí)必須小心,要保證任何寄存器組的切換都在控制之下,否則將產(chǎn)生不確定的函數(shù)結(jié)果。另外還要注意,帶using屬性的函數(shù)原則上不能返回bit類(lèi)型的值,并且關(guān)鍵字using不允許用于外部函數(shù)。
關(guān)鍵字interrupt也不允許用于外部函數(shù),它對(duì)中斷函數(shù)目標(biāo)代碼的影響如下:
在進(jìn)入中斷函數(shù)時(shí),特殊功能寄存器ACC、B、DPH、DPL、PSW將被保存入棧,如果不使用using進(jìn)行工作寄存器組的切換,則將中斷函數(shù)中所用到的全部工作寄存器都入棧保護(hù),在函數(shù)退出之前恢復(fù),中斷函數(shù)由RETI指令結(jié)束。
編寫(xiě)80C51單片機(jī)中斷函數(shù)時(shí)應(yīng)遵循以下原則:
①中斷函數(shù)不能進(jìn)行參數(shù)傳遞,如果中斷函數(shù)中包含任何參數(shù)聲明,都將導(dǎo)致編譯出錯(cuò)。
②中斷函數(shù)沒(méi)有返回值,如果企圖定義一個(gè)返回值,將得到不正確的結(jié)果。因此建議在定義中斷函數(shù)時(shí)將其定義為void類(lèi)型,以明確說(shuō)明沒(méi)有返回值。
③在任何情況下,都不能直接調(diào)用中斷函數(shù),否則會(huì)產(chǎn)生編譯錯(cuò)誤。因?yàn)橹袛嗪瘮?shù)的退出是由80C51單片機(jī)指令RETI完成的,RETI指令影響80C51單片機(jī)硬件中斷系統(tǒng)。如果在沒(méi)有實(shí)際中斷請(qǐng)求的情況下直接調(diào)用中斷函數(shù),則RETI指令的操作結(jié)果會(huì)產(chǎn)生一個(gè)致命的錯(cuò)誤。
④如果在中斷函數(shù)中調(diào)用了其他函數(shù),則被調(diào)用函數(shù)所使用的寄存器組必須與中斷函數(shù)相同。用戶(hù)必須保證按要求使用相同的寄存器組,否則會(huì)產(chǎn)生不正確的結(jié)果,這一點(diǎn)必須注意。如果定義中斷函數(shù)時(shí)沒(méi)有使用using選項(xiàng),則由編譯器自動(dòng)選擇一個(gè)寄存器組。另外,由于中斷的產(chǎn)生不可預(yù)測(cè),中斷函數(shù)對(duì)其他函數(shù)的調(diào)用可能形成遞歸調(diào)用,需要時(shí)可將被中斷函數(shù)所調(diào)用的其他函數(shù)定義成再入函數(shù)。
⑤C51編譯器從絕對(duì)地址8m+3處產(chǎn)生一個(gè)中斷向量,其中m為中斷號(hào)。該向量包含一個(gè)到中斷函數(shù)入口地址的絕對(duì)跳轉(zhuǎn)。
下面給出一個(gè)中斷編程實(shí)例。
例 用C語(yǔ)言編寫(xiě)例6-4的程序
分析:假設(shè)中斷源A、B、C、D都沒(méi)有中斷,皆為高電平;若有一個(gè)產(chǎn)生中斷,通過(guò)四或門(mén)在INT1引腳產(chǎn)生低電平,因?yàn)樵谥鞒绦蛑幸验_(kāi)放了中斷,所以就會(huì)執(zhí)行中斷服務(wù)程序把flag設(shè)置為1,主程序判斷flag=1,就會(huì)根據(jù)P1的低位來(lái)判斷哪一位為低,即哪一個(gè)中斷源產(chǎn)生中斷。
C51參考程序如下:

編輯:admin 最后修改時(shí)間:2018-05-08