鄭毛祥
(武漢鐵路職業技術學院 湖北 武漢 430205)
在單片機的串行異步通信中,實現波特率設置的方法有很多種,但是有些方法要么需要額外的硬件支持,要么實現算法過于復雜,占用單片機的大量資源,而且研究通信波特率高的情況比較多,但對如何適應波特率較低的情況研究較少,這就大大降低單片機通信應用范圍。文中研究并實現了一種簡單實用的方法,不需要額外的硬件支持,對單片機的波特率有效設置的方法,并且軟件開銷也非常小。
MCS-51串行通信接口可以作通用異步接收和發送器(UART)使用,也可以作同步移位寄存器用。在異步通信中,傳送的數據以幀的形式一幀一幀傳送的,數據可以是一個字符代碼或一個字節數據。一幀數據由4個部分組成:起始位、數據位、奇偶校驗位和停止位。異步通信起始位用“0”表示數據傳送的開始,然后從數據低位到高位逐位傳送數據,接下來是奇偶校驗位(可以省略不用),最后為停止位,用“1”表示一幀數據結束。起始位信號只占用一位,用來通知接收設備一個待接收的數據開始到達,線路上在不傳送數據時,保持為1。接收端不斷檢測線路的狀態。若在連續收到1以后,又收到一個0,就知道發來一個新數據,開始接收。數據位一般情況下是 8位(D0~D7)。 奇偶校驗位(D8)只占用一位,在數據傳送中也可以規定不用奇偶校驗位,這一位可以省去,或者把它用作地址/數據幀標志,來確定這一幀中的數據所代表信息的性質,如規定D8=1表示該幀信息傳送的是地址,D8=0表示傳送的是數據。停止位用來表示一個傳送字符的結束,它一定是高電平,停止位可以是1位、1.5位或2位,接收端接收到停止位后,就知道這一字符已傳送完畢。兩幀信息之間可以無間隔,也可以有間隔,且間隔時間可以任意改變,間隔用空閑位“1”來填充。
MCS-51單片機的串行口電路結構如圖1所示[1]。

圖1 MCS-51單片機串行口結構示意圖Fig.1 MCS-51 MCUserial port structure diagram
8051通過引腳RXD(串行數據接收端)和引腳TXD(串行數據發送端)與外界進行通信。單片機內部的全雙工串行接口部分,包含有串行發送緩沖器和接收緩沖器,兩個物理上獨立的緩沖器。發送緩沖器CPU只能寫入發送的數據,但不能讀出;接收緩沖器CPU只能讀出接收的數據,但不能寫入。因此,串行口可同時收、發數據,實現全雙工傳送。串行口發送和接收緩沖器的名稱都是特殊功能寄存器SBUF(一個是接收SBUF,一個是發送SBUF),它們共用一個地址 99H。CPU若向外發送一個數據,只要執行一條寫傳送數據指令(如MOV SBUF,A)。若要接收一個外部傳來的數據,只要執行一條讀數據傳送指令(如MOV A,SBUF)。
8051串行口是可編程接口,對它初始化編程主要是對串行口控制寄存器SCON(98H)的設置,包含串行口工作方式選擇位、接收和發送控制位以及串行口狀態標志位,其格式如圖2所示。

圖2 串行口控制寄存器SCONFig.2 Serial port control register SCON
SM0、SM1:串行口工作方式選擇位,8051串行口可設置方式0、方式1、方式2、方式3共4種工作方式。
SM2:多機通信控制位,雙機通信時,SM2=0,多機通信時,SM2=1。
REN:允許串行接收位。由軟件置1允許接收數據,置0禁止接收數據。
TB8:是在方式2和方式3中發送的附加位數據。根據發送數據的需要由軟件置位或復位。可作奇偶校驗位,也可在多機通信中作區別地址幀或數據幀的標志位。在方式0、方式1中該位未用。
RB8:是在方式2和方式3中接收的附加位數據。可作約定的奇偶校驗位,或是約定的地址/數據的標志位。在方式1中,若SM2=0,RB8中存放的是已接收到的停止位。方式0不使用 RB8。
TI:發送中斷請求標志位。在方式0中,串行發送第8位結束時,由硬件置位TI;在其他3種方式中,串行發送停止位開始時,由硬件置位TI。TI=1表示一幀數據發送完畢。可由軟件查詢TI的狀態,TI為1時,向CPU申請中斷,CPU響應中斷,TI標志必須由軟件清零,才能再發送下一幀數據。
RI:接收中斷標志位。在方式0中,串行接收到第8位數據時,由硬件置位RI;在其他3種方式中,串行接收到停止位時,硬件置位RI。RI=1表示一幀數據接收結束。可由軟件查詢RI的狀態,RI為1時,向CPU申請中斷,CPU響應中斷,RI必須由軟件清零,準備接收下一幀信息。
發送中斷和接收中斷是同一中斷服務程序入口地址(0023H),所以在全雙工通信時,必須由軟件查詢是發送中斷TI=1,還是接收中斷RI=1。
方式0以8位數據為一幀,不設起始位、停止位和奇偶校驗位,如圖3(a)。先發送或接收低位。工作方式0為同步移位寄存器輸入/輸出方式。常用于串行口外接移位寄存器以擴展I/O口,也可以外接串行同步輸入/輸出設備,不能用于單片機之間的通信。方式1為8位數據異步通信接口。傳送一幀信息為10位。包括1位起始位(0)、8位數據位(先低位,后高位)和1位停止位(1),如圖3(b)。方式2和方式 3為9位數據異步通信接口。傳送一幀信息為11位,包括1位起始位(0),8位數據位(先低位,后高位),1位附加可編程控制位,1 位停止位(1),如圖 3 (c)所示。

