天天看點

《51單片機應用開發從入門到精通》——2.8 用外部中斷控制燈閃爍

本節書摘來自異步社群《51單片機應用開發從入門到精通》一書中的第2章,第2.8節,作者 張華傑,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

功能說明:單片機p1端口的8隻led作左移右移,不斷循環。當按外部中斷int0開關k1時,循環停止,轉而使8隻led閃爍4次,然後再恢複燈的左右移循環。

外部中斷int0電路如圖2-11所示。

單片機的p3端口除當一般i/o使用外,還有第二功能,其p3.2(int0)腳是外部中斷0的輸入腳,其p3.3(int1)腳是外部中斷1的輸入腳。

本電路圖中,在p3端口的p3.2引腳上接有外部中斷int0控制開關k1,作為外部中斷的輸入信号。輸出部分由p1端口接的8隻led作輸出顯示。

《51單片機應用開發從入門到精通》——2.8 用外部中斷控制燈閃爍

本程式在燈左右移程式的基礎上,增加了外部中斷int0。

1.流程圖

程式設計流程如圖2-12所示。

《51單片機應用開發從入門到精通》——2.8 用外部中斷控制燈閃爍

2.程式

彙編語言編寫的用外部中斷控制燈閃爍源程式zd01.asm代碼如下:

1.标号說明

start:起始程式的進入點。

loop:左右移循環執行的進入點。

loop1:左移循環的進入點。

loop2:右移循環的進入點。

loop3:閃爍程式循環的進入點。

ext0:中斷子程式的進入點。

delay:延時子程式的進入點。

2.寄存器使用配置設定情況

寄存器p1和a(acc)的作用與之前相同。r0作計數器,在左移、右移和閃爍程式中都由r0負責計數,r5、r6和r7是延時子程式中的計數器。

psw、sp、ie、ip、tcon是新用到的特殊功能寄存器,其中psw是一個8位的專用寄存器,稱為程式狀态字寄存器,用于存儲程式運作中的各種狀态資訊。其中有兩位名為rs0和rs1,改變其值就能選擇cpu目前工作的寄存器組。

寄存器組是cpu工作時臨時存儲資料的地方,共有0~3組,每組8個單元r0~r7,rs0、rs1與寄存器組的對應關系見表2-10。

《51單片機應用開發從入門到精通》——2.8 用外部中斷控制燈閃爍

單片機開始工作時,rs0 = 0、rs1 = 0,cpu選用第0組的8個單元為目前工作寄存器。當主程式要調用中斷子程式時,通過“clr rs1”語句使rs1 = 0,通過“setb rs0”語句使rs0 = 1,即将rs1置為0、rs0置為1,則中斷子程式就可以使用第1組8個單元為目前工作寄存器r0~r7。

這樣,使主程式使用的第0組r0~r7的内容就能保持不變,即主程式與子程式各自使用各自的寄存器,以免内容混淆。

sp也是一個8位的專用寄存器,稱為堆棧指針寄存器,用于暫存堆棧頂部的位址。堆棧是按先進後出、後進先出的原則存取資料的一個專用存儲區。資料的進棧出棧由指針sp統一管理。

tcon、scon、ie和ip是4個特殊功能寄存器,它的作用是對中斷進行管理和控制。

3.程式分析解釋

01~04:規定起始位址。通過“org 00h”語句,規定了标号start所在的位址為00h,即第一條指令從00h開始存放;通過“org 03h”語句規定了下面标号ext0的中斷子程式起始位址為03h,03h是外部中斷0的入口位址。

05~08:中斷設定。首先是對中斷允許控制寄存器ie的設定。允許中斷是由兩層控制,第一層為全面控制(ea),它是總開關,第二層(ex0)是對個别中斷的控制,它是分開關。

通過“mov ie, #10000001b”語句,使中斷允許控制寄存器ie中的允許總控制位ea值為1,即中斷總允許。使ex0 = 1,即外中斷0允許使用。

接着對優先級控制寄存器ip進行設定。中斷有優先級,各中斷源的優先級由優先級控制寄存器ip進行管理,分低優先級和高優先級:px0 = 0時,為低優先級;px0 = 1時,為高優先級。“mov ip, #00000001b”語句使px0 = 1,即使外部中斷0為高優先級。

中斷觸發有兩種方式:脈沖方式和電平觸發方式。兩種方式的選擇是通過定時寄存器tcon來設定的。通過“mov tcon, #00000000b”語句将it0位設定為0,則使外中斷0選擇了電平觸發方式。

