📄 hm8.asm
字号:
;8比特汉明码模拟通讯程序
SADDR EQU 2000H ;原始数据区首址。
DADDR EQU 2040H ;模拟接收数据区首址。
BUF EQU 2100H ;模拟发送缓冲区首址。
NUMB DATA 30H ;数据个数存放单元。
ERR BIT 00H ;出错标志。
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV NUMB,#20H ;原始数据个数。
MOV R3,#20H
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 R0,#LOW(BUF)
LCALL TRANS ;用查表法生成汉明码模拟发送。
MOV DPTR,#DADDR ;模拟接收数据保存区首址。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R0,#LOW(BUF)
LCALL RECEV ;模拟接收,数据应该正确。
MOV DPTR,#DADDR ;模拟接收数据保存区首址。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R0,#LOW(BUF)
LCALL RECEV2 ;用查表法再接收一次,应该取得同样的效果。
MOV P2,#HIGH(BUF) ;在模拟通讯缓冲区子制造一个差错。
MOV R0,#LOW(BUF)+5 ;
MOVX A,@R0 ;
XRL A,#02H ;
MOVX @R0,A ;
MOV DPTR,#DADDR ;模拟接收数据保存区首址。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R0,#LOW(BUF)
LCALL RECEV ;再接收一次,应该能够纠正这个差错。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R0,#LOW(BUF)+6 ;在模拟通讯缓冲区子制造两个差错。
MOVX A,@R0 ;
XRL A,#11H ;
MOVX @R0,A ;
MOV DPTR,#DADDR ;模拟接收数据保存区首址。
MOV P2,#HIGH(BUF) ;模拟发送缓冲区首址。
MOV R0,#LOW(BUF)
LCALL RECEV ;再接收一次,这两个差错将被发现。
STOP: LJMP STOP ;
TRANS: MOV A,NUMB ;取数据个数。
MOV R2,A ;暂存。
LCALL OUTB ;将数据长度发送出去。
TRNS: MOVX A,@DPTR ;读取一个字节数据。
LCALL OUTB ;发送出去。
INC DPTR ;调整数据指针。
DJNZ R2,TRNS ;发送完全部数据。
RET ;发送结束。
OUTB: MOV R3,A ;暂存。
SWAP A ;准备发送高四位。
LCALL OUT ;发送出去。
MOV A,R3 ;准备发送低四位。
OUT: ANL A,#0FH ;取低四位十六进制数。
ADD A,#2 ;调整查表位置。
MOVC A,@A+PC ;查表。
SJMP OUT1
DB 00H,71H,0B2H,0C3H;十六个8比特汉明码。
DB 0D4H,0A5H,66H,17H
DB 0E8H,99H,5AH,2BH
DB 3CH,4DH,8EH,0FFH
OUT1: MOVX @R0,A ;模拟输出到缓冲区。
INC R0
RET
RECEV: CLR ERR ;出错标志初始化。
LCALL INBY ;从串行口输入一个字节。
MOV NUMB,A ;保存数据长度。
MOV R2,A
RECV: LCALL INBY ;从串行口输入一个字节。
MOVX @DPTR,A ;存入数据区。
INC DPTR ;调整数据指针。
DJNZ R2,RECV ;输入全部数据。
RET ;接收结束。
INBY: LCALL INB ;从串行口输入四位信息。
SWAP A ;高四位。
MOV R3,A ;暂存。
LCALL INB ;再从串行口输入四位信息。
ORL A,R3 ;低四位与高四位拼接成一个字节。
RET
INB: MOVX A,@R0 ;从缓冲区读取一个数据。
INC R0
MOV C,PSW.0 ;保存全字节偶校验结果。
MOV F0,C
ANL A,#7FH ;取7比特汉明码。
MOV R4,A ;暂存。
ANL A,#4DH ;对D1、D3、D5、D7进行偶校验。
MOV C,PSW.0 ;取校验结果(C1)。
MOV B.0,C ;存入C1中。
MOV A,R4 ;取接收到的汉明码。
ANL A,#2BH ;对D2、D3、D6、D7进行偶校验。
MOV C,PSW.0 ;取校验结果(C2)。
MOV B.1,C ;存入C2中。
MOV A,R4 ;取接收到的汉明码。
ANL A,#17H ;对D4、D5、D6、D7进行偶校验。
MOV C,PSW.0 ;取校验结果(C3)。
MOV B.2,C ;存入C3中。
MOV A,B ;取三个校验结果。
ANL A,#7
JZ CHG4 ;汉明码无差错,信息有效。
JB F0,CHG ;差错判断。
SETB ERR ;发现两个差错,设立出错标志。
CHG: INC A
MOVC A,@A+PC ;一个差错,查表得到纠错位置码。
SJMP CHG1
DB 40H,20H,08H,10H
DB 04H,02H,01H
CHG1: XRL A,R4 ;纠错处理。
MOV R4,A ;保存纠错后的汉明码。
CHG4: MOV A,R4 ;取正确的汉明码。
ANL A,#0FH ;分离出4比特信息位。
RET
RECEV2: CLR ERR ;出错标志初始化。
LCALL INBY2 ;从串行口输入一个字节。
MOV NUMB,A ;保存数据长度。
MOV R2,A
RECV2: LCALL INBY2 ;从串行口输入一个字节。
MOVX @DPTR,A ;存入数据区。
INC DPTR ;调整数据指针。
DJNZ R2,RECV2 ;输入全部数据。
RET ;接收结束。
INBY2: LCALL INB2 ;从串行口输入四位信息。
SWAP A ;高四位。
MOV R3,A ;暂存。
LCALL INB2 ;再从串行口输入四位信息。
ORL A,R3 ;低四位与高四位拼接成一个字节。
RET
INB2: MOVX A,@R0 ;从串行口读取一个数据。
INC R0
PUSH DPH
PUSH DPL
MOV DPTR,#LISB ;DPTR指向译码表。
MOVC A,@A+DPTR ;查译码表。
JNB ACC.7,INE
SETB ERR ;发现两个差错,设立出错标志。
INE: POP DPL
POP DPH
RET
DATS: DB 00H,01H,02H,03H,04H,05H,06H,07H
DB 08H,09H,0AH,0BH,0CH,0DH,0EH,0FH
DB 10H,11H,12H,13H,14H,15H,16H,17H
DB 18H,19H,1AH,1BH,1CH,1DH,1EH,1FH
LISB: DB 0,0,0,0FFH,0,0FFH,0FFH,7 ;256字节译码表。
DB 0,0FFH,0FFH,0BH,0FFH,0DH,0EH,0FFH
DB 0,0FFH,0FFH,7,0FFH,7,7,7
DB 0FFH,9,0AH,0FFH,0CH,0FFH,0FFH,07
DB 0,0FFH,0FFH,0BH,0FFH,5,6,0FFH
DB 0FFH,0BH,0BH,0BH,0CH,0FFH,0FFH,0BH
DB 0FFH,1,2,0FFH,0CH,0FFH,0FFH,7,0CH
DB 0FFH,0FFH,0BH,0CH,0CH,0CH,0FFH
DB 0,0FFH,0FFH,3,0FFH,0DH,6,0FFH,0FFH
DB 0DH,0AH,0FFH,0DH,0DH,0FFH,0DH
DB 0FFH,1,0AH,0FFH,4,0FFH,0FFH,7
DB 0AH,0FFH,0AH,0AH,0FFH,0DH,0AH,0FFH
DB 0FFH,1,6,0FFH,6,0FFH,6,6
DB 8,0FFH,0FFH,0BH,0FFH,0DH,6,0FFH
DB 1,1,0FFH,1,0FFH,1,6,0FFH,0FFH
DB 1,0AH,0FFH,0CH,0FFH,0FFH,0FH
DB 0,0FFH,0FFH,3,0FFH,5,0EH,0FFH
DB 0FFH,9,0EH,0FFH,0EH,0FFH,0EH,0EH
DB 0FFH,9,2,0FFH,4,0FFH,0FFH,7
DB 9,9,0FFH,9,0FFH,9,0EH,0FFH
DB 0FFH,5,2,0FFH,5,5,0FFH,5
DB 8,0FFH,0FFH,0BH,0FFH,5,0EH,0FFH
DB 2,0FFH,2,2,0FFH,5,2,0FFH
DB 0FFH,9,2,0FFH,0CH,0FFH,0FFH,0FH
DB 0FFH,3,3,3,4,0FFH,0FFH,3
DB 8,0FFH,0FFH,3,0FFH,0DH,0EH,0FFH
DB 4,0FFH,0FFH,3,4,4,4,0FFH
DB 0FFH,9,0AH,0FFH,4,0FFH,0FFH,0FH
DB 8,0FFH,0FFH,3,0FFH,5,6,0FFH
DB 8,8,8,0FFH,8,0FFH,0FFH,0FH
DB 0FFH,1,2,0FFH,4,0FFH,0FFH,0FH
DB 8,0FFH,0FFH,0FH,0FFH,0FH,0FH,0FH
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -