DELY2: DJNZ R4, DELY2
DJNZ R3, DELY1 DJNZ R2, DELY0 RET END
8.试设计一个8051单片机的双机通信系统,串行口工作在方式1,波特率为2400bps,编程将甲机片内RAM中40H~4FH的数据块通过串行口传送到乙机片内RAM的40H~4FH单元中。 答案:
双方约定的通信协议如下:
甲机先发送请求乙机接收信号“0AAH”,乙机收到该信号后,若为准备好状态,一个则发送数据“0BBH”作为应答信号,表示同意接收。当甲机发送完16个字节后,再向乙机发送一个累加校验和。校验和是针对数据块进行的,即在数据发送时,发送方对块中的数据简单求和,产生一个单字节校验字符(校验和),附加到数据块结尾。在数据接收时,接收方每接收一个数据也计算一次校验和;接收完数据块后,再接收甲机发送的校验和,并将接收到的校验和与乙机求出的校验和进行比较,向甲机发送一个状态字,表示正确(00H)或出错(0FFH),出错则要求甲机重发。甲机收到收到乙机发送的接收正确应答信号(00H)后,即结束发送,否则,就重发一次数据。
甲机采用查询方式进行数据发送,乙机采用中断方式进行数据接收。双方约定传输波特率为2400bps,两机主频均为11.059MHz,双机串行口都工作于方式1,查表6-2可知SMOD=0,定时器T1采用工作模式2,初值为F4H。
甲机发送子程序:
ORG 2000H
SEND: MOV TMOD, #20H ; 定时器1设为模式2
MOV TL1, #0F4H
MOV TH1, #0F4H ; 置定时器初值 SETB TR1 ; 启动T1
MOV SCON, #50H ; 设串行口为方式2 MOV PCON, #00H ; SMOD=0
TLLS: MOV SBUF, #0AAH ; 发送请求接收信号
29
WFS1: JBC TI, RYD1 ; 等待发送
SJMP WFS1
RYD1: JBC RI, RYD2 ; 等待乙机回答
SJMP RYD1
RYD2: MOV A, SBUF ; 接收应答信号
XRL A, #0BBH
JNZ TLLS ; 乙机未准备好,继续联络 SDD1: MOV R0, #40H ; 首地址40H→R0
MOV R1, #10H ; 数据个数→R1 MOV R2, #00H ; 清校验和寄存器 SDD2: MOV SBUF, @R0 ; 发送一个数据
MOV A, R2
ADD A, @R0 ; 求校验和 MOV R2, A ; 保存校验和 INC R0
WFS2: JBC TI, SDD3 ; 等待发送
SJMP WFS2
SDD3: DJNZ R1, SDD2 ; 数据块是否发送完
MOV SBUF, R2 ; 发送校验和 WFS3: JBC TI, RYD3
SJMP WFS3
RYD3: JBC RI, RYD4 ; 等待乙机回答
SJMP RYD3
RYD4: MOV A, SBUF
JNZ SDD1 ; 回答出错则重发 RET 乙机接收子程序:
ORG 2000H
RECV: MOV TMOD, #20H ; 定时器1设为模式2
MOV TL1, #0F4H
MOV TH1, #0F4H ; 置定时器初值 SETB TR1 ; 启动T1
MOV SCON, #50H ; 设串行口为方式2 MOV PCON, #00H ; SMOD=0
MOV R0, #40H ; 首地址40H→R0 MOV R1, #10H ; 数据个数→R1 MOV 50H, #00H ; 清校验和寄存器 SETB 7FH SETB 7EH ; 标志位初始置1 SETB ES ; 允许接收中断 SETB EA ; 开中断 LOOP: SJMP LOOP ; 等待中断
中断服务子程序:
CLR EA CLR RI ; 清中断 JB 7FH, RCMD ; 是请求接收信号吗 JB 7EH, DATA ; 是数据块吗 MOV A, SBUF ; 接收校验和
CJNE A, 50H, ERR ; 判断发送是否正确 MOV A, #00H
30
WFS1: MOV CLR JNB SBUF, A TI, WFS1 ; 正确,发 00H
; 等待发送
ERR: SJMP MOV RETN
TI A, #0FFH
WFS2: MOV CLR JNB SBUF, A T TI, WFS2 ; 出错,发 0FFH
; 等待发送
RCMD: SJMP XRL MOV AGAN
I A, SBUF ; 接收甲机请求信号JZ A, #0AAH
TYDX: SJMP TYDX WFS3: CLR MOV RETN
JNB SBUF, #0BBH ; 发送应答信号0BBH CLR TI TI, WFS3 ; 等待发送
DATA: SJMP 7FH MOV MOV RETN
A, SBUF ; 接收数据
INC R0, A ADD DPTR MOV A, 50H DJNZ 50H, A ; 求校验和 CLR R; 保存校验和 7EH 1, RETN AGAN: SJMP RETN ; 数据接收完后清数据标志位 SETB SETB 7FH MOV 7EH
MOV DPTR, #2000H ; 恢复标志位; 首地址2000H
→DPTR RETN: MOV R1, #10 50H, #00H ; 数据个数→R1 RETI
SETB EA ; ; 清校验和寄存器开中断
9.8051以方式2进行串行通信,假定波特率为1200bps,第9位作奇偶校验位,以中断方式发送。请编写程序。 答案:
主程序:
MAIN: ORG
MOV SCON, #80H
2000H
; 将串行口设置为方式2,REN=1
MOV MOV PCON, #00H MOV R0, #30H R1, #50H ; SMOD=0
MOV ; ; 发送数据区首地址→SETB R2, #20
; 接收数据区首地址→R0 置发送数据个数→R2
R1 LOOP: SETB E SJMP ES LOOP A
; ; 开中断等待中断
31
中断服务子程序:
ORG 0023H
AJMP SOUT ; 转至中断服务程序 ORG 0200H
SOUT: CLR TI ; 清发送中断标志
DJNZ R2, LOOP1 ; 数据未发送完,继续发送 SJMP RR1 ; 发送完返回
LOOP1: MOV A, @R0 ; 取发送数据到A
MOV C, PSW.0 MOV TB8, C
MOV SBUF, A ; 发送数据
INC R0 ; 指向下一个数据 RR1: RETI
10.8051以方式3进行串行通信,假定波特率为1200bps,第9位作奇偶验位,以查询方式接收。请编写程序。 答案:
ORG 2000H
RECV: MOV TMOD, #20H ; 定时器1设为模式2
MOV TL1, #0E8H
MOV TH1, #0E8H ; 置定时器初值 SETB TR1 ; 启动T1
MOV SCON, #0D0H ; 将串行口设置为方式3,REN=1 MOV PCON, #00H ; SMOD=0
MOV R1, #20H ; 接收数据区首地址→R1 MOV R2, #16 ; 置发送数据个数→R2 WAIT: JBC RI, PRI ; 等待接收到数据
SJMP WAIT
PRI: MOV A, SBUF ; 读接收数据
JNB PSW.0, PZEO ; P=0则跳转
JNB RB8, ERR ; P=1,RB8=0转至出错 SJMP RIGHT ; P=1,RB8=1转至正确 PZEO: JB RB8, ERR ; P=0,RB8=1转至出错 RIGHT: MOV @R1, A ; 存放数据
INC R1 ; 指向下一个存储单元
DJNZ R2, WAIT ; 未接收完则继续接收 CLR F0 ; F0=0 RET
ERR: CLR REN
SETB F0 ; 置F0=1 RET
11.RS-232C总线标准是如何定义其逻辑电平的?实际应用中可以将MCS-51单片机串行口和PC机的串行口直接相连吗?为什么?
答案:
32