;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK RS-485匯流排多機通訊 KKKKKKKKKKKKKKKKKKKK
;Rev:01.01
;DATE:2005.06.16
;作者:KOCOM/黃業勝
;使用晶片:AT89C2051、SP485
;使用晶振:18.432M
;電路描述:簡單RC上電複位、P1.7--P1.5分別接LED和限流電阻到VCC,P1.4--P1.2分別接KEY輕觸開關到GND
;琑xD串連到SP485的1腳R,
; TxD串連到SP485的4腳D,P3.7串連到SP485的2、3腳RE/DE,SP485的6腳DATA_A接上拉電
;阻4.7KP485的7腳DATA_B接下拉電阻4.7K
; 各分機的DATA_A、DATA_B、GND分別對應並接,再經RS-485/232轉換介面串連至PC。
;操作說明:本實驗只串連了3台分機和1台PC,分機在上電前先按住KEY1--KDY3中的某一鍵,以便在程式初始
;化時自動化佈建相應的預設地址
; 如上電前按住KEY1,則該分機相應地址為12340303H,同理KEY2---12340407,KEY3---12346789.
;功能描述:在1#分機按下KEY2,1#將發送資料呼叫2#,2#進行地址驗證和資料校正後,點亮或熄滅相應LED,
;並向1#回複應答訊號,
; 1#分機收到應答訊號後相應LED閃爍3次。
; PC端串口調試軟體可以監測到匯流排上的資料,並可與各分機雙向通訊。
; PC設定傳輸速率為9600,8位元據,奇或偶校正,資料收/發以十六進位。
; PC如發55 12 34 04 07 00 00 00 00 92 6D 70 AA呼叫1#分機,選擇1#將回複55 00 00 00 00 12
34 04 07 AA 55 07 AA
;呼叫時,選擇傳輸速率2400bps,資料位元8位,停止位1位,校正位none,流量控制none;PC發送資料時,只能採用HEX
發送方式,一個byte一個byte發送!
; PC如發55 12 34 04 07 12 34 03 03 92 6D 74 AA,則會看到1#和2#均有動作。
;********************資源分派****************
;@R0--接收資料時作資料儲存地址指標調整
;@R1--發送資料時作發送單元地址指標調整
;********************串口通訊知識****************
;工作方式2和方式3都是11位非同步收發串列通訊,兩者的差異僅在傳輸速率上有所不同,方式2:傳輸速率=2
SMOD*Fos/64(smod=0或1)
;方式3:傳輸速率=2 SMOD*Fosc/32*12*(M-T初)
;(1)資料發送 TI=0,發送資料前,先由軟體佈建TB8,可使用如下指令完成:SETB TB8; CLR TB8;然後再向SBUF
寫入8位元據,並以此啟動
;串列發送。一幀資料發送完畢後,CPU自動將TI置1,
;(2)資料接收REN=1,RI=0時,啟動接收若SM2=0,接收到的8位元據送SBUF,第9位送RB8.若SM2=1,接收到的第9位
資料為0,資料不送SBUF,
;接收到的第9位元據為1,資料送SBUF,第9位送RB8.
;********************串口通訊知識****************
;SM0 SM1=11;工作方式3;11位非同步收發傳輸速率可變(T1溢出率/n,n=32或16),SM2等於1,表示多機通訊,REN接
收控製為1表示應許接收!
;在方式2或方式3中,若SM2=0,串列口以單機發送或接收方式工作,TI和RI以正常方式被啟用併產生插斷要求
;
;若SM2=1,RB8=1時,RI被啟用併產生插斷要求;
;TB8在方式2和方式3時,TB8是發送第9位元據,在多機通訊中,以TB8位的狀態表示主機發送的是地址還是數
據:TB8=1表示地址,TB8=0表示資料。
;TI發送中斷標誌位。TI=1,表示已結束一幀資料發送,注意;TI在任何工作方式下都必須有軟體清零;
;RI同上
;AT89C51,串列發送中斷TI和接收中斷RI的中斷入口地址都是0023H,因此在中斷程式中必須有軟體查詢TI和RI
的狀態才能確定究竟是接收還是發送中斷,進而做相應處理。
;電源控制寄存器PCON,其中SMOD;串列口傳輸速率倍增位,在工作方式1~工作方式3時,若SMOD=1,則串列口波
特率增加一倍。若SMOD=0,傳輸速率不加倍!
;多機通訊原理,多機通訊時,主機向從機發送的資訊分為地址幀和資料幀兩類,以第9位可程式化TB8做區分標
志,TB8=0,表示資料;TB8=1,表示地址。多機通訊充分利用
;89C51串列控制寄存器SCON中的多機通訊控制位SM2的特性。當SM2=1時,CPU接收的前8位元據是否送入SBUF取
決於接收的第9位RB8的狀態;若RB8=1,將接收到的前8位元據送入
;SBUF,共置位RI產生插斷要求;若RB8=0,則接收的前8位元據丟棄。即當從機SM2=1時,從機只能接受主機發送
的地址幀(RB8=1),對資料幀(RB8=0)不予理睬。
;當從機SM2=0時,從機可接收主機發送的所有資訊?
;通訊開始時,主機首先發送地址幀,由於各從機的SM2=1
和RB8=1,所以各從機均分別發出串列接收終端請求,通過串列中斷服務程式來判斷主機發送的地址與本機從地
址是否相符,
;如果相符,則把自身的SM2清0,已準備接收隨後傳送來的資料幀。其餘從機由於地址不符,則仍然保持SM2=1
狀態,因而不能接收主機傳送來的資料幀。
;多機通訊過程:(1)主從機工作與方式2或方式3,主機置SM2=0,REN=1;從機置SM2=1,REN=1.(2)主機置位TB8=1,
向從機發送定址地址幀,各從機因滿足接收條件(SM2=1,RB8=1),從而接收
;到主機發來的地址,並與本機地址比較。(3)地址一致的從機(被定址機)將SM2清0,並向主機返回地址,共
主機核對,地址不一致的從機(未被定址機)保持SM2=1;
;(4)主機核對返回地址,若與此前發出的地址一致則準備發送資料;若不一致則返回(2)重新發送地址幀。(5)
主機向從機發送資料,此時主機的TB8=0,只有被選中的那台從機能接收到該資料。
;其他從機則捨棄該資料.(6)本次通訊結束後,從機重新置SM2=1,等下次通訊。
LED1 BIT P1.7
LED2 BIT P1.6
LED3 BIT P1.5
KEY1 BIT P3.3
KEY2 BIT P3.4
KEY3 BIT P3.5
RXTX BIT P2.0
RXADDRESS_1 EQU 30H ;接收到的被叫端地址4byte
RXADDRESS_2 EQU 31H
RXADDRESS_3 EQU 32H
RXADDRESS_4 EQU 33H
RXDATA_A1 EQU 34H ;接收到的呼叫端地址4byte
RXDATA_A2 EQU 35H
RXDATA_A3 EQU 36H
RXDATA_A4 EQU 37H
RXDATA_D1 EQU 38H ;接收到的受控指令2byte
RXDATA_D2 EQU 39H
RXDATA_CRC EQU 3AH ;接收到的資料同位1byte
RXDATA_END EQU 3BH ;接收到的通訊結束字AAH 1byte
LOOP4_ADDRESS_SAVE EQU 3CH ;迴圈接收4個地址碼
LOOP8_DATA_SAVE EQU 3DH ;迴圈接收8個資料碼
NOISE1 EQU 3EH ;按鍵消抖延時參數
LEDFLASH EQU 3FH ;LED閃爍次數
TXADDRESS_1 EQU 40H ;發送出去的終端地址4byte
TXADDRESS_2 EQU 41H
TXADDRESS_3 EQU 42H
TXADDRESS_4 EQU 43H
SELF_ADDRESS1 EQU 44H ;本機地址碼儲存單元44H--47H
SELF_ADDRESS2 EQU 45H
SELF_ADDRESS3 EQU 46H
SELF_ADDRESS4 EQU 47H
TXDATA_D1 EQU 48H
TXDATA_D2 EQU 49H
TXDATA_CRC EQU 4AH
TXLOOP_CRC8_BYTE12 EQU 4BH ;迴圈參數,迴圈校正8位CRC及連續發送12個位元組
RX_BIT_START BIT 20H.0;開始接收標誌,收到55H後置位,表示允許開始接收地址碼
RX_BIT_DATAENABLE BIT 20H.1;允許接收資料標誌,經驗證本機地址後置位,表示允許接收資料碼
FLASHDATA BIT 20H.2;資料重新整理標誌,當通訊接收完成後置位,表示接收完畢,可進入指令控製程
序
TX_BIT_FINISH BIT 20H.3;當前位元組資料發送完畢標誌位
ORG 0000H
JMP START
ORG 0023H
JMP SINT
SINT:
JBC RI,RXWK ;若是接收中斷,則清除RI標誌位,並轉接收處理
CLR TI ;若是發送中斷,則清除TI標誌位
SETB TX_BIT_FINISH;當前位元組資料發送完畢,置位標誌位
LJMP SEND
RXWK:
MOV A,SBUF
;MOV P0,A;調試時候用
JB RX_BIT_START,ADDRESS_SAVE ;確認收到55H起始字,轉入地址碼儲存程式
CJNE A,#55H,SEND ;在起始標誌位為0前,須檢測到55H方可進入接收程式
SETB RX_BIT_START
MOV LOOP4_ADDRESS_SAVE,#4 ;為後續儲存4個地址碼作迴圈參數
MOV R0,#30H ;地址指標指向儲存地址30H
LJMP SEND
ADDRESS_SAVE: ;儲存接收到的被叫端地址
JB RX_BIT_DATAENABLE,DATA_SAVE ;若已經驗證通過本機地址,則允許接收其後續的資料碼
MOV @R0,A ;若未通過地址驗證,則繼續接收地址碼
;MOV P0,A ;調試時候用
INC R0 ;調整儲存地址
DJNZ LOOP4_ADDRESS_SAVE,SEND
ADDRESS_CHECK: ;本機地址驗證
MOV A,RXADDRESS_1 ;取出接收到的被叫端地址碼
CJNE A,SELF_ADDRESS1,ERRO_ADDRESS ;驗證第1位地址碼,地址不對則退出
MOV A,RXADDRESS_2 ;取出接收到的被叫端地址碼
CJNE A,SELF_ADDRESS2,ERRO_ADDRESS ;驗證第2位地址碼,地址不對則退出
MOV A,RXADDRESS_3 ;取出接收到的被叫端地址碼
CJNE A,SELF_ADDRESS3,ERRO_ADDRESS ;驗證第3位地址碼,地址不對則退出
MOV A,RXADDRESS_4 ;取出接收到的被叫端地址碼
CJNE A,SELF_ADDRESS4,ERRO_ADDRESS ;驗證第4位地址碼,地址不對則退出
OK_ADDRESS_CHECK: ;地址驗證通過
CLR SM2 ;允許接收資料中斷,其它未經過地址驗證的機子在收到資料
碼時無法引起中斷
SETB RX_BIT_DATAENABLE ;允許接收資料標誌置位
MOV LOOP8_DATA_SAVE,#8 ;準備迴圈接收8位元據碼
MOV R0,#RXDATA_A1 ;地址指標指向資料碼儲存地址,為DATA_SAVE程式段儲存資料
作準備
LJMP SEND
ERRO_ADDRESS:
RESET_SIGN_BIT: ;標誌位複位
CLR RX_BIT_START ;關閉開始接收標誌,使下一次通訊重新進入55H起始字驗證
SETB SM2 ;只允許接收到的資料為地址碼才引起中斷
CLR RX_BIT_DATAENABLE ;關閉允許接收資料碼標誌,使下一次通訊須重新進行本機地
址驗證方可
LJMP SEND
DATA_SAVE:
MOV @R0,A
INC R0
DJNZ LOOP8_DATA_SAVE,SEND ;8個資料碼未接收完畢則繼續等待下一個資料
DATA_RECEIVE_OVER: ;資料接收完畢
SETB FLASHDATA ;資料重新整理標誌置位
LJMP RESET_SIGN_BIT ;轉去對通訊過程相關的標誌位進行複位,並退出
SEND:
RETI
START:
MOV P1,#00H
ACALL DELAY
MOV P1,#0FFH
SET_ADDR1:
JB KEY1,SET_ADDR2
MOV SELF_ADDRESS1,#12H ;本機地址設為1234棟303號
MOV SELF_ADDRESS2,#34H
MOV SELF_ADDRESS3,#03H
MOV SELF_ADDRESS4,#03H
JMP SET_OK
SET_ADDR2:
JB KEY2,SET_ADDR3
MOV SELF_ADDRESS1,#12H ;本機地址設為1234棟303號
MOV SELF_ADDRESS2,#34H
MOV SELF_ADDRESS3,#04H
MOV SELF_ADDRESS4,#07H
JMP SET_OK
SET_ADDR3:
JB KEY3,SET_OK
MOV SELF_ADDRESS1,#12H ;本機地址設為1234棟303號
MOV SELF_ADDRESS2,#34H
MOV SELF_ADDRESS3,#67H
MOV SELF_ADDRESS4,#89H
SET_OK:
MOV P1,#0FFH
MOV SP,#07H
MOV P0,#0FFH
CLR RXTX ;485處於接收狀態
CLR FLASHDATA
CLR RX_BIT_START ;關閉開始接收標誌,使下一次通訊重新進入55H起始字驗證
CLR RX_BIT_DATAENABLE ;關閉允許接收資料碼標誌,通訊須進行本機地址驗證方可接收資料
CLR TX_BIT_FINISH
;mov scon,#0f0h
;mov tmod,#20h
;mov th1,#0fbh
mov tmod,#20h
mov th1,#0f3h
mov tl1,#0f3h
setb tr1
mov scon,#0f0h ;串口工作方式3,地址/資料驗證控制,允許接收
mov pcon,#00h
;SETB SM2 ;只允許地址碼引起中斷,待與本機地址碼驗證通過方可由資料碼接收
引起中繼
SETB EA
SETB ES ;允許串口中斷
;clr sm2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;與PC雙
向通訊實驗,取消D/A驗證
MAIN:
IFTXDATA:
JNB FLASHDATA,KEY_TEST ;若通訊資料接收完畢,則進行資料處理,否則轉下一程式段
LJMP RX_COMMAND
KEY_TEST:
JB KEY1,IFK2FX
MOV NOISE1,#00H
K1NIE:
JB KEY1,IFK2FX
DJNZ NOISE1,K1NIE
;MOV A,#91H
MOV TXDATA_D1,#91H
MOV TXADDRESS_1,#12H
MOV TXADDRESS_2,#34H
MOV TXADDRESS_3,#03H
MOV TXADDRESS_4,#03H
ACALL TXDATA
JNB KEY1,$
IFK2FX:
JB KEY2,IFK3FX
MOV NOISE1,#00H
K2NIE:
JB KEY2,IFK3FX
DJNZ NOISE1,K2NIE
;MOV A,#92H
MOV TXDATA_D1,#92H
MOV TXADDRESS_1,#12H
MOV TXADDRESS_2,#34H
MOV TXADDRESS_3,#04H
MOV TXADDRESS_4,#07H
ACALL TXDATA
JNB KEY2,$
IFK3FX:
JB KEY3,ENDIFKEY
MOV NOISE1,#00H
K3NIE:
JB KEY3,ENDIFKEY
DJNZ NOISE1,K3NIE
;MOV A,#93H
MOV TXDATA_D1,#93H
MOV TXADDRESS_1,#12H
MOV TXADDRESS_2,#34H
MOV TXADDRESS_3,#67H
MOV TXADDRESS_4,#89H
ACALL TXDATA
JNB KEY3,$
ENDIFKEY:
JBC FLASHDATA,RX_COMMAND
LJMP END_COMMAND
RX_COMMAND: ;對接收的資料進行處理
CLR FLASHDATA
MOV A,RXDATA_END
CJNE A,#0AAH,NOPASS
MOV B,#0 ;由接收到的8位元據產生1位CRC,暫存於B
MOV TXLOOP_CRC8_BYTE12,#8
MOV R1,#RXADDRESS_1 ;指標指向接收到的資料起始單元
CRC_CHECK:
MOV A,@R1
INC R1
ADD A,#0;奇偶標誌每個指令周期都由硬體來置位或清零,以表示累加器A中1的位元的奇偶數,若1的位元為
奇數,則P置位,否則清零;
MOV C,PSW.0;這個P時狀態寄存器中的第0位即PSW.0,為基數偶數校正位!
MOV A,B
RLC A
MOV B,A
DJNZ TXLOOP_CRC8_BYTE12,CRC_CHECK
CJNE A,RXDATA_CRC,NOPASS
/*MOV DPTR,#INFORMATION
FIND_HEAD:
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0BBH,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0C6H,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0D2H,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0B5H,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0CAH,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0A4H,FIND_HEAD
;...... ;資料校正!!!!!!
;......
*/
MOV A,RXDATA_D1 ;校正功能碼
MOV P1,RXDATA_D1
CPL A
CJNE A,RXDATA_D2,NOPASS
LJMP Checkout_PASS
NOPASS:
LJMP END_COMMAND
Checkout_PASS:
MOV RXDATA_CRC,#0
MOV RXDATA_END,#0 ;清除驗證碼,防止FLASHDATA被誤置位而誤進入RX_COMMAND
MOV A,RXDATA_D1 ;取出功能碼
CJNE A,#0AAH,NEXD0
MOV LEDFLASH,#3
LEDDISP1:
MOV A,TXDATA_D1
CJNE A,#91H,LEDDISP2
MOV A,#01111111B
LJMP LEDPLY
LEDDISP2:
CJNE A,#92H,LEDDISP3
MOV P1,#10111111B
MOV A,#10111111B
LJMP LEDPLY
LEDDISP3:
CJNE A,#93H,LEDDISP_END
MOV A,#11011111B
LJMP LEDPLY
LEDDISP_END:
LEDPLY:
MOV P1,A
ACALL DELAY
MOV P1,#11111111B
ACALL DELAY
DJNZ LEDFLASH,LEDPLY
LJMP NEXD3
NEXD0:
CJNE A,#91H,NEXD1
;MOV P1,#01111111B
CPL LED1
MOV TXDATA_D1,#0AAH ;接收正確,回複ACK
MOV TXADDRESS_1,RXDATA_A1
MOV TXADDRESS_2,RXDATA_A2
MOV TXADDRESS_3,RXDATA_A3
MOV TXADDRESS_4,RXDATA_A4
ACALL DELAY
ACALL DELAY
ACALL TXDATA
LJMP NEXD3
NEXD1:
CJNE A,#92H,NEXD2
;MOV P1,#10111111B
CPL LED2
MOV TXDATA_D1,#0AAH ;接收正確,回複ACK
MOV TXADDRESS_1,RXDATA_A1
MOV TXADDRESS_2,RXDATA_A2
MOV TXADDRESS_3,RXDATA_A3
MOV TXADDRESS_4,RXDATA_A4
ACALL DELAY
ACALL DELAY
ACALL TXDATA
LJMP NEXD3
NEXD2:
CJNE A,#93H,NEXD3
;MOV P1,#11011111B
CPL LED3
MOV TXDATA_D1,#0AAH ;接收正確,回複ACK
MOV TXADDRESS_1,RXDATA_A1
MOV TXADDRESS_2,RXDATA_A2
MOV TXADDRESS_3,RXDATA_A3
MOV TXADDRESS_4,RXDATA_A4
ACALL DELAY
ACALL DELAY
ACALL TXDATA
LJMP NEXD3
NEXD3:
END_COMMAND:
LJMP IFTXDATA
DELAY:
MOV R5,#4
LOOP1:
DJNZ R7,$
DJNZ R6,LOOP1
DJNZ R5,LOOP1
RET
TXDATA:
MOV TXDATA_CRC,#0
MOV TXLOOP_CRC8_BYTE12,#8
MOV R1,#TXADDRESS_1 ;指標指向待發資料的起始單元
CRC_TakePlace:
MOV A,@R1
INC R1
ADD A,#0
MOV C,P
MOV A,TXDATA_CRC
RLC A
MOV TXDATA_CRC,A
DJNZ TXLOOP_CRC8_BYTE12,CRC_TakePlace
SETB RXTX
MOV A,#55H ;發送起始字55H
SETB TB8;表示地址幀
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,TXADDRESS_1 ;發送終端地址碼1
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,TXADDRESS_2 ;發送終端地址碼2
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,TXADDRESS_3 ;發送終端地址碼3
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,TXADDRESS_4 ;發送終端地址碼4
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
CLR TB8;表示資料幀
MOV A,SELF_ADDRESS1 ;發送本機地址碼1
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,SELF_ADDRESS2 ;發送本機地址碼2
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,SELF_ADDRESS3 ;發送本機地址碼3
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,SELF_ADDRESS4 ;發送本機地址碼4
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,TXDATA_D1 ;發送資料原碼
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
;MOV A,TXDATA_D2 ;發送資料反碼
MOV A,TXDATA_D1
CPL A
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,TXDATA_CRC ;發送CRC校正字
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
MOV A,#0AAH ;發送結束字AAH
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
CLR RXTX
RET
INFORMATION:
DB "KOCOM Communication Part"
DB "Rev:01.01"
DB "DATE:2005.06.16"
DB "R&D/黃業勝"
END