|
- ;主机和多台从机之间通信。通信协议如下:
- ;(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
复制代码
|
|