關於c51的中斷函式要注意的幾個問題
作者 guyepiaoyu日期
2006-5-21 16:27:00
**自:
最近在蝦潭逛,發現一些小蝦公尺對c51中斷函式有些不了解,今天週末,抽空發個技術帖子,希望對小蝦公尺有所幫助,如有錯誤之處,還請指正,就當拋磚引玉吧!
c51的中斷函式的格式為:
void funcir(void) interrupt x [using y]
以下是夢遊的一些分析:
一、中斷函式是乙個特殊的函式,沒有引數,也沒有返回值;但是程式中允不允許使用return呢?答案是允許的,不過只能用"return;",不能用"return(z);";用在一些需要快速返回的地方,對應的彙編會有多個ret語句,相對效率會高一些。
二、using的用法,using可以修飾任何函式,不過個人建議只用來修飾中斷函式;簡單的說,「using」會指定工作暫存器組,由於中斷函式一般都是比較緊急的事情,有時一條語句都會斤斤計較,所以使用using切換暫存器組可以省去一些壓棧的動作,由於51只有兩級中斷,同級中斷不能被打斷,因此,我們可以同級中斷設成同樣的暫存器組,從某種意義上來說,有一組暫存器是多餘的。同時個人建議中斷函式應該使用using這個關鍵字。
三、中斷中呼叫函式,首先要討論中斷函式中呼叫函式的必要性,前天在論壇上我和別人爭論過這個問題,現在我還是這個觀點:有些情況中斷中呼叫函式還是必要的,這個時候是不是該呼叫函式,其實和普通函式差不多,首先是這個函式如果呼叫多次,或者要帶一些引數什麼的就更加必要的;前天有人跟我叫勁,說假如只呼叫一次且無引數無返回的函式要直接寫,因為如果用函式,至少會增加call和ret兩條語句,我不敢苟同,我是實際除錯發現的,當你程式比較複雜時,你將那部分單獨拉出來做成函式,可能**和時間都會更好。
四、中斷中呼叫的函式最好不要被中斷外的其它函式呼叫,因為會出現「重複呼叫」的警告,有時這種呼叫是很致命的,有人說這個函式可以用reentrant來修飾,是的,的確可以這樣解決,不過個人不建議這麼做,也許這樣會跟你減少很多堆疊空間,並且整個程式的優化要差很多,個人建議出現這種情況就把這個函式寫兩遍,分成兩個函式分別呼叫。
五,中斷呼叫了函式,會出現一些莫名其妙的問題,一些資料不對。其實一般是因為彙編中使用了絕對暫存器引起的,有人說中斷函式使用那個暫存器組,被中斷呼叫的
函式就使用哪個暫存器組,我認為這樣不好, 這樣會增加額外的消耗,使用using會增加一下語句:
push psw
mov psw, #xx
....
pop psw
更重要的是,使用using的函式不能有返回值,這是致命傷
個人推薦的方法有兩種:
1、使用「#pragma noaregs」禁止使用絕對暫存器
2、使用「#pragme rb(x)」來指定本檔案的工作暫存器組
六、一般說來,要求中斷函式盡可能的短,但也有特殊情況,有些前/後台的系統中,就會把很多相對重要的事情放到定時中斷(這個定時中斷類似實時作業系統中的時鐘節拍)去做,而且程式很長。我單獨提出來這點是想告訴大家,中斷函式也是乙個函式而已,只要系統有必要,可以做一些看似不合理的事情,該出手時就出手,就像goto語句一樣。
初學C51者應注意的地方
這裡講述一些初學者學習c51的一些誤區和注意事項。高手的特別應用不包括在內。1 c忌諱絕對定位。常看見初學者要求使用 at 這是一種謬誤,把c當作asm看待了。在c中變數的定位是編譯器的事情,初學者只要定義變數和變數的作 用域,編譯器就把乙個固定位址給這個變數。怎麼取得這個變數的位址?要用指標。比如...
關於C語言fgets函式要注意的地方
fgets函式一般用來讀入檔案內容,每次讀一行,然後存入快取區 有人問那怎麼讀下一行,直至讀完整個文字檔案的內容,其實很簡單,只要迴圈用fgets就行,如果你這次把第一行讀完了,那麼下一次檔案指標就會從第二行的開頭開始,下次用fgets就會從第二行開始讀啦!值得一提的是,當fgets函式讀完一行,會...
C51儲存的優化
我們知道51微控制器只有128byte的ram,有的增強型有xram,此時程式設計時就要注意,否則就有可能超出空間 1 對於各模組的全域性變數 靜態變數 全域性列舉型常量,靜態列舉型常量 個別操作儲存 如外部spi flash 的區域性變數都要修飾成xdata型別,從而節省空間。2 對於bit型變數...