📄 实验九(点对点串行通信2)_接收.asm
字号:
;功能:在“串入并出”芯片扩展输出引脚基础上,增加串行通信
DISPBUF DATA 48H ;笔段码显示缓冲区:
;48H单元记录千位,49H单元记录百位
;4AH单元记录十位,4BH单元记录个位
RXDBuf DATA 30H ;接收缓冲区
RXDC DATA 50H ;发送/接收字节计数器
FRAMES BIT 07H ;信息帧开始标志
SDI BIT P1.2 ;串行数据输入
SCLK BIT P3.4 ;串行数据移位脉冲
PCLK BIT P3.5 ;并行锁存脉冲
ORG 0000H
LJMP MAIN
ORG 0023H
LJMP UART ;跳串行口中断服务程序入口地址
ORG 0050H
;-----主程序开始-----
PROC MAIN
MAIN:
MOV SP, #0DFH ;对于具有256字节内部RAM芯片来说,
;将0E0H-0FFH,共计32字节作为堆栈区
MOV DPTR, #8000H ;关闭蜂鸣器
MOV A, #0FFH
MOVX @DPTR, A
;---复位后,将08H-0FF内部RAM单元清0。
MOV R7, #248
MOV R0, #08H
LOOPIC1:
MOV @R0, #0
INC R0
DJNZ R7, LOOPIC1
;初始化定时器T1(作串行通信波特率发生器输入信号)
MOV TL1, #250 ;4800波特率对应定时器初值
MOV TH1, #250
ANL TMOD, #0F0H
ORL TMOD, #00100000B ;定时器T1工作在方式2(8位自动重装初值)
SETB TR1 ;启动定时器T1
CLR ET1 ;禁止T1中断
;初始化串行口
MOV SCON, #11010000B ;串行口工作在方式3,SM2=0,以便用TB8位
;作奇偶校验位。
;SETB REN ;允许接收
ORL PCON, #40H ;将b6位置1,启用帧错误侦测功能
;-----初始化中断控制器
SETB ES ;允许串行口中断
SETB EA ;开中断
;接收显示处理
WAIT:
MOV R0, #RXDBuf+4
MOV A, @R0 ;读接收缓冲区有效标志
JNB ACC.7, WAIT ;接收缓冲区无效,等待
CLR ACC.7
MOV @R0, A ;清接收缓冲区有效标志
;把接收缓冲区信息送显示缓冲区显示
MOV DPTR, #LEDTAB ;0-F字模表首地址送DPTR
MOV R0, #DISPBUF
MOV R1, #RXDBuf
MOV R7, #4
LOOP1:
MOV A, @R1 ;取显示数码
MOVC A, @A+DPTR ;取数码对应字模
MOV @R0, A ;字模送显示缓冲区
INC R0
INC R1
DJNZ R7, LOOP1
;显示分与秒之间的小数点
MOV R0, #DISPBUF+1
MOV A, @R0
CLR ACC.7 ;使b7,即DP位亮
MOV @R0, A ;回写
SETB REN ;允许串行口接收新的数据
LCALL S_DISP ;执行串行输出子程序,将笔段码送LED
SJMP WAIT ;等待
END
PROC S_DISP ;串行输出子程序
S_DISP:
MOV R0, #DISPBUF ;显示缓冲区首地址送R0
MOV R7, #4
LOOP2:
MOV A, @R0
MOV R6, #8
LOOP1:
CLR SCLK
RLC A
MOV SDI, C ;串行数据送SDI引脚
NOP
SETB SCLK ;锁存串行输入数据
DJNZ R6, LOOP1
;取下一显示码
INC R0
DJNZ R7, LOOP2
;4位笔段码已全部移到串入并出芯片中
CLR PCLK
NOP ;延迟一个机器周期
SETB PCLK
RET
END
PROC UART ;串行中断服务子程序
UART:
PUSH ACC
PUSH PSW
SETB RS0 ;切换工作寄存器区
SETB RS1
JNB RI, NEXT1
CLR RI ;清除接收中断
;串行接收有效
JBC SCON.7, RERROR ;帧错误
MOV A, SBUF
;执行奇偶校验,P标志与RB8位应该相同,否则就错
MOV C, P
ANL C, /RB8 ;计算P. /RB8
MOV F0, C ;暂时保存F0标志中
MOV C, RB8
ANL C, /P ;计算RB8. /P
ORL C, F0 ;完成了P与RB8的异或运算!
JC RERROR ;奇偶校验错!
;奇偶校验正确!判别是否为帧首信息
CJNE A, #0AAH, NEXT11
;等于0AAH,属于一信息帧开始
MOV RXDC, #0 ;复位接收字节计数器
SETB FRAMES ;帧开始标志有效
SJMP NEXT1
NEXT11:
;非帧首信息
JNB FRAMES, RERROR ;在这之前尚未接收到帧开始标志
;当前接收内容为帧内数据信息
MOV A, RXDC
ADD A, #RXDBuf ;加接收缓冲区首地址
MOV R0, A
MOV @R0, SBUF ;接收数据送接收缓冲区
INC RXDC ;接收字节计数器加1
;判别接收的字节数
MOV A, RXDC
CJNE A, #5, NEXT1
;已经接收了5字节,做和校验
MOV R0, #RXDBuf
MOV R7, #4 ;对30~33H单元求和,共4字节
CLR A ;清累加器
LOOP1:
ADD A, @R0 ;累加求和
INC R0
DJNZ R7, LOOP1
XRL A, @R0 ;与接收到的和校验字节异或
JNZ RERROR
;正确
MOV A, @R0
ORL A, #80H
MOV @R0, A ;接收缓冲区数据有效标志
MOV A, #0A5H ;发送0A5H应答信号
CLR REN ;停止接收,等待处理接收数据
SJMP TXDACK
RERROR:
MOV A, #0A6H ;错误标志
TXDACK:
CLR FRAMES ;清除帧开始标志
MOV RXDC, #0 ;复位接收字节计数器
MOV C, P ;奇偶标志P送C
MOV TB8, C ;奇偶标志P送TB8,即b8位
MOV SBUF, A ;写串行口缓冲寄存器,启动发送
SJMP EXIT
NEXT1:
JNB TI, EXIT
;串行发送结束中断
CLR TI ;清除发送结束中断
EXIT:
POP PSW
POP ACC
RETI
END
LEDTAB: ;八段LED共阳数码管字模
;数码 0 1 2 3 4 5 6 7
DB 0C0H, 0F9H, 0A4H, 0B0H, 99H, 92H, 82H, 0F8H
;数码 8 9 A B C D E F
DB 80H, 90H, 88H, 83H, 0C6H, 0A1H, 86H, 8EH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -