官术网_书友最值得收藏!

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關鍵字選擇寄存器組。

主站蜘蛛池模板: 盐源县| 深圳市| 饶平县| 香河县| 蒙山县| 堆龙德庆县| 怀宁县| 高阳县| 咸宁市| 南川市| 巨鹿县| 剑河县| 南郑县| 沈丘县| 肇庆市| 琼结县| 新野县| 西藏| 宜黄县| 永胜县| 上杭县| 潜山县| 新和县| 申扎县| 吉安县| 曲麻莱县| 永顺县| 西乌珠穆沁旗| 白玉县| 永清县| 鹤庆县| 滁州市| 社会| 湘阴县| 马公市| 邻水| 通化市| 锡林郭勒盟| 玛纳斯县| 长沙市| 青浦区|