标题:
51单片机主机和多台从机之间通信串行通信汇编程序
[打印本页]
作者:
daniu
时间:
2014-12-26 22:37
标题:
51单片机主机和多台从机之间通信串行通信汇编程序
;主机和多台从机之间通信。通信协议如下:
;(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
复制代码
作者:
hongfeng0107
时间:
2017-11-11 12:01
可以请教您问题吗
作者:
SOPHHANA
时间:
2018-4-25 09:54
偷一手代码,溜了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1