圖3 數據幀格式Fig.3 Data frame format
方式1與方式3發送和接收數據時的波特率相同,波特率是由內部定時器T1送來的溢出信號經過16或32分頻(取決于SMOD位,SMOD是電源控制寄存器PCON的最高位,當SMOD=1時,使串行口波特率加倍。)而得到的,波特率為=2SMOD/32×T1溢出率。波特率是可變的。
方式 2波特率=2SMOD/64×fosc,只有 2種:fosc/64或 fosc/32(取決于SMOD的值)。
顯然,波特率可以靈活改變的只有方式1和方式3,定時器T1作為可變的波特率發生器,T1工作方式有3種,可以工作在方式0(13位定時方式)、方式1(16位定時方式)和方式2(8位自動重裝定時初值)。一般情況下,為了不影響波特率的精度,選用定時器工作方式2,且禁止T1中斷定(ET1=0),以免T1溢出時產生不必要的中斷。設定時器T1的初值為X,計數器長度為 L(取13、16和8)每過 2L-X個計數周期,T1就會產生一次溢出。溢出周期為:12/fosc(2L-X)。T1的溢出率為溢出周期的倒數,則


圖4 波特率隨初值X的變化Fig.4 Baud rate with initial X changes
從圖4可以看出,如果串行通信選用較低的波特率時,將定時器T1設置定時方式1(16位計數)最好控制,X值的變化對波特率引影比較接近線性關系,變化比較平坦,易于對波特率的設置與微調。其次是方式0(13位計數),最后才是方式2。但在選用方式0或方式1的情況下,T1溢出時需由中斷服務程序來重裝計數初值,而且應該允許T1中斷(ET1=1)。中斷響應和中斷處理的時間雖然會對波特率的精度帶來一點誤差,但也是可以根據指令執行周期進行校正克服的。
單片機之間的通信,可以利用其串行通信口,構成雙機通信和多機通信系統。串行口控制寄存器SCON中的SM2為多機通信控制位[2]。

