2.2 RS-485
RS-485標準接口是單片機系統種常用的一種串行總線之一。RS-485通信方式RS-485標準是由EIA(電子工業協會)和TIA(通訊工業協會)共同制訂和開發的。RS-485作為一種多點差分數據傳輸的電氣規范,已成為業界最廣泛應用的標準通信接口之一。理論上,RS-485標準最多接入32個設備(受芯片驅動能力的影響),可以工作在半雙工或全雙工模式下,最大傳輸距離約為1219米,最大傳輸速率約為10Mbps[1]。然而通常RS-485網絡采用平衡雙絞線作為傳輸媒體,平衡雙絞線的長度與傳輸速率成反比,只有在20Kbps的傳輸速率下,才可能達到最大傳輸距離。一般15米長的雙絞線最大傳輸速率僅為1Mbps。不過對于速率要求不是很高的控制系統來說已經足夠了。
RS-485采用平衡發送和差分接收方式來實現通信:在發送端TXD將串行口的TTL電平信號轉換成差分信號A、B兩路輸出,經傳輸后在接收端將差分信號還原成TTL電平信號。兩條傳輸線通常使用雙絞線,又是差分傳輸,因此有極強的抗共模干擾的能力,接收靈敏度也相當高。同時,最大傳輸速率和最大傳輸距離也大大提高。如果以10Kbps速率傳輸數據時傳輸距離可達12m,而用100Kbps時傳輸距離可達1.2km。如果降低波特率,傳輸距離還可進一步提高。另外RS-485實現了多點互連,最多可達256臺驅動器和256臺接收器,非常便于多器件的連接。不僅可以實現半雙工通信,而且可以實現全雙工通信。
2.3 多機通信原理
在多機通信中,每臺從機均分配有一個從機地址,主機與從機之間進行串行通信時,通常是主機先呼叫某從機地址,喚醒被叫從機后,主、從兩機之間進行數據交換。而未被呼叫的從機則繼續進行各自的工作。可是,如果在主機與某被呼叫從機進行數據交換過程中,其他從機如果不采取相應的數據識別技術,則這些從機就會因為串行通信線上有數據傳輸而時時被打斷,影響正常的工作。利用單片機的串口工作方式2、方式3可以很好解決上述問題。在多機通信過程中,從機首先要解決的是如何識別主機發送的是地址信息還是數據信息。當發送的是地址信息時,各從機都響應串口中斷,接收主機下發的一幀地址數據。而當主機發送數據幀時,無關從機可不響應串口中斷。解決的方法是:當主機發送一幀地址信息時,應保持這幀數據的第9位為1(即TB8=1)。從機按照工作方式2或工作方式3運行時,將串口寄存器SCON中的控制位SM2置為1,當所接收的一幀數據的第9位為1,所有從機都產生串口中斷,接收這一幀地址數據并與各自的從機地址進行比較,以判斷主機是否要與本機通信。接收到的地址數據與從機地址相等達到為被呼叫從機,該從機將串口控制寄存器SCON中的控制位SM2清為0, 去接收主機發送來的數據幀(數據幀的第9位為0),此時不管接收到的第9位數據是否為1或0,都要產生串口中斷,這就保證了主機與被呼叫從機間的正常數據通信。數據通信結束后,該從機又重新將串行口控制寄存器SCON中的控制位SM2置為1,為下一次與主機進行通信做好準備。其他從機則一直在SM2=1下繼續自己的工作,不會因為主、從機之間的數據通信而被打斷。
多機通信的實現,主要靠主、從機正確地設置與判斷多機通信控制位SM2和發送或接收的第9位數據(TB8或RB8)。當主機給從機發送信息時,要根據發送信息的性質來設置TB8,發送地址信號時,設置TB8=1;發送數據或命令時,設置TB8=0。當從機的SM2為1時,該從機只接收地址幀(RB8位為1),對數據幀(RB8位為0)將不予理睬。而當SM2為0時,該從機接收所有發送來的信息。多機通信過程如下:(1) 使所有從機的SM2置1,處于只接收地址幀的狀態(即從機復位);
(2) 主機發送一地址幀信息,其中包含8位地址,第9位為地址、數據標志位,第9
位置1表示發送的是地址;
(3) 從機接收到地址幀后,各自中斷CPU,把接收到的地址與本地址作比較; (4) 地址相符的從機,使SM2清零以接收主機隨后發來的所有信息,對于地址不相符
的從機,仍保持SM2=1狀態,對主機隨后發送的數據不予理睬,直到主機發送來新的地址幀;
(5) 主機發送數據或控制信息給被尋址的從機;
(6) 被尋址的從機,因SM2=0,可以接收主機發送過來的所有數據,當從機接收數據
結束時,置位SM2,返回接收地址幀狀態(復位狀態);
(7) 當主機改為與另外從機聯系時,可再發地址幀尋址其從機,而先前被尋址過的從
機恢復SM2=1
第4章 系統問題及其解決
4.1 通信規則
由于MAX485通訊是一種半雙工通訊,發送和接收共用同一物理信道。在任意時刻只允許一臺單機處于發送狀態。因此要求應答的單機必須在偵聽到總線上呼叫信號已經發送完畢,并且沒有其它單機發出應答信號的情況下,才能應答。半雙工通訊對主機和從機的發送和接收時序有嚴格的要求。如果在時序上配合不好,就會發生總線沖突,使整個系統的通訊癱瘓,無法正常工作。要做到總線上的設備在時序上的嚴格配合,必須要遵從以下幾項原則: (1) 復位時,主從機都應該處于接收狀態。
MAX485芯片的發送和接收功能轉換是由芯片的 RE* ,DE端控制的。RE*=1,DE=1時,MAX485發送狀態;RE*=0,DE=0時,MAX485處于接收狀態。一般使用單片機的一根口線連接RE*,DE端。在上電復位時,由于硬件電路穩定需要一定的時間,并且單片機各端口復位后處于高電平狀態,這樣就會使總線上各個分機處于發送狀態,加上上電時各電路的不穩定,可能向總線發送信息。因此,如果用一根口線作發送和接收控制信號,應該將口線反向后接入MAX485的控制端,使上電時MAX485處于接收狀態。 另外,在主從機軟件上也應附加若干處理措施,如:上電時或正式通訊之前,對串行口做幾次空操作,清除端口的非法數據和命令。
(2) 控制端RE*,DE的信號的有效脈寬應該大于發送或接收一幀信號的寬度。 在全雙工通訊過程中,發送和接收信號分別在不同的物理鏈路上傳輸,發送端始終為發送端,接收端始終為接收端,不存在發送、接收控制信號切換問題。在RS-485半雙工通訊中,由于MAX485的發送和接收都由同一器件完成,并且發送和接收使用同一物理鏈路,必須對控制信號進行切換。控制信號何時為高電平,何時為低電平,一般以單片機的TXC(發送完成標記),RXC(接收完成標記)信號作參考。
發送時,檢測TXC是否建立起來,當TXC為高電平后關閉發送功能轉為接收功能; 接收時,檢測RXC是否建立起來,當RXC為高電平后,接收完畢,又可以轉為發送。 在理論上雖然行得通,但在實際聯調中卻出現傳輸數據時對時錯的現象。根據查證有關資料,并借助示波器反復測試,才發現一個值得注意的問題,我們可以查看單片機的時序:
單片機在串行口發送數據時,只要將8位數據位傳送完畢,TXC標志即建立,但此時應發送的第九位數據位(若發送地址幀時)和停止位尚未發出。如果在這是關閉發送控制,勢必造成發送幀數據不完整。如果單片機多機通訊采用較高的波特率,幾條操作指令的延時就可能超過2位(或1位)數據的發送時間,問題或許不會出現。但是如果采用較低波特率,如9600,發送一位數據需104μs左右,單靠幾條操作指令的延時遠遠不夠,問題就明顯地暴露出來。接收數據時也同樣如此,單片機在接收完8個數據位后就建立起RXC信號,但此時還未接收到第九位數據位(若接收地址幀時)和停止位。所以,接收端必須延時大于2位數據位的時間(1位數據位時間=1/波特率),再作應答,否則會發生總線沖突。
(3) 總線上所連接的各單機的發送控制信號在時序上完全隔開。
為了保證發送和接收信號的完整和正確,避免總線上信號的碰撞,對總線的使用權必須進行分配才能避免競爭,連接到總線上的單機,其發送控制信號在時間上要完全隔離。
總之,發送和接收控制信號應該足夠寬,以保證完整地接收一幀數據,任意兩個單機的發送控制信號在時間上完全分開,避免總線爭端。
第5章 軟件設計
5.1 系統結構
該多機通信系統的系統結構圖如圖5-1所示,系統采用半雙工主從通信方式,主機可以讀取從機的數據或寫數據到從機,并將數據送終端進行顯示;從機主要負責對分布的電子設備進行監測或控制,用中斷的方式接收主機發來的命令并做出回應。
5.2 通信協議 5.2.1 信息格式
該協議的信息格式如下:
(1)編碼格式;二進制代碼。
(2)波特率:9600 b/s。
(3)通信方式:半雙工。
(4)每個字符由u 位組成; 1位:起始位(0); 8位:數據位;1位:地址/數據識別位(1為地址,o為數據); l位:停止位(1)。
(5) 字符發送順序;低位在先
(6) 幀結束標志:通信線路空閑3.5 ms以上
(7) 幀校驗方式:數據和(2字節)
(8) 主機詢問的一般格式見表5-2:
表5-2 主機詢問的一般格式
從機地址碼:兩字節二進制數,后一字節是前一字節的反碼。 命令碼:一字節二進制數,O1H代表主機讀,02H代表主機寫。 數據個數:表示主機要讀寫的字節個數,一字節二進制數。
校驗和:兩字節二進制數,是將從機地址碼、命令和數據按字節從頭依次相加,生成兩字節的校驗和。 從機應答的一般格式(如表5-3)
表5-3 從機應答的一般格式
圖中信息段的定義同圖2
5.2.2 定時與重發
本通信協議定時規定如下:
(1)幀發送時限;70 ms.超過此時限結束發送。
(2)主機等待從機應答時限:7 ms,超過此時限,酌情重發。 (3)主機重發次數:不超過4次,超過后,判通信失敗。
5.2.3 通信過程
一次完整的通信過程分為3個階段:主機詢問、從機應答和鏈路釋放。主機詢問階段,主機以幀的形式將從機地址碼、命令、數據和校驗碼傳送到指定從機;從機應答階段,從機解釋接收的命令碼,并組織相應幀信息回送到主機;鏈路釋放階段,從機清除接收緩沖區及相關變量,準備與主機下次通信。任何一次完整的通信過程都是由主機方發起的,從機在被主機尋址前只能處于偵聽狀態,從機在接收到地址碼的第2個字節后,立即判斷是否尋址自己,如果是.繼續接受下面的數據,否則不與理睬。
5.3 通信軟件設計 5.3.1 從機通信軟件設計
在該系統中,從機的主要任務是對被檢測設備進行故障檢測和故障定位,通信軟件的主要功能是接收主機的命令并將檢測的結果回送主機。從機通信軟件由2部分組成:串行中斷服務程序和定時器TO中斷服務程序。串行中斷服務程序用于接收或發送數據;TO中斷服務程序用于當從機接收完一幀信息后進行解釋并啟動通信向主機應答,另外也用于當從機發送超時后的一些處理。從機上電后處于偵聽狀態,當主機尋址時,便進人中斷服務程序,其程序流程圖如圖5-4所示。
圖5-4 串行通信中斷服務程序流程圖
定時器TO,并置收發標志為收。當接收完第2個字節后,各從機立即判斷是否尋址本機,若是,則置SM2為‘
0’,繼續接收主機送來的數據;若不是,則禁止T0定時,不在接收后面的數據。當被尋址從機接收完一幀信息后,字符間隔定時器會產生定時中斷,進入TO中斷服務程序。圖5-5是TO中斷服務程序流程圖
進入TO中斷服務程序后,首先清除TO中斷請求標志,停止TO定時器,接著判斷是接收完成還是發送超時,若是接收完成,再判斷校驗和是否正確,若正確,對接收的命令進行解釋,看是主機讀還是主機寫操作,若是主機讀,則將數據打包,送到專門用于通信的數組,接著,禁止接收,置本機為應答工作方式,最后啟動發送,發送第一個字節,同時啟動發送時限定時器TO。當一個字節發送完后,便進入通信中斷服務程序,
繼續發送余下數據。如果在上邊判校驗和時,發現不正確,則置SM2為‘1’,恢復本機的偵聽狀態,以便接收主機的重發信息。
5.3.2 主機通信軟件設計
該系統主機的主要任務是循環讀取從機的檢測結果,并送終端顯示,其通信軟件由3部分組成:主程序中負責尋址從機的尋址模塊、通信中斷服務程序和TO中斷服務程序。尋址模塊程序流程圖見圖5-6。
對從機尋址是按照從機的編號順序進行的,即從1號從機開始,主機發送該從機信息幀的第1個字節啟動尋址,同時啟動發送超時定時器TO,然后檢測通信結束標志.當主機成功的接收到該從機的應答信息后,便會置位該標志,完成與該從機的通信。接下來,尋址下一從機,直到所有從機都被尋址。最后,主機完成其它功能后,又從1號從機開始下一循環的尋址。通信中斷服務程序和TO中斷服務程的設計方法與從機的大同小異,在此不再介紹。
第6章 程序設計
程序是單片機靈魂,沒有對應的程序,單片機系統是無法完成任何動作的,解決所涉及的問題的。編寫程序必須對機器的指令系統非常的熟悉,而且不能脫離具體的機器,因此程序不能在不同的機器上通用。未了使本系統能夠成功運行,程序是必不可少的,所以這次編寫了一個主機程序,兩個從機程序。
6.1 主機程序如下:
#include《reg51.h》 #include《absacc.h》 #include《intrins.h》 unsigned char cort=0; sbit P3_5=P3^5;
/********************************* 按鍵掃描子程序
*********************************/ key_serial() interrupt 0 using 1
{
++cort; }
/********************************* 發送子程序
*********************************/ void master(void) { if(cort==1) { SBUF=0x01; while(TI!=1);TI=0; P3_5=0; SM2=0;
while (RI!=1);RI=0;
P2=SBUF;
SM2=1; P3_5=1;
}
if(cort==2) {
SBUF=0x02; while(TI!=1);TI=0; SM2=0; P3_5=0;
while(RI!=1);RI=0; P2=SBUF; SM2=1; P3_5=1;
}
if(cort==3)cort=1; SM2=1;
}
/***************主程序****************/ void main(void) {
P2=0xff; TMOD=0x20; TL1=0xfd; TH1=0xfd; PCON=0x00; TR1=1; SCON=0xf8; EA=1; EX0=1; IT0=1; P3_5=1;
while(1) {
master();
//發送
} }
6.2 從機1程序如下: #include《reg51.h》 #include《absacc.h》 #include《intrins.h》
unsigned char serial_receiver; sbit P3_5=P3^5;
/**************************************** 串行口中斷子程序
****************************************/ void serial (void) interrupt 4 using 1 { ES=0; RI=0;
if(SBUF==0x01)
{
P3_5=1; SM2=0; P1=0x10; SBUF=0x10;
while(TI!=1);TI=0;
}
SM2=1; ES=1;
P3_5=0;
}
/*****************主程序******************/
void main(void) { P1=0x00; TMOD=0x20; TL1=0xfd; TH1=0xfd; PCON=0x00; TR1=1; SCON=0xf0; EA=1; ES=1; P3_5=0; while(1) { _nop_();
}
6.3 從機2程序如下: #include《reg51.h》 #include《absacc.h》 #include《intrins.h》
unsigned char serial_receiver; sbit P3_5=P3^5;
/**************************************** 串行口中斷子程序
****************************************/ void serial (void) interrupt 4 using 1 { ES=0; RI=0;
if(SBUF==0x02)
{
P3_5=1; SM2=0; P1=0x80; SBUF=0x80;
while(TI!=1);TI=0;
} SM2=1; ES=1;
P3_5=0;
}
/*****************主程序******************/ void main(void) { P1=0x00; TMOD=0x20; TL1=0xfd; TH1=0xfd; PCON=0x00; TR1=1; SCON=0xf0; EA=1; ES=1; P3_5=0; while(1) { _nop_();