中斷(Interrupt)是指在計算機運行過程中,出現某些意外情況需主機干預時,機器能自動停止正在運行的程序并轉入處理新情況的程序,處理完畢后又返回原被暫停的程序繼續運行。
定時器/計數器(Timer/Counter)在實時控制系統中,實現對于外界事件的定時延時及計數功能。
串行通信(Serial Communicate)是計算機與外界交換信息的一種基本通信方式。
中斷系統中斷過程中,請求產生中斷的事件稱為中斷源,中斷源向CPU提出的請求為中斷請求(Interrupt Requst,IRQ),CPU通過上下文切換保存好當前的工作狀態后,轉而去處理中斷請求,也就是產生中斷響應。直到處理完中斷請求事件,才返回原來的工作狀態,繼續工作。整個過程如下圖所示:
51單片機中斷系統的結構圖如下:
中斷源51單片機中有5個中斷源,如下表所示:
中斷號 優先級 中斷源 中斷入口地址0 1(最高級) 外部中斷0 0003H
1 2 定時器0 000BH
2 3 外部中斷1 0013H
3 4 定時器1 001BH
4 5(最低級) 串口中斷 0023H
每個中斷源都分配了對應的中斷號及中斷服務入口地址,在這個中斷入口地址里,存放著跳轉到相應中斷服務程序的跳轉指令。當多個中斷源同時向CPU提出中斷請求時,CPU將根據中斷源的優先級來依次響應中斷。
相關寄存器SFR中與中斷有關的寄存器有:
IEIE(Interrupt Enable),中斷允許寄存器,可位尋址,其各位定義如下:
位地址 AFH AEH ADH ACH ABH AAH A9H A8H定義 EA - (ET2) ES ET1 EX1 ET0 EX0
* EA(Enable All):CPU中斷總控制位,EA=1,CPU對所有中斷開放,EA=0,CPU禁止一切中斷響應。
* ES(Enable Serial):串口中斷允許控制位,ES=1,允許串行口接受、發送中斷。
* ET0/ET1(Enable Timer):定時/計數器0/1中斷允許控制位,ET0/ET1=1,允許T0/T1中斷。52系列單片機里還有ET2。
* EX0/EX1(Enable Exterior):外部中斷INT0/INT1中斷允許控制位,EX0/EX1=1,允許外部中斷INT0/INT1中斷。
IP(Interrupt Priority),中斷優先級寄存器,可位尋址,其各位定義如下。未設置時或復位后,IP各位均為”“則按照系統默認的優先級
位地址 BFH BEH BDH BCH BBH BAH B9H B8H定義 - - (PT2) PS PT1 PX1 PT0 PX0
* PS(Priority Serial):串行口優先級設定位,PS=1,串行口為高優先級。
* PT0/PT1(Priority Timer):定時/計數器0/1優先級設定位,PT0/PT1=1,定時/計數器0/1為高優先級。
* PX0/PX1(Priority Exterior):外部中斷INT0/INT1優先級設定位,PX0/PX1=1,外部中斷INT0/INT1為高優先級。
TCON(Timer Control),定時/計數器控制寄存器,可位尋址,其各位定義如下:
位地址 8FH 8EH 8DH 8CH 8BH 8AH 89H 88H定義 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
* TF0/TF1(Timer Flag):定時/計數器0/1溢出標志位,當定時/計數器計滿溢出時,由硬件自動置“1”,并申請中斷;在進入中斷服務程序后,又由硬件自動置“0”。
* TR0/TR1(Timer Run):定時/計數器0/1啟停控制位,TR0/TR1=1,啟動定時/計數器。
* IE0/IE1(Interrupt Exterior):外部中斷INT0/INT1中斷請求標志位,外部中斷源有請求時,對應的標志位IE0/IE1由硬件置“1”,當CPU響應該中斷后,又由硬件自動置“0”。
* IT0/IT1(Interrupt Touch):外部中斷INT0/INT1的觸發方式選擇位,IT0/IT1=0,對應外部中斷設置為低電平觸發方式,IT0/IT1=1,對應外部中斷設置為邊沿觸發方式。
51單片機在CPU的每個機器周期的S5 P2期間,將自動查詢TCON中各個中斷申請標志,若查詢到某個中斷標志位被置位,將啟動中斷機制。
中斷源發出中斷請求后。要使CPU能夠響應中斷,IE中的中斷總允許位EA及對應的中斷允許位(ES/ET/EX)都需要置為“1”。
處理外部中斷時,若外部中斷設為低電平觸發方式,則CPU在每個查詢中斷申請標志時也將對INTi引腳進行采樣,測得INTi=0,則認為有中斷申請,隨即將IEi標志位置位,否則測得INTi=1,則認為無中斷請求,而清除IEi標志位。所以施加在INTi引腳上的低電平持續時間應該大于一個機器周期,且小于中斷服務程序得執行時間。
若外部中斷設為邊沿觸發方式,則CPU在每個查詢中斷申請標志時將對INTi引腳進行采樣,若在連續兩個機器周期采樣到先高后低的電平變化,則認為有中斷申請,隨即將IEi標志位置位,否則測得INTi=1,則認為無中斷請求,而清除IEi標志位。所以,為了保證CPU在兩個機器周期內能夠檢測到由高到低跳變得電平,輸入的高低電平持續時間至少要保持12個振蕩周期(即一個機器周期)時間。
在中斷處理過程中,如果正在執行同級或高優先級的中斷服務程序,或是正在執行的指令還沒完成,則中斷響應會受到阻斷。51單片機的中斷響應時間最短為3個機器周期,其他情況的中斷響應時間一般是3~8個周期。
在CPU響應中斷后,應該撤除該中斷請求,否則會再次產生中斷,進入死循環。
中斷程序的編寫由中斷的處理過程可知,在編寫中斷管理與控制程序時應該考慮一下幾個方面:
* CPU開中斷和關中斷
* 某個中斷源中斷請求的允許或屏蔽
* 各中斷源優先級別的設定
* 外部中斷請求的觸發方式
中斷程序基本編寫格式如下:
匯編:
;中斷入口設置 ORG 0000H ;起始地址 LJMP MAIN ;跳轉到主程序 ORG 0003H ;中斷入口地址1 LJMP INT1 ;跳轉到外部中斷INT0服務程序 ORG 000BH ;中斷入口地址2 LJMP INT2 ;跳轉到定時器0中斷服務程序,沒有則不寫或寫成“RETI”,下同 ORG 0013H ;中斷入口地址3 LJMP INT3 ;跳轉到外部中斷INT1服務程序 ORG 001BH ;中斷入口地址4 LJMP INT4 ;跳轉到定時器1中斷服務程序 ORG 0023H ;中斷入口地址5 LJMP INT5 ;跳轉到串口中斷服務程序 ;主程序 ORG 0030H ;起始地址 MAIN: SETB IT0 ;IT0=1,邊沿觸發 SETB EA ;EA=1,開啟總中斷 SETB EX0 ;EX0=1,允許外部中斷INT0 …… LOOP: NOP LJMP LOOP ;死循環 ;中斷服務程序 ORG 0100H ;起始地址 INT1: PUSH ACC ;保存原來狀態,下同 PUSH PSW ; …… INT2: …… …… POP PSW ;恢復原始狀態,下同 POP ACC ; RETI ;中斷返回 END ;結束C語言:
#include "reg51.h" // 主程序 void main() { IT0 = 1;//注釋同匯編 EX0 = 1; EA = 1; while (1) { …… } } // 中斷處理程序 void int0() interrupt 0 { // 外部中斷INT0服務程序 …… } 定時/計數器51單片機內部有兩個16位可編程的定時/計數器0和1,分別用T0及T1表示。它們的工作方式、定時時間、量程、啟動方式、等均可通過程序來設置和改變。
計數功能用于統計從T0(P3.4)、T1(P3.5)引腳輸入的脈沖負跳變數量,每輸入一個脈沖負跳變,計數器就加1。負跳變指的是一個機器周期采樣為高電平,后一個機器周期采樣為低電平。
定時功能是單片機通過對內部機器脈沖信號計數實現的,計數值乘以機器周期即是相應的時間。如單片機采用12MHz晶振,機器內部脈沖頻率為1MHz,機器周期為1us,計數1000次,即1ms時間。
當計數值溢出后,定時計數器給出中斷請求,進而使CPU去處理中斷事件。
51單片機定時/計數器結構如下:
相關寄存器除前面介紹過的中斷相關寄存器外,SFR中與定時/計數器有關的寄存器有:
TMODTMOD(Timer Mode),定時/計數器模式控制寄存器,不可位尋址,其各位定義如下。其中TMOD的高半字節D4~D7用來控制定時/計數器1,低半字節D0~D3用來控制定時/計數器0。
位號 D7H D6H D5H D4H D3H D2H D1H D0H定義 GATE C\T M1 M0 GATE C\T M1 M0
* GATE:門控制位,用來控制定時/計數器的啟動方式。GATE=1,由外部中斷引腳INT0/INT1來啟動定時器T0/T1, 當INT0/INT1引腳為高電平且TR0/TR1置位,啟動定時器T0/T1;GATE=0,僅由TR0/TR1置位而啟動定時器T0/T1。
* C\T:功能選擇位,C\T=0,為定時模式,計數脈沖由內部提供,計數周期等于機器周期;C\T=1,為計數模式,計數脈沖由外部引腳T0或T1引入。
* M0/M1:工作方式控制位,用于設置定時/計數器的工作方式,如下表:
0 0 方式0 13位計數器
1 0 方式1 16位計數器
0 1 方式2 8位重裝計數器
1 1 方式3 定時器0分為兩個獨立8位計數器
T0、T1
T0、T1(Timer),兩個定時/計時器的初始賦值寄存器,不可位尋址,用于存放定時/計數的初始值。它們是兩個16位寄存器,均可分為兩個獨立的8位寄存器,高8位記為TH,即TH0、TH1,低8位記為TL,即TL0、TL1。使用定時/計數器時,當外部或系統時鐘振蕩器輸入一個脈沖時,對應寄存器的值便自動加1。
編程時需要注意,16位計數初始值要分兩次寫入對應初始值寄存器。
定時/計數過程51單片機定時/計數器的工作模式、工作方式、計數初始值及啟停操作均需要在使用前進行初始化。
首先是通過TMOD中的GATE位來設置定時/計數器T0/T1的啟動操作方式,工作在定時還是計數模式則是通過C/T位來設置。其次就是選擇它們的工作方式。
工作方式0、1、3為非自動重裝方式,在初始化程序和對應中斷服務程序中均需要對初始數據寄存器THi、TLi裝載。方式0是一個13位定時/計數器,只用了16位寄存器的高8位THi和TLi的低5位0~4位,TLi高3位未用,裝入數據時需要注意。方式1為16位寄存器。
方式3只適用于定時/計數器T0,一般在定時/計時器T1作串行口波特率發生器時,才會選擇這個工作模式。此時T0拆分為兩個獨立8位計數寄存器TH0和TL0,其中TL0下為8位定時/計數器,操作方式同方式0、1;TH0只做簡單的內部定時功能,它借用定時/計時器1的控制位TR1和溢出標志位TF1,占用T1的中斷資源,啟動和停止也僅受TR1控制,此時T1僅可用在不需要中斷的場合。
方式2為8位重裝寄方式,僅由TLi作為工作寄存器,THi的值一直保持不變。TLi溢出時,THi的值作為裝載值由CPU自動裝入TLi,自動完成計數值初始化。所以此種方式下需要初始化時在THi和TLi中放入相同的計數值。
T0/T1寄存器中的初值X與定時/計數器的工作方式、工作模式有關。
在工作方式0下,為13位寄存器,也就是說最大的計數值M=213=8192,超過這個數字就會溢出,觸發中斷。工作方式為1下,為16位寄存器,M=216=65536。工作方式為2下,為8位寄存器,M=28=256。工作方式為3下,定時/計數器0分為高8位和低8位兩個獨立8位計數器,THi、TLi的M均為28=256。
不管是進行定時還是計數模式,其具體實現都是歸結于計數。
計數模式下,是對外部脈沖數計數,初值X = M - 計數值。定時模式下,是對機器周期進行計數,初值X = M - 計數值 = M - 定時時間Tc機器周期Tp = M - 定時時間Tc×晶振頻率12。
最后,中斷中的相關寄存器也需要進行設置,設置TRi=1,來啟動定時/計數器。
定時/計數程序編寫通過上面對定時/計數過程的分析,可知編寫想關功能程序時,要先進行初始化,再根據公式計算出定時初值并裝載。
定時/計數程序基本編寫格式如下:
匯編:
;中斷入口設置 ORG 0000H ;起始地址 LJMP MAIN ;跳轉到主程序 ORG 000BH ;中斷入口地址2 LJMP INT2 ;跳轉到定時器0中斷服務程序 ORG 001BH ;中斷入口地址4 LJMP INT4 ;跳轉到定時器1中斷服務程序 ;主程序 ORG 0030H ;起始地址 MAIN: MOV TMOD, #xxH ;設置工作模式,方式 MOV TH0, #xxH ;計數初值,高八位 MOV TL0, #xxH ;低八位 SETB EA ;EA=1 ,開啟總中斷 SETB ET0 ;ET0=1,允許定時/計數器中斷 SETB TR0 ;TR0=1,啟動定時/計數器 …… LOOP: NOP LJMP LOOP ;死循環 ;中斷服務程序 ORG 0100H ;起始地址 INT2: PUSH ACC ;保存原來狀態,下同 PUSH PSW ; MOV TH0, #xxH ;重新賦計數初值(非重裝方式下) MOV TL0, #xxH …… INT4: …… …… POP PSW ;恢復原始狀態,下同 POP ACC ; RETI ;中斷返回 END ;結束C語言:
#include "reg51.h" // 主程序 void main() { TMOD = 0xxx; //注釋同匯編 TH0 = 0xxx; TL0 = 0xxx; EA = 1; ET0 = 1; TR0 = 1; while (1) { …… } } // 中斷處理程序 void int2() interrupt 1{ // 定時器0中斷服務程序 TH0 = 0xxx; TL0 = 0xxx; …… } 串口通信 通信相關概念計算機通信方式可以分為并行(Parallel)與串行(Serial)通信兩大類,它將計算機技術和通信技術的相結合,完成計算機與外部設備或計算機與計算機之間的信息交換:
并行通信:數據的各個二進制位在不同的數據線上同時傳輸。這樣傳輸速度快,效率高,但所需的數據線多,成本高,抗干擾能力較差,適用于近距離傳輸。
串行通信:將數據拆分成多個二進制位,逐一的在同一條數據線上輸出。雖然這樣傳輸速度較慢,效率較低,但所需的數據線少、硬件電路簡單、抗干擾能力強,且適用于遠距離數據傳輸。
串行通信又分為同步(Synchronous)通信和異步(Asynchronous)通信兩種方式:
同步通信:串行連續地傳輸數據,待發送的若干個字符數據構成一個數據塊,在該數據塊前部添加1~2個同步字符,在數據塊的末尾添加校驗信息,以此種方式構成數據幀,以數據幀為單位進行串行通信。
異步通信:每個字符數據被封裝成幀,之后以幀的形式發送。每一幀由四部分構成,分別是起始位、數據位、校驗位和停止位。起始位是數據開始傳送的標志,用邏輯0表示;數據位緊跟起始位,通常是5~8位二進制位;校驗位用于校驗數據位是否發送正確,可以選擇奇校驗、偶校驗或者不使用校驗位。幀和幀之間可以連續,或者加入任意的空閑位,空閑位用邏輯1表示。
串行數據的傳輸制式可分為單工(Simplex)、半雙工(Half Duplex)、全雙工(Full Duplex)。
單工:數據傳輸僅能沿一個方向,不能實現反向傳輸。
半雙工:數據傳輸可以沿兩個方向,但需要分時進行。
全雙工:數據可以同時進行雙向傳輸。
串行通信的錯誤校驗方式有奇偶校驗(Parity Check)、代碼和校驗、循環冗余校驗(Cyclical Redundancy Check,CRC)三種:
奇偶校驗:在發送數據時,數據位尾隨的1位為奇偶校驗位(1或0)。奇校驗時,數據中“1”的個數與校驗位“1”的個數之和應為奇數;偶校驗時,數據中“1”的個數與校驗位“1”的個數之和應為偶數。接收字符時,對“1”的個數進行校驗,若發現不一致,則說明傳輸數據過程中出現了差錯。
代碼和校驗:發送方將所發數據塊求和(或各字節異或),產生一個字節的校驗字符(校驗和)附加到數據塊末尾。接收方接收數據同時對數據塊(除校驗字節外)求和(或各字節異或),將所得的結果與發送方的“校驗和”進行比較,相符則無差錯,否則即認為傳送過程中出現了差錯。
循環冗余校驗:通過某種數學運算實現有效信息與校驗位之間的循環校驗,常用于對磁盤信息的傳輸、存儲區的完整性校驗等。這種校驗方法糾錯能力強,廣泛應用于同步通信中。
波特率(Baud Rate)是串口通信時每秒鐘傳輸二進制代碼的位數,單位是位/秒(bps)。
51單片機的串行接口是一個全雙工通信接口,即能夠同時進行數據發送和接收。它可作通用異步收發傳輸器(Universal Asynchronous Receiver/Transmitter,UART)用,也可以作同步移位寄存器。其結構如下:
相關寄存器除前面介紹過的中斷及定時/計數器相關寄存器外,SFR中與串口通信相關的寄存器有:
SCONSCON(Serial Control),串行口控制寄存器,可位尋址,其各位定義如下:
位地址 9FH 9EH 9DH 9CH 9BH 9AH 99H 98H定義 SM0 SM1 SM2 REN TB8 RB8 TI RI
* SM0和SM1(Serial Mode):串行口工作方式控制位,用于設置串行口工作方式,如下表:
SM0 SM1 工作方式 功能 波特率0 0 方式0 8位同步移位寄存器 晶振頻率/12
0 1 方式1 10位UART 可變
1 0 方式2 11位UART 晶振頻率/64 或 /32
1 1 方式3 11位UART 可變
* SM2:多機通訊控制位,主要在以上工作方式為2或3下使用,工作方式0或1下都應該設為“0”狀態。
* REN(Receive Enable):串行允許接收位,REN=1,允許接受數據。
* TB8(Transfer Bit 8):工作方式為2或3下存放發送數據的第9位,由軟件置”0”或”1”。
* RB8(Receive Bit 8):工作方式為2或3下存放接受數據的第9位。方式0下不使用;方式1下,當SM2=0時,用于存放接收到的停止位。
* TI(Transfer Interrupt):發送中斷標志位,用于指示一幀數據是否發送完成。使用前必須軟件復位為“0”,發送完一幀數據后硬件將自動置”1”。
* RI(Receive Interrupt):接受中斷標志位,用于指示一幀數據是否接受完成。接受完一幀數據后硬件將自動置”1”,之后必須軟件復位為“0”。
SBUF(Serial Data Buffer),串行數據緩沖器,不可位尋址。串行口兩個SBUF,分別為發送寄存器和接收寄存器,它們在物理結構上是完全獨立的,在SFR中的字節地址都是99H。這個重疊的地址靠讀/寫指令區分:串行發送時,CPU向SBUF寫入數據,此時99H表示發送SBUF;串行接收時,CPU從SBUF讀出數據,此時99H表示接收SBUF。
PCONPCON(Power Control),電源控制寄存器,不可位尋址,其中只有一位與串口設置有關,其余都用于電源控制。其各位定義如下:
位號 D7H D6H D5H D4H D3H D2H D1H D0H定義 SMOD - - - GF1 GF0 PD IDL
* SMOD(Serial Mode):波特率選擇位。工作方式1、2、3下串行通信波特率與2SMOD成正比。也就是SMOD=1,通信波特率可提高一倍。
* GF0/GF1(General Flag):通用標志位,用戶可自由使用
* PD(Power Down):掉電控制位。PD=0,單片機正常工作;PD=1,進入掉電模式,外部晶振停振,CPU、定時器、串行口全部停止工作,只有外部中斷工作。在該模式下,只有硬件復位和上電能夠喚醒單片機。
* IDL(Idle):空閑控制位。IDL=0,單片機正常工作;IDL=1,單片機進入空閑模式,除CPU不工作外,其余仍繼續工作,在空閑模式下可由任一個中斷或硬件復位喚醒。
一般情況下,當CPU允許接收(REN=1)且接收中斷標志RI復位時,就啟動一次接收過程。外界數據通過引腳RXD(P3.0)串行輸入,數據最低位首先輸入一個大小為9位移位寄存器,當一幀數據接收完畢后再并行送入接收SBUF中,同時RI也置“1”。當用軟件讀取完數據并復位RI后,才進行下一次操作。
當發送中斷標志TI復位后,CPU便開始執行一條寫SBUF指令,啟動一次發送過程,發送控制器同時啟動,并開始發送數據。發送的數據通過引腳TXD(P3.1)輸出,首先輸出最低位。當一幀數據發送完畢即發送SBUF為空時,CPU自動將TI值“1”。使用軟件將TI復位,才執行下一個發送過程。
51單片機串行口有4種工作方式,通過SCON寄存器中的SM0、SM1口選擇。
方式0下,串行口為同步移位寄存器的輸入輸出方式,主要用于和外部同步移位寄存器外接,以達到擴展一個并行輸入或輸出口的目的。這種方式下,數據從RXD端串行輸入或輸出,同步移位信號從TXD輸出,波特率固定為晶振頻率的1/12。TXD引腳每輸出一位同步移位脈沖,數據就由RXD引腳輸入或輸出一個二進制位,發送和接收均為8位數據,低位在先,高位在后,沒有起始位和停止位。此時,SM2、RB8、TB8均設為“0”,不起作用。方式0工作時序圖如下:
方式1下,串行口為10位異步通信方式,即1個起始位、8個有效數據位和1個停止位,波特率由定時/計數器T1溢出率及PCON中的SMOD位共同決定。進行發送操作時,發送電路會自動在8位發送數據前后分別加上一位起始位和一位停止位。接收操作時,接收器以所選擇波特率的16倍速率采樣RXD引腳電平,檢測負跳變時,則說明起始位有效,將其移入輸入移位寄存器,并開始接收這一幀信息的其余位。接收過程中,數據從輸入移位寄存器右邊移入,起始位移至輸入移位寄存器最左邊時,控制電路進行最后一次移位,隨后將接收到的9位數據的前8位數據裝入接收SBUF,第9位(停止位)進入RB8,并置RI=1,向CPU申請中斷。如果上述條件不滿足,數據則會被舍棄。此時,SM2也要設為“0”。方式1工作時序圖如下:
方式2及方式3下,串行口都為11為異步收發方式,即1個起始位、8個有效數據位、1個附加數據位和1個停止位,其兩者的差異在于通信波特率的不同:方式2的波特率取決于晶振頻率和PCON中的SMOD位,固定為晶振頻率的1/64或1/32;方式3的波特率由定時器T1的溢出率和SMOD位共同決定,故其波特率是可調的。比方式1多出來的一個附加位發送時為SCON中的TB8,接收時為RB8,由用戶安排,可作奇偶校驗位,也可作其他控制位。這兩種方式很適合主從式的通信結構,在多機通訊時,主機的SM2位設為“0”,而從機的SM2位設為“1”,以便之間相互識別。
方式0下:
波特率=晶振頻率fosc12
方式2下:
波特率=2SMOD64?fosc
方式1下及方式3下,波特率都由定時/計數器T1溢出率及PCON中的SMOD位共同決定。T1的溢出率又取決于計數速率和計數值。定時模式下,計數速率為晶振頻率的1/12;計數模式下,計數速率取決于外部輸入時鐘頻率,但不可超過晶振頻率的1/24。作波特率發生器時,T1通常設置為定時模式,工作在工作方式2下,作8位重裝寄存器,此時波特率計算公式為:
T1溢出周期=定時時間=12f_osc?(256?計數初值X)
T1溢出率=1T1溢出周期
波特率=2SMOD32?T1溢出率=2SMOD?f_osc384?(256?X)
則T1的計數初值,也就是裝載值為:
計數初值X=256?2SMOD?f_osc384?波特率
串行通信程序編寫由串行通信的基本過程可知,在使用串行口之前需要對串行口進行初始化,確定使用的工作方式并進行相關配置。
串行通信程序基本編寫格式如下:
匯編:
;中斷入口設置 ORG 0000H ;起始地址 LJMP MAIN ;跳轉到主程序 ORG 0023H ;中斷入口地址5 LJMP INT5 ;跳轉到串口中斷服務程序 ;主程序 ORG 0030H ;起始地址 MAIN: MOV TMOD, #20H ;設置定時/計數器T1工作模式為定時,工作方式2 MOV TH1, #F4H ;計數初值,高八位,波特率2400 MOV TL1, #F4H ;低八位 MOV SCON, #90H ;設置串行口工作方式2,單機,允許接收 MOV PCON, #00H ;波特率不加倍 SETB EA ;EA=1 ,開啟總中斷 SETB ES ;ES=1,開啟串口中斷 SETB TR1 ;TR1=1,啟動定時/計數器 …… SEND: MOV A, #xxH ;待發送數據放入A,即刻生成了偶校驗位放在P中 MOV C, P ;將偶校驗位放入位寄存器C CPL C ;奇校驗則把P取反 MOV TB8, C ;將校驗位放入TB8中 MOV SUBF, A ;發送數據 JBC TI, xxx ;發送完一幀數據后清除TI并進行下一步 LOOP: NOP LJMP LOOP ;死循環 ;中斷服務程序 ORG 0100H ;起始地址 INT5: MOV A, SBUF ;取出接收到的數據 JB RB8, ERR ;進行校驗,不同則跳轉到錯誤處理 CLR RI ;復位,準備下次接收 …… RETI ;中斷返回 ERR: …… …… END ;結束C語言:
#include "reg51.h" // 主程序 void main() { TMOD = 0x20H; //注釋同匯編 TH0 = 0xF4; TL0 = 0xF4; SCON = 0x90; PCON = 0x00; EA = 1; ES = 1; TR1 = 1; while (1) { send(data); } } //發送數據 void send(unsigned char data) { ACC = data; TB8 = P; SBUF = data; while(!TI == 0){ …… TI = 0; } } // 中斷處理程序,接收數據 void int5() interrupt 5{ // 定時器0中斷服務程序 ACC = SBUF; RI = 0; if (RB8 == p){ …… }else{ …… } }更新歷史:
* 2017.11.27 完成初稿
原文鏈接
評論
查看更多