圖5 主從式多機通信Fig.5 Master slave multi MCUs communication
雙機通信時,在方式1處于接收狀態時,SM2置為0,則接收到有效的停止位(高電平 1)時,才會激活 RI(即RI置1);在方式2和方式 3處于接收狀態時,SM2置為0,則接收到第 9 位數據(RB8)=1 后,RI置 1。
多機通信,只有工作方式2和工作方式3,主機SM2置為0,由主機發起通信,當從機SM2置為1時,從機接收到第9位數據(RB8)=1后,RI才置 1;當從機 SM2置為 0時,則接收到第 9位數據(RB8)為0或1時,RI都置1。
1)雙機通信數據傳輸
方式1發送數據時,數據從TXD端輸出。只要執行把8位數據寫入發送緩沖器SBUF命令,便啟動串行口發送器發送。啟動發送后,串行口能自動地在數據的前后分別插入1位起始位(0)和 1位停止位(1),以構成一幀信息,依次由TXD端上發出。在一幀數據發出之后,也就是在停止位輸出時,使TI置1,用以通知CPU可以發送下一個數據。當一幀信息發完之后,自動保持TXD端的信號為1。接收數據時,數據從RXD端輸入。在REN置“1”,允許接收器接收的前提下,在沒有信號到來時,RXD端狀態為1,當檢測到有由1到0的變化時,就確認是一幀信息的起始位(0),便開始接收這一幀數據。把收到的數據一位一位地移入接收移位寄存器中,直到一幀數據全部接收完畢(包括1位停止位)。在RI=0并且SM2=0時,前8位數據裝入SBUF中,置中斷標志RI為1。如果不滿足這兩個條件,將丟棄接收到的信息,并不置位RI。
方式2和方式3的接收和發送操作完全一樣,只是波特率設置不同。方式2(或方式3)發送數據時,數據由TXD端輸出,發送一幀信息為11位,附加位數據D8是SCON中的TB8(可作奇偶校驗位或地址/數據標志位,發送前根據通信協議由軟件設置),CPU執行一條數據寫入發送緩沖器SBUF的指令,就啟動發送器發送,發送完一幀信息,置中斷標志TI為1,發送過程和方式1相同。接收數據時,數據從RXD端輸入。方式2(或方式3)在SCON中的REN=1,允許接收時,接收器開始采樣RXD電平。當檢測到RXD端有1到0變化時,啟動接收器接收,把接收到的9位數據逐位移入移位寄存器中(含附加位),接收完一幀信息后,在RI=0并且SM2=0時,前8位數據裝入SBUF中,附加位數據D8裝入SCON中的RB8,置中斷標志RI為1。如果不滿足這兩個條件,將丟棄接收到的信息,并不置位RI。
2)多機通信數據傳輸
圖5所示為MCS-51多機通信系統的連接示意圖。系統中只有一個主機,有多個從機。主機發送的信息可傳到各個從機或指定的從機,而各個從機發送的信息只能被主機接收。
當串行口以方式2(或方式3)接收數據時,SM2=1,則僅當接收器接收到的附加位RB8=1時,本幀數據才裝入接收緩沖器SBUF,且置RI為1,向CPU發出中斷請求信號;若RB8=0,則不產生中斷請求信號,數據將丟失。而SM2=0時,則接收到一個數據字節后,不管RB8=0或RB8=1,都產生中斷請求信號RI,接收數據裝入SBUF中。應用這一特性,便可實現多個MCS-51單片機之間的串行通信。
在多機通信時,主機發送的信息有兩類,即地址和數據。地址是需要和主機通信的從機地址。例如,將圖5中3個從機的地址分別定義為00H,01H,02H。主機和從機串行口工作在方式2(或方式3),即9位異步通信方式。主機發送的是地址信息時特征是D8=1,而發送的是數據信息時特征是D8=0。對于從機就要利用SM2位的功能來確認主機是否在呼叫自己,及數據傳送。從機處于接收時,置SM2=1,然后依據接收到的串行數據的附加位的值來決定是否接收主機信號,多機通信實現過程如下。
首先定義從機地址,由系統初始化程序(或相關處理程序)將從機串行口編程為方式2或方式3接收(9位異步通訊方式),然后置從機SM2=1,REN=1,允許串行口中斷。
①主機首先將要通信的從機地址發出,發地址時D8=1,所有從機都接收。
② 從機串行口接收D8=1時,則置位中斷標志RI,各從機CPU分別響應中斷。
③各從機執行中斷服務程序,以判斷主機送來的地址是否與本機地址相符。若與本機地址相符,則SM2清零,準備和主機通信;若地址不一致,則保持SM2=1。
④ 主機發送數據(附加位為0)。
⑤ 從機接收到D8=0的信息幀(表示數據),只有SM2=0的從機才激活中斷標志RI=1,轉入中斷程序,表示接收主機的數據或命令,實現主機與從機的信息傳送。而其他從機因SM2=1,附加位為0,不激活RI中斷標志,接收的信息自動丟失不作處理,從而實現主機和從機的一對一通信。
⑥從機在通信完成后,重新使SM2置1,并退出中斷服務程序,等待下次通信。
用定時器T1,定時器T1工作在方式1(16位計數方式)作為波特率發生器,由設定的波特率得到的此時的初裝值為XXH,將主機中的數據塊(數據塊長度放在R7中)傳送到從機。
主機程序:
DATA_BUF EQU 40H;數據存放區首地址
SLAVE_ADDR EQU 30H;從機地址
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP INT_T1
ORG 0050H
MAIN:MOV TMOD,#10H;定時器T1初始化,工作方式1
MOV TH1,#0XXH
MOV TL1,#0XXH
MOV SCON,#0D0H ;串口工作在方式3,多機位值 SM2=0,允許接受
SETB TB8,#1 ;發送地址標志
SETB TR1 ;啟動定時器1
SETB IT1
SETB ES
SETB EA
MOV A,SLAVE_ADDR;發送從機地址
MOV SBUF,A
JNB TI,$
CLR TI
MOV TB8,#0 ;發送數據標志
MOV R0,#DATA_BUF
HERE: MOV SBUF,@R0;發送數據
JNB TI,$
CLR TI
DJNZ R7,HERE
SETB TB8
MOV SBUF,A SJMP$
INT_T1:MOV TH1,#0XXH
MOV TL1,#0XXH
RETI
END
從機程序:
FLAG BIT 2AH ;數據傳送標志
ADDR_ACK EQU 1AH
DATA_BUF EQU 40H
TEMP_BUF EQU 31H ;數據暫存器
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP INT_T1
ORG 0023H
AJMP HANDLEDATA
ORG 0050H
MAIN:MOV TMOD,#10H;定時器T1初始化,工作方式1
MOV TH1,#0XXH
MOV TL1,#0XXH
MOV SCON,#0F0H;串口工作在方式3,多機位SM2=1,允許接收
CLR FLAG
SETB TR1 ;啟動定時器T1
SETB IT1
SETB EA
AJMP$
HANDLE_DATA:CLR RI
MOV A,SBUF
MOV TEMP_BUF,A
SEND:JNB RB8,DATA_RECEIVE
CJNE ADDR_ACK,TEM_BUF, XXXX
JB FLAG OVER
SETB FLAG
CLR SM2
RETI
OVER:SETB SM2
CLR FLAG
RETI
DATA_RECEIVE:MOV DATA_BUF,TEMP_BUF
INC DATA_BUF
XXXX:RETI
INT_T1:MOV TH1,#0XXH
MOV TL1,#0XXH
RETI
END
在進行上述多機通信時,要先運行從機中的接收程序,再運行主機中的發送程序。
簡要闡述了單片機[7-8]通信方式及串行接口的原理,并通過實例介紹了單片機串行多機通信頻率可調的實現方法,經過實驗驗證,文中所提出的波特率可調方法具有簡單、準確、調節范圍廣的特點。可以應用于幾乎所有的具有波特率的串行通信系統中,滿足多種特定環境通信速率的不同要求。
[1]鄭毛祥.單片機基礎[M].2版.北京:人民郵電出版社,2009.
[2]李云鶴,武善玉.基于ISP的簡約型51單片機實驗板的設計[J].微計算機信息,2008,5(2):95-97.LI Yun-he,WU Shan-yu.Based on ISP compact 51 MCU experimental board design[J].Microcomputer Information,2008,5(2):95-97.
[3]李曉鵬,王民.單片機串行通信自適應波特率的一種簡單實現算法[J].現代計算機,2010(10):90-93 LI Xiao-peng,WANG Min.MCU serial communication baud rate of a simple adaptive algorithm[J].Modern Computer,2010(10):90-93.
[4]洪沙.陽翰凌·單片機多機通信中從機串口中斷服務程序設計[J].微機應用,2008(12):153-155.HONG Sha,YANG Han-ling.The single-chip microcomputer communication from the machine serial port interrupt service program design[J].Microcomputer Application,2008 (12):153-155.
[5]潘策,陳曉南,楊培林.PC機與單片機串行通信的硬件設計[J].現代電子技術,2003(15):4-8.PAN Ce,CHEN Xiao-nan,YANG Pei-lin.PC machine serial communication with the MCU hardware design[J].Modern Electronic Technology,2003(15):4-8.
[6]彭宗乾.MCS-51單片機多機通信的組成原理及通信程序[J].通迅與電視,1992(2):20-22.PENG Zong-qian.MCS-51 MCU communication principle and communication program[J].Communication and Television,1992(2):20-22.
[7]孫俊,王京梅,李莉,等.基于單片機的串聯鋰離子電池組監測系統設計[J].電子科技,2011(10):4-6.SUN Jun,WANG Jing-mei,LI Li,et al.Design of supervising and measuring system of serial lithium-ion batteries based on MCU[J].Electronic Science and Technology,2011(10):4-6.
[8]吳汶泰,扈維,林勝潔.分布式單片機網絡中CSMA的軟件設計與性能分析[J].電子科技,2009(7):93-95.WU Wen-tai,HU Wei,LIN Sheng-jie.Software design of CSMA in the distributed SCM Network and its performance analysis[J].Electronic Science and Technology,2009(7):93-95.