📄 comm485.asm
字号:
DEL: MOV R7,#20 ;延时程序DELAY 10MS
DEL1: MOV R6,#125
CPL WDT
DEL2: DJNZ R6,DEL2
DJNZ R7,DEL1
RET
;入口:R7 = 要求延时的ms数
_DELAY: MOV R5,#2 ;1ms延时子程序
DELAY1: MOV R6,#154
CPL WDT
DJNZ R6,$
DJNZ R5,DELAY1
DJNZ R7,_DELAY
RET
ANSWER: CPL WDT ;向发送缓冲区中写入应答帧
CLR EA
MOV DEST,#00H ;将接收到的源地址放入DEST
MOV B,#00H
LCALL WBUF ;将DEST写入发送缓冲指针对应的第1位(目的地址)
MOV B,NETNO ; 将NETNO写入第2位(源地址)SOURCE
LCALL WBUF
MOV B,#3
LCALL WBUF ;将长度写入第3位(LENGTH)(应答帧长度为3)
MOV B,#01H
LCALL WBUF ;将类型写入第4位(TYPE)(应答帧类型为1)
CPL WDT
SETB EA
RET
WBUF: MOV DPTR,#TRBUF
MOV A,SPT+01H
ADD A,DPL
MOV DPL,A
MOV A,SPT
ADDC A,DPH
MOV DPH,A
MOV A,B
MOVX @DPTR,A
MOV A,SPT+01H
ADD A,#01H
MOV SPT+01H,A
MOV A,SPT
ADDC A,#00H
ANL A,#03H
MOV SPT,A
RET
SIOT: CPL WDT
JBC RI,SIOT0 ;串行中断服务程序(RI=1则将RI清零并转移,表示由接收引起中断)
CLR TI ;由发送引起中断时,先将TI清零,再判断TSN的状态
JB TSN,SIOTC ;TSN=1表示有数据要正在发送,则转入下一步
RETI ;TSN=0表示无需要发送的数据,退出中断;
SIOT0: JNB TSN,SIOTC ;TSN=0表示无需要发送的数据,可进行下一步
RETI ;TSN=1表示有数据正在发送,退出中断;
SIOTC: PUSH PSW
MOV C,WXYF
ORL C,FSCF
ORL C,CRCF
ORL C,JSCF
JNC SIOT1 ;C=0表示无出错,则转到SIOT1;C=1表示有错,退出中断
POP PSW
CPL WDT
RETI
SIOT1: PUSH ACC ;SIO RS-485 INTERRUPT SEVEICE
PUSH B
PUSH DPH
PUSH DPL
SETB RS1 ;选取2区寄存器
CLR RS0
JB TSN,LKLK ;TSN=1表示有数据要正在发送,则转入发送子程序LKLK
LJMP RECEV ;TSN=0表示无需要发送的数据,则转入接收子程序RESEV
SIOT10: AJMP RS100
LKLK: CPL WDT
MOV A,SBUF ;发送子程序
CJNE A,15H,SIOT10 ;接收积存器的内容是否等于发送的数据(A=R5?)
JNB TFS,RS00 ;发送完毕标志TFS=0表示一帧数据尚未发完,转到RS00继续发送
SETB SM2 ;若TFS=1则表示一帧数据已发完,将SM2置位,保持接收地址状态
CLR TSN ;将发送标志清零表示无需要发送的数据
CLR DRV485 ;置485口为接收状态
ANL TPT,#03H
MOV A,TPT+01H
ADD A,#3
PUSH ACC
MOV A,TPT
ADDC A,#00H
ANL A,#03H
MOV B,A
;ADD A,#TRBUF
MOV DPTR,#TRBUF
POP ACC
ADD A,DPL
MOV DPL,A
MOV A,DPH
ADDC A,B
MOV DPH,A
MOVX A,@DPTR
;MOV R0,A
;MOV A,@R0 ;此时指向这一帧的类型位
CJNE A,#1,RS000 ;检查这一帧是否为应答帧,若为应答帧则将ONLPT的内容赋给TPT(即将TPT指向下一帧的起始位置)
;ANL ONLPT,#7FH
;MOV TPT,ONLPT
MOV TPT+01H,ONLPT+01H
MOV TPT,ONLPT
CLR TFS ;清发送完毕标志TFS
MOV CFCS,#0 ;清重发次数
JB STNO,RSRET
LJMP RSRET
;MOV WXYCOUNT,#150 ;(SET TIME FOR TRANS CONFIRM)MAIN 150*20.8MS ; 若这一帧为非应答帧则将WXYCOUNT置为150
RS000: ;MOV WXYCOUNT+01H,#0B8H
MOV WXYCOUNT,#60
CLR WXYF ;清无响应标志
LJMP RSRET
RS00: CPL WDT
MOV A,R2 ;R2在TRANS子程序中传第一位时清零,每传一位加1
CJNE A,16H,RS01 ;IF DATA TRANS FINISH? R2=R6(R6在TRANS子程序中放置一帧的长度)
MOV A,CRC1 ;TRANS CRC1
LJMP RS03
RS01: JC RS02
MOV A,CRC2 ;TRANS CRC2
SETB TFS ;将TFS置位
LJMP RS03
RS02: CPL WDT
;ANL ONLPT,#7FH
;MOV A,ONLPT
;INC ONLPT ;将在线发送指针加1
;ANL A,#7FH
;ADD A,#TRBUF
MOV A,ONLPT+01H
ADD A,#01H
MOV ONLPT+01H,A
MOV A,ONLPT
ADDC A,#00H
ANL A,#03H
MOV ONLPT,A
;MOV R0,A ;将要传输的数送入A
;MOV A,@R0
MOV DPTR,#TRBUF
MOV A,ONLPT+01H
ADD A,DPL
MOV DPL,A
MOV A,DPH
ADDC A,ONLPT
MOV DPH,A
MOVX A,@DPTR
CLR TB8 ;清TB8表示此次发送的是数据而非地址
CLR SM2 ;SM2清零,可接收数据
MOV R5,A ;将所传输的数据送入R5
INC R2 ;传输位数加1
PUSH ACC
LCALL CPCRC ;调用CRC校验子程序
POP ACC
MOV SBUF,A ;将所要传输的数据送入SBUF
AJMP RSRET
RS03: CPL WDT
MOV R5,A ;将所传输的数据送入R5
INC R2 ;传输位数加1
MOV SBUF,A ;将本帧最后一位数据送入SBUF
RSRET: POP DPL ;退出串行中断
POP DPH
POP B
POP ACC
POP PSW
CPL WDT
RETI
RS100: SETB FSCF ;将发送错置位
CLR DRV485 ;将485口置接收状态
CLR RSN ;将接收标志清零
LJMP RS09 ;将B2BTIME和接收错标志清零
RECEV: CPL WDT
MOV A,SBUF ;接收数据子程序
MOV R7,A
JB RSN, RS04 ;接收标志位RSN=1表示正在接收则转到RS04;RSN=0表示接收第1位
MOV BCOUNT,#00H
MOV A,NETNO ;ADD*16+01H(在发送目的地址时有同样的操作)
rl A
ORL A,#01H
CJNE A,17H,RS101 ;R7 PSW=10 判断接收的目的地址是否与本站号一致
MOV R7,NETNO ;若一致则将站号赋予R7,否则转到RS101
RS102: JB RFS,RSRET ;接收完毕标志RFS=1表示一帧数据已接收完毕退出串行中断;
SETB RSN ;RFS=0表示还有数据需要接收。先将接收标志位RSN置1
CLR SM2 ;允许接收数据位
MOV WXYCOUNT,#00H ;将WXYCOUNT无响应标志清零
CLR WXYF ;无响应标志清零
MOV CRC1,#00H ;CRC1、CRC2清零
MOV CRC2,#00H
MOV ONLRPT,RPT ;接收指针RPT清零
MOV ONLRPT+01H,RPT+01H
CPL WDT
RS04:
;INC RPT ;具体接收数据部分
;ANL ONLRPT+01H,#0FFH ;将接收指针RPT加1,指向下一位
;ANL ONLRPT,#03H
;MOV R3,RPT ;将位数放入R7
MOV DPTR,#REBUF
;ADD A,RPT
;MOV R0,A
MOV A,DPL
ADD A,ONLRPT+01H
MOV DPL,A
MOV A,DPH
ADDC A,ONLRPT
MOV DPH,A
MOV A,R7 ;SBUF
MOVX @DPTR,A
PUSH ACC
MOV A,ONLRPT+01H
ADD A,#01H
MOV ONLRPT+01H,A
MOV A,ONLRPT
ADDC A,#0H
ANL A,#03H
MOV ONLRPT,A
POP ACC
;INC RPT ;将接收的数据放入对应的接收缓冲区
LCALL CPCRC ;调用CRC校验子程序
MOV A,BCOUNT
CJNE A,#02H,RS06 ;R3=2指本帧对应长度位IF DATA LENTH?
MOV A,R7 ;SBUF
ADD A,#02H
MOV R4,A ;将接收的长度位值+2送入R4
RS05: CPL WDT
INC BCOUNT
MOV B2BTIME,#3 ;一帧数据接收完毕前B2BTIME=#4(SET TIME OF BYTE-BYTE)
CLR JSCF
RS050: LJMP RSRET
RS101: MOV A,R7 ;目的地址与本站号不一致时的处理子程序
CJNE A,#0FFH,RS050 ;判断目的地址是否为FFH(复位消音)
mov r7,#7fh
LJMP RS102
RS06: JC RS05 ;R3为0或1时,转移到RS05,重新开始
MOV A,BCOUNT ;R3=2指本帧对应长度位
CJNE A,14H,RS05 ;R3=R4?判断是否接收完毕(相等则指本位为本帧最后一位)
CLR RSN ;清接收标志
SETB SM2 ;允许接收地址
;MOV R0,#REBUF+3
;MOV A,@R0
;CJNE A,#1,RS060 ;判断本帧是否为应答帧(@4E03=1时为应答帧)RECEIVE RESPNSE
;CPL WDT
;JB TFS,RS08 ;若本帧为应答帧且发送完毕标志TFS为1时,不进行CRC判断
RS060: MOV A,CRC1 ;当本帧不为应答帧或为应答帧但TFS=0时进行CRC判断
JNZ RS07
MOV A,CRC2
JZ RS08
RS07: SETB CRCF ;若CRC判断出错则将CRCF置位
AJMP RS09
RS08: SETB RFS ;本帧为应答帧且TFS为1或CRC判断正确时,将接收完毕标志RFS置位
MOV RPT,ONLRPT
MOV RPT+01H,ONLRPT+01H
CPL WDT
RS09: MOV B2BTIME,#00H ;清B2BTIME、接收错标志JSCF,并结束CLEAR TIME OF BYTE-BYTE
CLR JSCF
LJMP RSRET
CPCRC: CPL WDT
XRL A,CRC1 ;CRC校验子程序
CLR C
RLC A
MOV DPL,A
MOV A,#TABH
ADDC A,#0
MOV DPH,A
CLR A
MOVC A,@A+DPTR
XRL A,CRC2
MOV CRC1,A
MOV A,#1
MOVC A,@A+DPTR
MOV CRC2,A
RET
SETRRPT: ;将接收缓冲区处理指针指到下一条事件
MOV DPTR,#REBUF
MOV A,RRPT+01H
ADD A,DPL
MOV DPL,A
MOV A,RRPT
ADDC A,DPH
MOV DPH,A
INC DPTR
INC DPTR
MOV A,DPH
ANL A,#03H
MOV DPH,A
MOVX A,@DPTR
ADD A,#3
ADD A,RRPT+01H
MOV RRPT+01H,A
MOV A,#0
ADDC A,RRPT
ANL A,#03H
MOV RRPT,A
RET
ADDDPTR: ;DPTR + B A ->DPTR
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A
RET
PEXCH: MOV DPL,R6 ;@R7R6 -> @R5R4
MOV DPH,R7
MOVX A,@DPTR
MOV B,A
INC DPTR
MOV A,DPH
ANL A,#3H
MOV R7,A
MOV R6,DPL
MOV DPL,R4
MOV DPH,R5
MOV A,B
MOVX @DPTR,A
INC DPTR
MOV R4,DPL
MOV R5,DPH
DJNZ R3,PEXCH
RET
PROCBUF:LCALL GETNUM ;处理接收缓冲区的事件,将其放到相应的事件列表
; MOV DPTR,#FIRENUM
MOVX A,@DPTR
PUSH ACC
XRL A,#0FFH
JZ PROCBUF2
PROCBUF1:
POP ACC
MOV B,#32
MUL AB
MOV R0,A
MOV R1,B
LCALL GETBUF
; MOV DPTR,#FIRE
MOV B,R1
MOV A,R0
LCALL ADDDPTR
MOV R5,DPH
MOV R4,DPL
MOV R3,#32
MOV DPTR,#REBUF
MOV A,RRPT+01H
MOV B,RRPT
LCALL ADDDPTR
MOV A,DPH
ANL A,#3H
MOV DPH,A
MOV A,#4H
MOV B,#0H
LCALL ADDDPTR
MOV A,DPH
ANL A,#3H
MOV DPH,A
MOV R7,DPH
MOV R6,DPL
LCALL PEXCH
LCALL GETNUM
; MOV DPTR,#FIRENUM
MOVX A,@DPTR
INC A
MOVX @DPTR,A
LCALL SETRRPT
RET
PROCBUF2:
POP ACC
LCALL GETFST
;MOV DPTR,#FIREFIRST
MOVX A,@DPTR
MOV B,#32
MUL AB
MOV R1,B
MOV R0,A
LCALL GETBUF
; MOV DPTR,#FIRE
MOV B,R1
MOV A,R0
LCALL ADDDPTR
MOV R5,DPH
MOV R4,DPL
MOV R3,#32
MOV DPTR,#REBUF
MOV A,RRPT+01H
MOV B,RRPT
LCALL ADDDPTR
MOV A,DPH
ANL A,#3H
MOV DPH,A
MOV A,#4H
MOV B,#0H
LCALL ADDDPTR
MOV A,DPH
ANL A,#3H
MOV DPH,A
MOV R7,DPH
MOV R6,DPL
LCALL PEXCH
LCALL GETFST
MOVX A,@DPTR
INC A
MOVX @DPTR,A
LCALL SETRRPT
RET
GETNUM: MOV DPTR,#TMPNUM
MOVX A,@DPTR
MOV B,A
MOV DPTR,#TMPNUM+01H
MOVX A,@DPTR
MOV DPL,A
MOV DPH,B
RET
GETBUF: MOV DPTR,#TMPBUF
MOVX A,@DPTR
MOV B,A
MOV DPTR,#TMPBUF+01H
MOVX A,@DPTR
MOV DPL,A
MOV DPH,B
RET
GETFST: MOV DPTR,#TMPFST
MOVX A,@DPTR
MOV B,A
MOV DPTR,#TMPFST+01H
MOVX A,@DPTR
MOV DPL,A
MOV DPH,B
RET
CSEG AT 700H
TAB: DB 00H,00H,89H,11H,12H,23H,9BH,32H
DB 24H,46H,0ADH,57H,36H,65H,0BFH,74H
DB 48H,8CH,0C1H,9DH,5AH,0AFH,0D3H,0BEH
DB 6CH,0CAH,0E5H,0DBH,7EH,0E9H,0F7H,0F8H
DB 81H,10H,08H,01H,93H,33H,1AH,22H
DB 0A5H,56H,2CH,47H,0B7H,75H,3EH,64H
DB 0C9H,9CH,40H,8DH,0DBH,0BFH,52H,0AEH
DB 0EDH,0DAH,64H,0CBH,0FFH,0F9H,76H,0E8H
DB 02H,21H,8BH,30H,10H,02H,99H,13H
DB 26H,67H,0AFH,76H,34H,44H,0BDH,55H
DB 4AH,0ADH,0C3H,0BCH,58H,8EH,0D1H,9FH
DB 6EH,0EBH,0E7H,0FAH,7CH,0C8H,0F5H,0D9H
DB 83H,31H,0AH,20H,91H,12H,18H,03H
DB 0A7H,77H,2EH,66H,0B5H,54H,3CH,45H
DB 0CBH,0BDH,42H,0ACH,0D9H,9EH,50H,8FH
DB 0EFH,0FBH,66H,0EAH,0FDH,0D8H,74H,0C9H
DB 04H,42H,8DH,53H,16H,61H,9FH,70H
DB 20H,04H,0A9H,15H,32H,27H,0BBH,36H
DB 4CH,0CEH,0C5H,0DFH,5EH,0EDH,0D7H,0FCH
DB 68H,88H,0E1H,99H,7AH,0ABH,0F3H,0BAH
DB 85H,52H,0CH,43H,97H,71H,1EH,60H
DB 0A1H,14H,28H,05H,0B3H,37H,3AH,26H
DB 0CDH,0DEH,44H,0CFH,0DFH,0FDH,56H,0ECH
DB 0E9H,98H,60H,89H,0FBH,0BBH,72H,0AAH
DB 06H,63H,8FH,72H,14H,40H,9DH,51H
DB 22H,25H,0ABH,34H,30H,06H,0B9H,17H
DB 4EH,0EFH,0C7H,0FEH,5CH,0CCH,0D5H,0DDH
DB 6AH,0A9H,0E3H,0B8H,78H,8AH,0F1H,9BH
DB 87H,73H,0EH,62H,95H,50H,1CH,41H
DB 0A3H,35H,2AH,24H,0B1H,16H,38H,07H
DB 0CFH,0FFH,46H,0EEH,0DDH,0DCH,54H,0CDH
DB 0EBH,0B9H,62H,0A8H,0F9H,9AH,70H,8BH
DB 08H,84H,81H,95H,1AH,0A7H,93H,0B6H
DB 2CH,0C2H,0A5H,0D3H,3EH,0E1H,0B7H,0F0H
DB 40H,08H,0C9H,19H,52H,2BH,0DBH,3AH
DB 64H,4EH,0EDH,5FH,76H,6DH,0FFH,7CH
DB 89H,94H,00H,85H,9BH,0B7H,12H,0A6H
DB 0ADH,0D2H,24H,0C3H,0BFH,0F1H,36H,0E0H
DB 0C1H,18H,48H,09H,0D3H,3BH,5AH,2AH
DB 0E5H,5EH,64H,4FH,0F7H,7DH,7EH,6CH
DB 0AH,0A5H,83H,0B4H,18H,86H,91H,97H
DB 2EH,0E3H,0A7H,72H,3CH,0C0H,0B5H,0D1H
DB 42H,29H,0CBH,38H,50H,0AH,0D9H,1BH
DB 66H,6FH,0EFH,7EH,74H,4CH,0FDH,5DH
DB 8BH,0B5H,02H,0A4H,99H,96H,10H,87H
DB 0AFH,0F3H,26H,0E2H,0BDH,0D0H,34H,0C1H
DB 0C3H,39H,4AH,28H,0D1H,1AH,58H,0BH
DB 0E7H,7FH,6EH,6EH,0F5H,5CH,7CH,4DH
DB 0CH,0C6H,85H,0D7H,1EH,0E5H,97H,0F4H
DB 28H,80H,0A1H,91H,3AH,0A3H,0B3H,0B2H
DB 44H,4AH,0CDH,5BH,56H,69H,0DFH,78H
DB 60H,0CH,0E9H,1DH,72H,2FH,0FBH,3EH
DB 8DH,0D6H,04H,0C7H,9FH,0F5H,16H,0E4H
DB 0A9H,90H,20H,81H,0BBH,0B3H,32H,0A2H
DB 0C5H,5AH,4CH,4BH,0D7H,79H,5EH,68H
DB 0E1H,1CH,68H,0DH,0F3H,3FH,7AH,2EH
DB 0EH,0E7H,87H,0F6H,1CH,0C4H,95H,0D5H
DB 2AH,0A1H,0A3H,0B0H,38H,82H,0B1H,93H
DB 46H,6BH,0CFH,7AH,54H,48H,0DDH,59H
DB 62H,2DH,0EBH,3CH,70H,0EH,0E9H,1FH
DB 8FH,0F7H,06H,0E6H,9DH,0D4H,14H,0C5H
DB 0ABH,0B1H,22H,0A0H,0B9H,92H,30H,83H
DB 0C7H,7BH,4EH,6AH,0D5H,58H,5CH,49H
DB 0E3H,3DH,6AH,2CH,0F1H,1EH,78H,0FH
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -