近日学习测控网络技术,一时无趣想起以前学
51时后面的串行通信的
多机通信部分还未尝试过,虽然技术可能已经过时,但是对于理解网络协议的基本原理还是有些裨益的。
单片机的多机通信最重要的就是SM2位的使用,主从式通信方式中,主机以广播形式发送地址帧,程序控制主机SM2为1,此时TB8位置1,从机初始时SM2=1,当接收到RB8为1时,引起接受中断,这时主、从机通过约定的应答机制进行校验,即从机收到地址后与自身上电就得到的本机地址比较,如确定是在找自己,就发送应答,清零SM2开始接收数据,仿真原理图如下所示:
![](../img/eep/emb/emb-60430gnecmwsppak.jpg)
主要实现代码如下:
多机通信主机:
DATA_ACK EQU 2AH;本例中未使用
ADDR_ACK EQU 1AH;地址校验帧
DATA_BUF EQU 40H ;按键中断数据的存放区
WORK_FLAG EQU P2.0 ;可作为单片机类程序设计的软件调试接口
SLAVE_ADDR EQU 30H ;单片机上电后获得的本机地址
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP INT_EX0
ORG 000BH ;使用定时器产生1s
;AJMP INT_T0
ORG 0013H
AJMP INT_EX1
ORG 001BH
;AJMP INT_T1
ORG 0023H
; AJMP SEND_DATA
ORG 50H
MAIN:
MOV SP,#60H
MOV DATA_BUF,#0
MOV P0,#0C0H
MOV SLAVE_ADDR,P1
;定时器初始化
MOV TMOD,#20H
MOV TH1,#0FDH
MOV TL1,#0FDH
MOV SCON,#0D0H ;串口工作在方式3,多机位值1,允许接受
MOV TB8 ,#1 ;发送地址
SETB TR1 ;open the timer1
SETB IT0
SETB EX0
SETB IT1
SETB EX1
;SETB ES
SETB EA
HERE:
LCALL HANDLE_DATA
;LCALL RECEIVE_ACK
LCALL DISPLAY
SJMP HERE
HANDLE_DATA:
MOV A,TB8
JNZ HANDLE_ADR
;MOV WORK_FLAG,#0
MOV TB8,#0
MOV R0,#DATA_BUF
MOV SBUF,@R0
JNB TI,$
MOV WORK_FLAG,#0
CLR TI
;MOV TB8,#0
RET
HANDLE_ADR:
MOV A,SLAVE_ADDR
MOV SBUF,A
JNB TI,$
CLR TI
RECEIVE_ACK:
JNB RI,$
CLR RI
MOV A,SBUF
XRL A,ADDR_ACK
MOV TB8,#0
JZ HANDLE_DATA
MOV TB8,#1
RET
INT_EX0:
CLR EX0
PUSH ACC
PUSH PSW
MOV A,DATA_BUF
INC A
MOV DATA_BUF,A
CJNE A,#10,EXIT
MOV DATA_BUF,#0
EXIT:
POP PSW
POP ACC
SETB EX0
RETI
INT_EX1:
CLR EX1
PUSH ACC
PUSH PSW
MOV A,DATA_BUF
DEC A
MOV DATA_BUF,A
CJNE A,#0FFH,QUIT
MOV DATA_BUF,#9
QUIT:
POP PSW
POP ACC
SETB EX1
RETI
DISPLAY:
MOV DPTR,#DATASEG
MOV R0,#DATA_BUF
MOV A,@R0
MOVC A,@A+DPTR
;MOV P0,#0FFH
MOV P0,A
ACALL DELAY
RET
DELAY:
MOV R6,#25 ;5MS
DEL1:
MOV R7,#98 ; ;98
DJNZ R7,$
DJNZ R6,DEL1
RET
DATASEG:
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H
DB 080H,090H,0BFH
END
多机通信从机:
DATA_ACK EQU 2AH
ADDR_ACK EQU 1AH
DATA_BUF EQU 40H
WORK_FLAG EQU P2.0
SLAVE_ADDR EQU 30H
TEMP_BUF EQU 31H
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP INT_EX0
ORG 000BH ;使用定时器产生1s
;AJMP INT_T0
ORG 0013H
AJMP INT_EX1
ORG 001BH
;AJMP INT_T1
ORG 0023H
; AJMP RECIVE_DATA
ORG 50H
MAIN:
MOV SP,#60H
MOV DATA_BUF,#0
MOV P0,#0C0H
MOV SLAVE_ADDR,P1
MOV R5,#0
;定时器初始化
MOV TMOD,#20H
MOV TH1,#0FDH;
MOV TL1,#0FDH
MOV SCON,#0D0H ;串口工作在方式3,多机位值1,允许接收
SETB SM2 ;多机通信控制位1
SETB TR1 ;open the timer1
SETB IT0
SETB EX0 ;从机暂未使用
SETB IT1
SETB EX1 ;从机暂未使用
SETB EA
HERE:
LCALL HANDLE_DATA
LCALL DISPLAY
SJMP HERE
HANDLE_DATA:
JNB RI,$
CLR RI
MOV A,SBUF
MOV TEMP_BUF,A
JNB SM2, DATA_RECEIVE
XRL A,SLAVE_ADDR
JNZ OVER
MOV A,ADDR_ACK
MOV SBUF,A
CLR A
JNB TI,$
CLR TI
CLR SM2
RET
OVER:
SETB SM2
RET
DATA_RECEIVE:
MOV WORK_FLAG,#0
MOV DATA_BUF,TEMP_BUF
RET
INT_EX0:
CLR EX0
PUSH ACC
PUSH PSW
MOV A,DATA_BUF
INC A
MOV DATA_BUF,A
CJNE A,#10,EXIT
MOV DATA_BUF,#0
EXIT:
POP PSW
POP ACC
SETB EX0
RETI
INT_EX1:
CLR EX1
PUSH ACC
PUSH PSW
MOV A,DATA_BUF
DEC A
MOV DATA_BUF,A
CJNE A,#0FFH,QUIT
MOV DATA_BUF,#9
QUIT:
POP PSW
POP ACC
SETB EX1
RETI
DISPLAY:
MOV DPTR,#DATASEG
MOV R0,#DATA_BUF
MOV A,@R0
MOVC A,@A+DPTR
;MOV P0,#0FFH
MOV P0,A
ACALL DELAY
RET
DELAY:
MOV R6,#25 ;5MS
DEL1:
MOV R7,#98 ; ;98
DJNZ R7,$
DJNZ R6,DEL1
RET
DATASEG:
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H
DB 080H,090H,0BFH
END
仿真时注意波特率的设定,计算时晶振代入的是12MHZ(X约为253)而为了保证波特率的误差小于2.5%,主机设为11.05926MHZ,从机设为12MHZ。