📄 rect.asm
字号:
;矩形码模拟通讯程序
SADDR EQU 2000H ;原始数据区首址。
DADDR EQU 2100H ;模拟接收数据区首址。
BUF EQU 2200H ;模拟发送缓冲区首址。
NUMB DATA 30H ;数据个数存放单元。
XCHG DATA 31H ;“行”校验字节。
YCHG EQU 40H ;“列”校验字节存放首址。
ERR BIT 00H ;出错标志。
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV NUMB,#80H ;原始数据个数。
MOV R3,#80H
MOV DPTR,#DATS
MOV P2,#HIGH(SADDR) ;片外RAM中数据存放首址。
MOV R0,#LOW(SADDR)
COPY: CLR A
MOVC A,@A+DPTR ;将测试数据存放到片外RAM中。
MOVX @R0,A
INC DPTR
INC R0
DJNZ R3,COPY
MOV DPTR,#SADDR ;原始数据首址。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R1,#LOW(BUF)
LCALL TRANS ;模拟发送。
MOV DPTR,#DADDR ;模拟接收数据保存区首址。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R1,#LOW(BUF)
LCALL RECEV ;模拟接收,数据应该正确。
MOV P2,#HIGH(BUF) ;在模拟通讯缓冲区子制造一个差错。
MOV R1,#LOW(BUF)+5 ;
MOVX A,@R1 ;
XRL A,#02H ;
MOVX @R1,A ;
MOV DPTR,#DADDR ;模拟接收数据保存区首址。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R1,#LOW(BUF)
LCALL RECEV ;再接收一次,应该能够纠正这个差错。
STOP: LJMP STOP ;
TRANS: CLR A
MOV XCHG,A ;“行”校验字节初始化。
MOV R2,#10H ;16个“列”校验字节初始化。
MOV R0,#YCHG
CLEAR: MOV @R0,A
INC R0
DJNZ R2,CLEAR
MOV R2,#8 ;发送8行。
LOOP: MOV R3,#10H ;每行16个字节。
MOV R0,#YCHG ;“列”校验位置初始化。
CLR F0 ;“行”校验位初始化。
LOOP1: MOVX A,@DPTR ;读取一字节数据。
JNB PSW.0,LOOP2 ;本字节偶校验。
CPL F0 ;累加到“行”校验位上。
LOOP2: MOV R4,A ;暂存数据内容。
XRL A,@R0 ;进行“列”校验。
MOV @R0,A
MOV A,R4 ;将本字节数据发送出去。
LCALL OUT
INC DPTR ;调整数据指针。
INC R0 ;调整“列”校验指针。
DJNZ R3,LOOP1 ;处理完一行。
MOV A,XCHG ;取“行”校验字节。
MOV C,F0 ;将本行偶校验位拼入“行”校验字节。
RRC A
MOV XCHG,A
DJNZ R2,LOOP ;发送完8行数据信息。
MOV R0,#YCHG ;发送16个字节的“列”校验信息。
MOV R2,#10H
LOOP3: MOV A,@R0
LCALL OUT
INC R0
DJNZ R2,LOOP3
MOV A,XCHG ;发送一个字节的“行”校验信息。
LCALL OUT
RET ;发送结束。
OUT: MOVX @R1,A ;发送到通讯缓冲区。
INC R1
RET
RECEV: CLR A ;接收程序。
MOV XCHG,A ;“行”校验字节初始化。
MOV R2,#10H ;16个“列”校验字节初始化。
MOV R0,#YCHG
CLE: MOV @R0,A
INC R0
DJNZ R2,CLE
CLR ERR ;出错标志初始化。
MOV R2,#8 ;接收8行数据。
LP: MOV R3,#10H ;每行16个字节。
MOV R0,#YCHG ;“列”校验位置初始化。
CLR F0 ;“行”校验初始化。
LP1: LCALL INBY ;输入一字节数据。
MOVX @DPTR,A ;存入数据区。
INC DPTR ;调整数据指针。
JNB PSW.0,LP2 ;本字节偶校验。
CPL F0 ;累加到“行”校验位上。
LP2: XRL A,@R0 ;进行“列”校验。
MOV @R0,A
INC R0 ;调整“列”校验指针。
DJNZ R3,LP1 ;处理完一行。
MOV A,XCHG ;取“行”校验字节。
MOV C,F0 ;将本行偶校验位拼入“行”校验字节。
RRC A
MOV XCHG,A
DJNZ R2,LP ;接收完8行数据信息。
MOV R3,#10H ;准备接收16个字节的“列”校验信息。
MOV R0,#YCHG ;“列”校验位置指针初始化。
CLR F0 ;“列”校验出错初始化。
LP3: LCALL INBY ;输入一字节数据。
XRL A,@R0 ;进行“列”校验核查。
JZ LP4 ;本列未发现差错。
SETB F0 ;本列校验出错。
MOV R5,A ;保存纠错信息。
MOV A,R0 ;计算列出错位置。
CLR C
SUBB A,#YCHG
MOV R4,A ;保存差错所在列字节位置。
LP4: INC R0 ;调整“列”校验指针。
DJNZ R3,LP3 ;核查完16列字节。
LCALL INBY ;输入“行”校验字节。
XRL A,XCHG ;核查“行”校验字节。
JNZ CHG1 ;“行”校验出错。
JNB F0,REND ;未发现差错,接收成功。
ERROR: SETB ERR ;找不到差错所在位置,差错可能不止一个。
REND: RET
CHG1: JNB F0,ERROR ;无法确定差错所在列。
MOV R3,#0 ;准备判断差错所在“行”。
CHG2: RRC A
JC CHG3 ;找到差错所在行。
INC R3 ;调整到下一行。
SJMP CHG2
CHG3: MOV A,DPL ;将DPTR调整到数据区首址。
CLR C
SUBB A,#80H
MOV DPL,A
JNC CHG4
DEC DPH
CHG4: MOV A,R3 ;计算差错所在位置。
SWAP A
ADD A,R4
ADD A,DPL
MOV DPL,A
JNC CHG5
INC DPH
CHG5: MOVX A,@DPTR ;纠正差错。
XRL A,R5
MOVX @DPTR,A
RET
INBY: MOVX A,@R1 ;从缓冲区读取一个数据。
INC R1
RET
DATS: DB 00H,27H,4BH,05H,06H,07H,08H,4CH
DB 4DH,4EH,4FH,50H,51H,52H,53H,54H
DB 55H,56H,57H,58H,59H,5AH,5BH,5CH
DB 5DH,5EH,5FH,60H,61H,62H,6EH,6FH
DB 70H,02H,03H,01H,24H,25H,26H,04H
DB 09H,0AH,0BH,0CH,0DH,0EH,0FH,10H
DB 11H,12H,13H,17H,18H,19H,1AH,1BH
DB 1CH,1DH,1EH,1FH,20H,21H,22H,23H
DB 71H,75H,76H,77H,78H,79H,28H,29H
DB 2AH,2BH,2CH,63H,64H,65H,66H,67H
DB 68H,69H,6AH,14H,15H,16H,72H,73H
DB 74H,6BH,6CH,6DH,2DH,2EH,2FH,30H
DB 31H,32H,33H,34H,35H,39H,3AH,3BH
DB 3CH,3DH,3EH,3FH,40H,41H,42H,43H
DB 44H,45H,46H,47H,48H,49H,4AH,7AH
DB 36H,37H,38H,7BH,7CH,7DH,7EH,7FH
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -