|
- ;主機和多臺從機之間通信。通信協議如下:
- ;(1)系統中255臺從機地址分別為00~FEH;
- ;(2)地址FFH是對所有從機都起作用的一條控制命令,命令各從機恢復SM2=2的狀態;
- ;(3)主機發送的控制命令代碼為:00—要求從機接收數據塊,01—要求從機發送數據塊;
- ;(4)數據塊長度:16字節。
- ;(5)從機狀態字格式為:
- ;D7 D6 D5 D4 D3 D2 D1 D0
- ;ERR 0 0 0 0 0 TRDY RRDY
- ;其中:若ERR=1,表示從機接收到非法命令;若TRDY=1,表示從機發送準備就緒;
- ;若RRDY=1,表示從機接收準備就緒。
- ;編程方法:主機的串口通信以調用子程序方式進行;從機以串口中斷的方式進行,
- ;若從機未做好接收或發送數據的準備,就從中斷程序中返回,在主程序中做好準備。
- ;以下為主機串行通信程序
- ;入口參數:R0—主機發送的數據塊首址;R1—主機接收的數據塊首址;R2—被尋址從機地址;
- ;R3—主機命令;R4—數據塊長度;
- BITE EQU 9 ;串口發送9位數據
- FSSZ EQU 40H ;主機發送的數據塊首址
- JSSZ EQU 50H ;主機接收的數據塊首址
- ORG 0000H ;程序執行開始地址
- LJMP KS ;跳至KS
- ORG 0003H ;外中斷0中斷程序入口
- RETI ;中斷返回
- ORG 000BH ;定時器T0中斷程序入口
- RETI ;中斷返回
- ORG 0013H ;外中斷1中斷入口
- RETI ;中斷返回
- ORG 001BH ;定時器T1中斷程序入口
- RETI ;跳至INTT1中斷服務程序
- ORG 0023H ;串口中斷入口地址
- RETI ;中斷返回
- ORG 0100H
- KS: MOV SP,#1FH ;設置堆棧指針
- ;此處可以插入其他程序
- COM: MOV TMOD,#20H ;設置T1工作方式為方式2
- MOV SCON,#0D8H ;置串行模式3,SM2=1,允許接收
- MOV TH1,#0FDH ;11.0592MHz 晶振,波特率=9600,時長0.6695 FD
- SETB TR1 ;啟動T1
- ;若主機向10號從機發送數據塊,數據塊放置在內部RAM區的40~4F單元中,
- ;則主程序調用子程序的入口條件如下:
- MOV FSSZ,#0
- MOV FSSZ+1,#1
- MOV FSSZ+2,#2
- MOV FSSZ+3,#3
- MOV FSSZ+4,#4
- MOV FSSZ+5,#5
- MOV FSSZ+6,#6
- MOV FSSZ+7,#7
- MOV FSSZ+8,#8
- ;串口通信
- MOV R2,#0AH ;與10號從機通信
- ;MOV R3,#00H ;主機要求從機接收數據塊
- MOV R3,#01H ;主機要求從機發送數據塊
- ;占用資源:R0~R4,A、40H、50H
- COM1: LCALL MS101 ;調用串口通信子程序
- CJNE R4,#00H,COM1 ;查看是否發送接收數據完成
- SJMP KS ;實際中加入其他程序
- ;以下為主機串行通信子程序
- MS101: MOV A,R2 ;發送地址幀
- MOV SBUF,A
- JNB TI,$
- CLR TI
- JNB RI,[ DISCUZ_CODE_1 ]nbsp; ;等待從機應答
- CLR RI
- MOV A,SBUF
- XRL A,R2
- JZ MS103 ;判應答地址是否相符
- RET
- MS102: SETB TB8
- MOV SBUF,#0FFH ;不相符重新聯絡
- JNB TI,$
- CLR TI
- SJMP MS101 ;轉重發地址
- MS103: CLR TB8 ;地址符合,準備發送命令
- MOV SBUF,R3 ;發送命令
- JNB TI,$
- CLR TI
- JNB RI,[ DISCUZ_CODE_1 ]nbsp; ;等待從機應答
- CLR RI
- MOV A,SBUF ;取應答信息
- JNB ACC.7,MS104 ;判斷是否出錯
- SJMP MS102 ;若從機接收命令出錯,重新聯絡
- MS104: CJNE R3,#00H,MS105 ;判是否要求從機接收數據
- JNB ACC.0,MS102 ;從機接收數據準備就緒否?
- MOV R0,#FSSZ ;主機發送的數據塊首址
- MOV R4,#BITE ;設數據塊長度(9字節)
- LPTX: MOV SBUF,@R0 ;主機發送數據塊
- JNB TI,[ DISCUZ_CODE_1 ]nbsp; ;等待發送完1幀
- CLR TI
- INC R0 ;修改地址指針
- DJNZ R4,LPTX ;判數據塊是否傳完
- RET ;返回主程序
- MS105: JNB ACC.1,MS102 ;從機發送數據準備就緒否?
- MOV R1,#JSSZ ;主機接收的數據塊首址
- MOV R4,#BITE ;設數據塊長度(9字節)
- LPRX: JNB RI,LPRX ;等待接收完1幀
- CLR RI
- MOV A,SBUF ;取出接收到的字符
- MOV @R1,A
- INC R1
- DJNZ R4,LPRX ;未接收完則繼續
- RET
- END
-
- ;以下為從機串行通信程序
- ;從機的的串行通信采用中斷控制啟動方式,串行口中斷服務程序利用1區工作寄存器。在串口通信啟動后,
- ;仍采用查詢方式來接收或發送數據塊。從機的初始化程序中應包括定時器1和串口初始化以及開中斷程序。
- ;程序中利用F0(PSW.5)作發送準備就緒標志,F1(PSW.1)作接收準備就緒標志。
- SLAVE EQU 0AH ;設定從機地址
- BITE EQU 9 ;串口發送9位數據
- FSSZ EQU 40H ;主機發送的數據塊首址
- JSSZ EQU 50H ;主機接收的數據塊首址
- ORG 0000H ;程序執行開始地址
- LJMP KS ;跳至KS
- ORG 0003H ;外中斷0中斷程序入口
- RETI ;中斷返回
- ORG 000BH ;定時器T0中斷程序入口
- RETI ;中斷返回
- ORG 0013H ;外中斷1中斷入口
- RETI ;中斷返回
- ORG 001BH ;定時器T1中斷程序入口
- RETI ;跳至INTT1中斷服務程序
- ORG 0023H ;中斷返回
- LJMP SS10 ;跳至串口中斷服務程序
- KS: MOV SP,#1FH ;設置堆棧指針
- MOV TMOD,#20H ;設置T1工作方式為方式2
- MOV SCON,#0F0H ;置串行模式3,SM2=1,允許接收
- MOV TH1,#0FDH ;11.0592MHz 晶振,波特率=9600,時長0.6695
- SETB TR1 ;啟動T1
- SETB EA ;開總中斷
- MOV FSSZ,#0
- MOV FSSZ+1,#1
- MOV FSSZ+2,#2
- MOV FSSZ+3,#3
- MOV FSSZ+4,#4
- MOV FSSZ+5,#5
- MOV FSSZ+6,#6
- MOV FSSZ+7,#7
- MOV FSSZ+8,#8
- SETB F0 ;作發送準備就緒標志
- SETB F1 ;作接收準備就緒標志
- SETB ES ;允許串口通信
- SJMP [ DISCUZ_CODE_1 ]nbsp; ;可以插入其他程序
- ;串行口中斷服務程序(由0023轉來)
- ;占用資源:1區R0~R2,A、40H、50H、C
- SS10: CLR RI
- PUSH A ;保護現場
- PUSH PSW
- SETB RS0 ;選1區工作寄存器
- CLR RS1
- MOV A,SBUF
- XRL A,#SLAVE ;SLAVE為本從機地址
- JZ SSI01 ;判地址是否符合
- RETU: POP PSW ;恢復現場
- POP A
- RETI
- SSI01: CLR SM2 ;地址符合,準備接收數據
- MOV SBUF,#SLAVE ;從機地址送主機,準備核對
- JNB TI,[ DISCUZ_CODE_1 ]nbsp; ;等待發送完1幀
- CLR TI
- JNB RI,[ DISCUZ_CODE_1 ]nbsp; ;等待接收完1幀
- CLR RI
- JNB RB8,SSI02 ;是數據幀跳轉
- SETB SM2 ;復位信號,把SM2置“1”
- SJMP RETU
- SSI02: MOV A,SBUF ;取命令
- CLR C
- CJNE A,#02H,SS1 ;檢查命令是否合法,如果A<2,則C=1,否則C=0
- SS1: JC SSI03 ;A<02H則繼續
- MOV SBUF,#08H ;非法命令,置ERR=1
- JNB TI,[ DISCUZ_CODE_1 ]nbsp; ;等待發送完1幀
- CLR TI
- SJMP RETU ;返回
- SSI03: JZ CMD0 ;A=00H,準備接收數據塊
- JB F0,SSI04 ;發送準備就緒否
- MOV SBUF,#00H ;回答未準備就緒
- JNB TI,[ DISCUZ_CODE_1 ]nbsp; ;等待發送完1幀
- SJMP RETU
- SSI04: MOV SBUF,#02H ;發送準備就緒,置TRDY=1
- JNB TI,$
- CLR TI
- CLR F0 ;清發送準備標志
- MOV R0,#FSSZ
- MOV R2,#BITE ;發送或接收字節數送1區工作寄存器R2,現設定為9字節
- LP1: MOV SBUF,@R0 ;發送數據塊
- JNB TI,$
- CLR TI
- INC R0 ;修改數據指針
- DJNZ R2,LP1
- SETB SM2 ;發送完,置SM2=1
- SJMP RETU
- CMD0: JB F1,SSI05 ;判接收準備就緒否?
- MOV SBUF,#00H ;回答未準備就緒
- JNB TI,$
- CLR TI
- SJMP RETU
- SSI05: MOV SBUF,#01H ;接收準備就緒,置RRDY=1
- JNB TI,$
- CLR TI
- CLR F1
- MOV R1,#JSSZ ;接收緩沖區首址送1區工作寄存器R1,現設定為50~5FH
- MOV R2,#BITE
- LP2: JNB RI,LP2 ;等待1幀接收完
- CLR RI
- MOV @R1,SBUF
- INC R1
- DJNZ R2,LP2
- SETB SM2 ;接收完,置SM2=1
- SJMP RETU
- END
復制代碼
|
|