- 單片機C語言程序設計實訓100例:基于STC8051+Proteus仿真與實戰
- 彭偉
- 924字
- 2022-05-05 20:18:23
1.12 可重入函數和中斷函數
Keil C51編譯器在標準C語言函數上提供了很多擴展功能。
? 使用關鍵字reentrant指定函數是否可重入或可遞歸。
? 使用關鍵字interrupt將某函數定義為中斷函數。
? 使用關鍵字using選擇函數使用的寄存器組。
在標準C語言中調用函數時,函數參數及局部變量將被壓棧。由于8051單片機內部堆??臻g有限,為提高效率,Keil C51編譯器沒有默認提供這種堆棧方式,而是為每個函數設置固定空間,用于存放局部變量。正是因為這種特征,普通Keil C51函數不能被遞歸調用,且在重入時,此前的參數值和局部變量將被覆蓋。
在單片機C語言程序設計中,定義為可重入的函數允許在函數體內調用自身,可重入函數在被遞歸調用或多重調用時不必擔心變量被覆蓋。因為每次調用時局部變量會被單獨保存(壓棧),如果編寫的函數必須重入,則函數須參照下面的示例編寫:

在設計遞歸程序時,必須將遞歸函數聲明為reentrant,這一點不同于標準C語言函數。另外,在單片機程序中,如果一般函數Function1和中斷函數INT_Fx都可能調用同一個函數Comm1,那么Comm1也必須設為可重入,而這種調用并非遞歸調用。因為Function1正在調用Comm1時,中斷事件的發生會使中斷函數INT_Fx打斷Function1對它的調用,開始也調用Comm1,這時Comm1必須具有保護現場的能力,因此reentrant關鍵字是必需的。
中斷函數又稱中斷服務程序、中斷例程、中斷例行程序等。中斷函數設計是單片機C語言程序設計技術中的重要內容。下面是一個中斷函數示例,中斷號由interrupt關鍵字設置:

中斷函數調用與普通C語言函數調用是不一樣的。中斷事件發生后,示例中的“T0_INT”中斷函數被自動調用,并沒有函數參數,也沒有返回值。用interrupt關鍵字將某函數設為中斷函數會對生成的目標代碼造成以下影響。
? 在必要時特殊功能寄存器ACC、B、DPH、DPL及PSW的內容被保存到堆棧中。
? 如果沒有使用using關鍵字指明寄存器組,中斷函數中的所有工作寄存器將被保存到堆棧中。
? 退出中斷函數時,所有保存在堆棧中的工作寄存器及特殊功能寄存器被恢復。
? 函數由8051單片機的RETI指令中止并返回。
? Keil C51編譯器會為中斷函數自動生成中斷向量。
在上述代碼中,using 1使中斷函數使用寄存器組1;using可選擇0~3,它們代表8051單片機的4個寄存器組;在中斷函數中用using設置寄存器組,可使中斷函數不使用堆棧保存和恢復數據。對于本書案例中的中斷函數,調試時可自行添加using關鍵字選擇寄存器組。