語句“mov sp, #70h”設定堆棧指針位址,當程式中執行保護現場指令push或恢複現場指令pop時,sp會自動加1或減1,然後将資料壓入或彈出堆棧,目的是使中斷結束後能正确地回到程式調動點繼續執行。

09~20:使led左移和右移。

21~33:中斷子程式。

中斷子程式由3部分組成:保護現場部分(21~24行語句)、閃爍功能部分(25~30行語句)和恢複現場部分(31~32行語句)。

其中閃爍功能部分是使用中斷的目的。而閃爍功能部分前邊的保護現場和後邊的恢複現場部分是為了使中斷結束後能正确地回到原程式調用點繼續執行。

21~22行語句是将累加器a和程式狀态字寄存器psw中的值壓棧儲存;23~24行語句是設定rs1 = 0、rs0 = 1,目的是使中斷子程式使用第1組工作寄存器。這樣,第0組r0~r7的内容就能保持不變

34~40:延時1s子程式。

41:程式結束。

4.邊用邊學指令

本節程式新用到的指令有:push、pop、reti和org。

push和pop是兩條專用堆棧操作指令,屬于資料傳送類。堆棧操作的特點是按先進後出、後進先出的原則存取資料。push和pop是成對出現的,push是進棧指令,pop是出棧指令,一般用于在中斷子程式中保護現場和恢複現場。

reti是控制轉移類指令,reti的功能是使中斷服務程式結束傳回。reti除具有子程式傳回指令ret所具有的全部功能之外,還有清除中斷響應時被置位的優先級狀态、開放較低級的中斷和恢複中斷邏輯等功能。

org是僞指令,org的功能是規定下面目标程式存放的起始位址。

1.模拟仿真前注意事項

(1)将第12、18、28行調用延時語句前加上分号,如“acall delay”改為“;acall delay”。目的是使程式跳過調用延時的語句,節省模拟運作的時間。

(2)将第20行語句“jmp loop”改為“jmp ext0”,使程式能運作标号為ext0的中斷子程式。

(3)重新将程式“編譯/彙編”和“産生代碼并裝入”,然後再調試。

2.模拟仿真中注意事項

(1)注意觀察中斷設定中特殊功能寄存器ie、ip、tcon和sp值的變化。其中ie、ip、tcon在程式中給出的是二進制值,但在模拟仿真特殊功能寄存器視窗中看到的是十六進制數。

(2)在運作20行語句前,acc的值是feh,psw的值是01h,即psw中控制工作寄存器組的兩個位rs0 = 0、rs1 = 0,是以此時cpu選中的是第0組工作寄存器。

當運作21~24行語句之後,psw的值改變為09h,即psw中控制工作寄存器組的兩個位rs0 = 1、rs1 = 0,是以此時cpu使用的工作寄存器由第0組改為第1組。使原來第0組工作寄存器的内容能保持不變,起到保護現場的作用。

(3)當程式運作到31~32行之後,psw的值為01h,acc的值為feh,這是通過pop指令取回了psw和a在進入中斷子程式前的值(即原來值),起到恢複現場的作用。

将寫入程式的單片機插入實驗闆插座上,檢查無誤後接通電源,此時将看到亮燈從右向左移動,移到最左端後再從左向右移動,不斷循環。

當按開關k1産生中斷信号時,燈移動循環停止,轉而執行中斷服務程式,8隻led閃爍4次。中斷服務程式結束之後,亮燈再恢複左右移動循環。

在執行個體測試時要仔細觀察,程式從什麼地方發生中斷,将從什麼地方開始恢複。

亮燈從右端向左移動到第3個時,下一個将是第4個位置燈亮,可以在此時按k1按鈕發生中斷,燈開始閃爍,當燈閃爍停止後,亮燈會接着從第4個位置開始向左移動。中斷後程式能準确地從原中斷點開始恢複,主要是因為在中斷服務程式中采用了保護現場和恢複現場的措施。

編寫中斷程式要注意以下幾步。

(1)确定中斷入口位址。

(2)中斷設定,包括開通中斷、确定優先級和觸發方式等,即對4個特殊功能寄存器tcon、scon、ie和ip進行設定。

(3)在中斷處理子程式裡,要有保護現場和恢複現場部分,這是中斷處理子程式與前面講的子程式的不同點。