- 單片機C語言程序設計實訓100例
- 彭偉編著
- 914字
- 2018-12-27 05:11:56
1.9 可重入函數和中斷函數
Keil C51編譯器在標準C語言函數上提供了很多擴展,例如:
(1)使用關鍵字reentrant指定是否可重入或可遞歸。
(2)使用關鍵字interrupt將某函數設為中斷函數。
(3)使用關鍵字using選擇函數使用的寄存器組。
在C語言中調用函數時,函數參數和局部變量會入棧,由于8051內部堆??臻g有限,為提高效率,Keil C51沒有默認提供這種堆棧方式,它為每個函數設置固定空間,用于存放局部變量。正是因為這種特征,普通Keil C51函數不能被遞歸調用,函數重入時,此前的參數值和局部變量會被覆蓋。
可重入函數允許在函數體內調用自身,可重入函數在被遞歸調用或多重調用時不必擔心變量被覆蓋,因為每次調用時局部變量會被單獨保存,如果編寫的8051單片機C函數必須重入,則函數需要按下面的示例編寫:
void Comm1(int a,int b) reentrant { //局部變量; //函數代碼; }
在設計遞歸程序時必須將遞歸函數聲明為reentrant,這一點不同于標準C語言函數,另外,在單片機程序中,如果一般函數Function1和中斷函數INT_Fx都可能調用同一個函數Comm1,那么Comm1也必須設為可重入,雖然這種調用并非遞歸調用,因為Function1正在調用Comm1時,中斷事件的發生會使中斷函數INT_Fx打斷Function1對它的調用,開始也調用Comm1,這時Comm1必須具有保護現場的能力,因此reentrant關鍵字是必須的。
中斷函數設計是單片機C語言程序設計技術中的重要內容。下面是一個中斷函數(中斷服務程序)示例,中斷號由interrupt關鍵字設置:
void T0_INT() interrupt 1 using 1 { //T0中斷函數代碼 }
中斷函數調用與普通C函數調用是不一樣的,中斷事件發生后T0_INT中斷函數被自動調用,它沒有函數參數,也沒有返回值。用interrupt關鍵字將某函數設為中斷函數會對生成的目標代碼帶來如下影響:
(1)在必要時特殊功能寄存器ACC、B、DPH、DPL及PSW的內容被保存到堆棧中。
(2)如果沒有使用using關鍵字指明寄存器組,中斷函數中的所有工作寄存器將被保存到堆棧中。
(3)退出中斷函數時,所有保存在堆棧中的工作寄存器及特殊功能寄存器被恢復。
(4)函數由8051的RETI指令中止并返回。
(5)另外,Keil C51編譯器會為中斷函數自動生成中斷向量。
上述代碼中的using 1使中斷函數使用寄存器組1,using可選擇0~3,它們代表8051的4個寄存器組,在中斷函數中用using設置寄存器組,可使中斷函數不使用堆棧保存和恢復數據。對于本書案例中的中斷函數,讀者可自行添加using關鍵字選擇寄存器組。
- Kubernetes實戰
- Python for Secret Agents:Volume II
- Java高手真經(高級編程卷):Java Web高級開發技術
- Getting Started with PowerShell
- 從學徒到高手:汽車電路識圖、故障檢測與維修技能全圖解
- 零基礎學Python數據分析(升級版)
- Node.js:來一打 C++ 擴展
- Python Data Science Cookbook
- Python預測分析實戰
- AngularJS UI Development
- Developing Java Applications with Spring and Spring Boot
- 一步一步學Spring Boot:微服務項目實戰(第2版)
- 計算機程序的構造和解釋(JavaScript版)
- TensorFlow 2.0深度學習應用實踐
- Python GUI設計:tkinter菜鳥編程