modbus2002-1d.asm
来自「自已编写的MODBUS程序」· 汇编 代码 · 共 1,722 行 · 第 1/4 页
ASM
1,722 行
CPL P2.2 ;清看门狗
CLR P2.3 ;转换通道。
CLR TONGXUN_ZX ;置与CPU通讯位
CLR JI_JIAOYAN ;置偶校验标志
CLR TI
CLR RI
MOV 2DH, #00 ;每次,清与CPU通讯故障标志位
MOV TH1, R5
MOV TL1, R6
CLR T35 ;清T35标志
MOV CISHU_T35,#01H ;送T35定时次数
SETB ET1 ;允许T1产生中断
SETB TR1 ;启动T1
CPL P2.2 ;清看门狗
SEND_1:
JBC T35, SEND_2 ;一次延时时间到,清标志转处理
JB P0.2, SEND_1 ;执行器没有响应继续查询(P0.2=0)?
CLR TR1 ;停T1定时器
CLR ET1 ;禁止T1中断
MOV R0, #50H ;送发送CPU数据首址
MOV R1, LONG_S_CPU ;送发送给CPU的数据长度
SEND_3: MOV A, @R0 ;取发送数据
MOV C, P ;取偶校验位
MOV TB8, C
MOV SBUF, A ;发送
JNB TI, $ ;发送未完等待
CLR TI ;清发送完成标志位
INC R0 ;地址加1
DJNZ R1,SEND_3 ;未完继续
; MOV SCON, #0D0H
CPL P2.2 ;清看门狗
MOV R0, #58H ;准备接受
MOV R1,LONG_R_CPU ;送接收长度
RECE_1: CLR T35 ;清T35标志
MOV CISHU_T35,#01 ;送T35定时次数
MOV TH1, R5
MOV TL1, R6
SETB ET1 ;允许T1产生中断
SETB TR1 ;启动T1
RECE_2: JBC T35,SEND_2 ;延时时间到,转出错处理子程序1
JNB RI,RECE_2 ;没有接收数据继续查询
CLR RI ;有数据,清接收标志位
CLR ET1 ;禁止T1中断
CLR TR1 ;停T1定时器
JNB JIAOYAN,RECE_3
MOV A, SBUF ;增加偶校验
JNB P, VERIFY_0
JB RB8, RECE_3
SJMP COMM_ERR4 ;增加偶校验完毕--
RECE_3: MOV @R0, A ;存数据
INC R0 ;地址加1
DJNZ R1, RECE_1 ;未完继续
CLR T35 ;再次,清T35标志!!
MOV A, 50H ;发送命令=接收命令吗?
XRL A, 58H
JNZ COMM_ERR2
MOV 2DH,#00H ;OK,清通讯标志.
COMM_END:
SETB P2.3 ;换回总线通道
SETB TONGXUN_ZX ;置与总线通讯位
CLR JIESHOU_WAN ;清接收完标志位
CLR MANG ;清接收处理标志位
MOV C, P1.7
JC APPLY_OVER
CLR P1.6 ;总线仲裁完毕,复位/A
COMM_OVER:
LCALL T2_MAKE ;换总线用波特率
POP PSW ;恢复现场
POP ACC
RET
SEND_2:
CPL P2.2 ;清看门狗
CLR TR1
CLR ET1
MOV A, CISHU_CPU
JZ COMM_ERR1
DEC CISHU_CPU
LJMP APPLY_1
VERIFY_0:
JB RB8, COMM_ERR4
SJMP RECE_3
COMM_ERR1:
SETB TONGXUN_CPU_ERR ;与CPU通讯总故障
SETB TIME_O_CPU ;与CPU通讯超时
SJMP COMM_END
COMM_ERR2:
SETB TONGXUN_CPU_ERR ;与CPU通讯总故障
SETB FEIFA_CPU ;与CPU通讯非法命令
COMM_ERR4:
MOV R6, CISHU_CPU
CJNE R6,#00H,COMM_ERR40
SETB TONGXUN_CPU_ERR ;与CPU通讯总故障
SETB JIAOYAN_CPU_ERR ;与CPU通讯校验故障
SJMP COMM_END
COMM_ERR40:
LJMP SEND_2
LJMP START ;软件抗干扰语句
APPLY_OVER:
CLR P1.4 ;总线仲裁完毕,复位/B
SJMP COMM_OVER
;------------------****延时140微秒子程序****-------------
DELAY_140:
PUSH ACC ;保护现场
MOV A, #28H ;赋计数次数
DELAY1: DEC A
JNZ DELAY1 ;未完继续
POP ACC ;恢复现场
RET
;-----------------****延时100毫秒子程序****--------------
DELAY_100mS: ;延时计算公式:T=()*12/fosc
PUSH ACC ;保护现场
MOV A, #0EEH ;赋计数次数
DELAY2: LCALL DELAY_140 ;延时140微秒
LCALL DELAY_140 ;延时140微秒
LCALL DELAY_140 ;延时140微秒
DEC A
JNZ DELAY2 ;未完继续
POP ACC ;恢复现场
RET
LJMP START ;软件抗干扰语句
;---------------****总线发送子程序****-------------
SEND_BUS: ;入口:LONG_S_BUS MODE17
PUSH PSW ;保护现场
SETB P2.1 ;禁止接收
SETB P2.7 ;发送允许
CLR ES ;禁止接收中断
JB GUANGBO,SEND_BUS_END ;广播不回发数据
MOV R0, #48H ;送待发送数据首地址
JNB MODE17, SEND_BUS0 ;是F17功能吗?
MOV R0, #30H ;功能5/6/15/16/17时从30H开始
SEND_BUS0:
SETB TB8 ;TB8=1
MOV SBUF, @R0 ;发送地址
JNB TI, $ ;发送未完成等待
CLR TI ;清发送完成标志位
LCALL DELAY_140 ;延时0.5T/38.400KBPS
DJNZ LONG_S_BUS,SEND_BUS1
SJMP SEND_BUS_END
SEND_BUS1:
LCALL DELAY_140
INC R0 ;地址加1
CLR TB8 ;TB8=0
MOV SBUF, @R0 ;发送
JNB TI, $ ;发送未完等待
CLR TI ;清发送完成标志位
DJNZ LONG_S_BUS,SEND_BUS1 ;未完继续
SEND_BUS_END:
CLR P2.7 ;禁止发送
CLR P2.1 ;允许接收
CLR MODE17 ;清F17功能标志
SETB ES ;允许接收中断
POP PSW ;恢复现场
RET
LJMP START ;软件抗干扰语句
;----------------------****CRC校验子程序****-----------------
CRC: ;入口(数据首)地址=20H(21H),数据长度=22H
;23H=低位 24=高位
;22H=待校验数据长度
PUSH PSW ;保护现场
CLR RS1 ;取RAM01区
SETB RS0
MOV R1, 22H ;取要进行校验的实际数据长度
MOV R0, 20H ;送CRC校验数据首地址
MOV R7, #0FFH ;R7为CRC校验寄存器低位
MOV R6, #0FFH ;R6为CRC校验寄存器高位
CRC0: MOV A, R6 ;取高位
XRL A, @R0 ;得出index
INC R0 ;地址指针指向下一位数据
MOV R5, A ;R5暂存变量
MOV DPTR, #TAB6 ;送高位表基址
MOVC A, @A+DPTR ;查表得校验高位数据
XRL A, R7 ;异或CRC低位
MOV R6, A ;存高位CRC结果
MOV DPTR, #TAB5 ;送低位表基址
MOV A, R5
MOVC A, @A+DPTR ;查表得校验低位数据
MOV R7, A ;存低位CRC结果
DJNZ R1, CRC0 ;未完继续
MOV 23H, R6 ;CRC计算结果送出口寄存器(23H--低位)
MOV 24H, R7 ;24H存CRC校验高位结果
POP PSW ;恢复现场
RET
LJMP START ;软件抗干扰语句
;---------------------****判断是否溢出子程序****-------------------
OVER_FLOW: ;说明: 本程序只适用于01,02,03,04,15,16功能
MOV 2FH, #00H
MOV A, 32H
JNZ OVER_FLOW1 ;地址溢出,转处理
MOV DPTR, #TAB7 ;送数据表基址
MOV A, 31H ;取功能码
MOVC A,@A+DPTR ;查表得数据(=最大地址+1)
MOV B, A ;暂存
MOV A, 33H ;地址溢出?
CLR C
SUBB A, B
JNC OVER_FLOW1 ;地址溢出,转处理
MOV A, 34H
JNZ OVER_FLOW2 ;长度溢出,转处理
MOV A, 31H ;取功能码
MOV DPTR, #TAB7 ;送数据表基址
MOVC A,@A+DPTR ;查表得数据(=最大长度+1)
INC A
MOV B, A ;暂存
MOV A, 35H ;长度溢出?
JZ OVER_FLOW2 ;数据长度为0?
ADD A, 33H
CLR C
SUBB A, B
JNC OVER_FLOW2 ;长度溢出,转处理
RET
OVER_FLOW1:
SETB DIZHI_Z_ERR ;置地址错误(溢出)标志
RET
OVER_FLOW2:
SETB SHUJU_Z_ERR ;置数据错误(长度溢出)标志
RET
LJMP START ;软件抗干扰语句
;---------------------****T1装载服务子程序****----------------
; T1计时时间为T35
T1_MAKE:
PUSH ACC ;保护现场
PUSH B
MOV A, BOTELU ;取波特率设定值
ANL A, #0FH ;取低位数据---波特率代码
JB TONGXUN_ZX, T1MAKE0 ;是与总线通讯吗 ?
MOV A, #08H ;与CPU通讯时波特率为38400BPS
T1MAKE0:MOV B, A
MOV DPTR, #TAB2 ;送代码表基址
MOVC A, @A+DPTR ;查表取得T1低位重装值
MOV TL1, A ;T1低位装载
MOV R6, A
MOV A, B
ADD A, #09H ;取得高位代码
MOVC A, @A+DPTR ;查表取得T1高位重装值
MOV TH1, A ;T1高位装载
MOV R5, A
MOV DPTR, #TAB3
MOV A, B
MOVC A, @A+DPTR ;查表取得T35重装值
MOV CISHU_T35,A
POP B ;恢复现场
POP ACC
RET
LJMP START ;软件抗干扰语句
;--------------------****定时/计数器2设定子程序****---------------
T2_MAKE: ;在与执行器未取得联系时,与执行器的通讯波特率为9600BPS
CLR TR2 ;停T2
MOV T2CON, #30H ;RCLK=TCLK=1
MOV A, #08H ;与CPU通讯时波特率为38400BPS
JNB TONGXUN_ZX,T2_MAKE0 ;是与CPU通讯吗 ?
MOV A, BOTELU ;取波特率设定值
ANL A, #0FH ;取低位数据---波特率代码
MOV B, A ;波特率代码有误?
CLR C
SUBB A, #09H
MOV A, B
JNC T2_MAKE2
T2_MAKE0:
MOV B, A
MOV DPTR, #TAB4 ;送代码表基址
MOVC A, @A+DPTR ;查表取得T2低位重装值
MOV RCAP2L, A ;T2低位装载
MOV A, B
ADD A, #09H ;取得高位代码
MOVC A, @A+DPTR ;查表取得T2高位重装值
MOV RCAP2H, A ;T2高位装载
SETB TR2 ;启动定时器2
RET
T2_MAKE2: ;波特率代码出错处理
MOV R0, #0A7H
MOV @R0, #00H
INC R0
MOV @R0, #00H
LJMP START
;***********************中断服务程序区*****************************
;***////串行接收中断服务子程序////***
SIO_INT: ;*********SM2=0*******,接收总线数据
PUSH ACC ;保护现场
PUSH PSW
CLR RS0 ;RAM 02区
SETB RS1
JNB RI,SIO_INT_END ;是接收中断?
CLR RI
CLR ES ;转为查询方式
CLR JIESHOU_WAN
JB MANG,SIO_INT_E ;忙?
CLR GUANGBO
MOV A, SBUF ;数据暂存
MOV B, A
JNZ SIO_INT_A ;广播?
SETB GUANGBO
SJMP SIO_INT_B
SIO_INT_A:
MOV R0, #9DH ;呼叫本卡?
XRL A, @R0
JNZ SIO_INT_END
SIO_INT_B:
MOV R0, #30H
MOV R1, #00H
MOV @R0, B ;存数据
LCALL T1_MAKE
MOV R4, CISHU_T35
SIO_INT_C:
INC R0 ;地址加1
INC R1 ;数据长度加1
CLR T35
CLR TR1
MOV TH1, R5 ;T1装载
MOV TL1, R6
MOV CISHU_T35,R4
SETB ET1 ;允许T1中断
SETB TR1 ;启动T1
SIO_INT_D:
JBC T35,SIO_INT_OVER
JNB RI, SIO_INT_D
CLR RI
MOV @R0, SBUF ;接收数据
SJMP SIO_INT_C
SIO_INT_E: ;忙处理
MOV R0, #99H ;送从机总线忙低位地址(=98H\99H,高位在前)
MOV A, @R0
CLR C
ADD A, #01H ;从机忙次数加1
MOV @R0, A ;存从机忙低位
DEC R0
CLR A
ADDC A, @R0
MOV @R0, A ;存从机忙高位
SJMP SIO_INT_END
SIO_INT_OVER:
SETB JIESHOU_WAN
MOV LONG_R_BUS,R1
SIO_INT_END:
CLR T35 ;等待下一次中断
CLR TR1
SETB ES
POP PSW ;恢复现场
POP ACC
RETI
LJMP START ;软件抗干扰语句
;-------------**** T1中断服务子程序 ***-----------------
T1_INT:
CLR TR1 ;停计时器1
CPL P2.2 ;清看门狗
DJNZ CISHU_T35,T1_INT1 ;T35计时到了吗 ?
CLR ET1 ;禁止T1中断
SETB T35 ;置T35计时到标志
RETI
T1_INT1:MOV TH1, R5 ;T1进行装载
MOV TL1, R6
SETB TR1 ;启动T1
RETI
LJMP START ;软件抗干扰语句
;-----------------------**** 功能散转表 ****----------------
TAB0:
LJMP FUNCTION01 ; 功能F01
LJMP FUNCTION02 ; 功能F02
LJMP FUNCTION03 ; 功能F03
LJMP FUNCTION04 ; 功能F04
LJMP FUNCTION05 ; 功能F05
LJMP FUNCTION06 ; 功能F06
LJMP FUNCTION07 ; 功能F07
LJMP FUNCTION08 ; 功能F08(CPU支持?)
LJMP ERROR ; ERROR
LJMP ERROR ; ERROR
LJMP ERROR ; ERROR
LJMP ERROR ; ERROR
LJMP ERROR ; ERROR
LJMP ERROR ; ERROR
LJMP FUNCTION15 ; 功能F15
LJMP FUNCTION16 ; 功能F16
LJMP FUNCTION17 ; 功能F17(CPU不支持)
LJMP START ;若程序出错,则复位
;------------**** T1计数用的不同时间常数 ****-----------------
TAB1: DB 'WRICH RQM MODBUS MODULE ** M1.01'
; 以下18个子节为T35计数T1重装值,低位重装值
TAB2: DB 00H,00H,00H,80H, 40H, 20H, 90H,0C8H, 64H
DB 04H,19H,19H,8CH,0C6H,0E3H,0F1H,0F8H,0FCH
;-----------------****以下为T35计数次数表****----------------------
TAB3: DB 05H,02H,01H,01H, 01H, 01H, 01H, 01H, 01H
;------------------**** 与回路通讯的波特率 ****--------------------
; 以下18个字节为波特率代码-------CPU时钟为11.0592MHz
; 0.11, 0.3, 0.6, 1.2, 2.4, 4.8, 9.6,19.2,38.4-----对应波特率
TAB4: DB 0BAH, 80H,0C0H,0E0H, 70H,0B8H,0DCH,0EEH,0F7H ;T2低位重装值
DB 0F3H,0FBH,0FDH,0FEH,0FFH,0FFH,0FFH,0FFH,0FFH ;T2高位重装值
;------------------**** CRC校验用表 ****------------------------
; 以下为校验表低位数据
TAB5: DB 00H,0C0H,0C1H, 01H,0C3H, 03H, 02H,0C2H,0C6H, 06H, 07H,0C7H, 05H,0C5H,0C4H
DB 04H,0CCH, 0CH, 0DH,0CDH, 0FH,0CFH,0CEH, 0EH, 0AH,0CAH,0CBH, 0BH,0C9H, 09H
DB 08H,0C8H,0D8H, 18H, 19H,0D9H, 1BH,0DBH,0DAH, 1AH, 1EH,0DEH,0DFH, 1FH,0DDH
DB 1DH, 1CH,0DCH, 14H,0D4H,0D5H, 15H,0D7H, 17H, 16H,0D6H,0D2H, 12H, 13H,0D3H
DB 11H,0D1H,0D0H, 10H,0F0H, 30H, 31H,0F1H, 33H,0F3H,0F2H, 32H, 36H,0F6H,0F7H
DB 37H,0F5H, 35H, 34H,0F4H, 3CH,0FCH,0FDH, 3DH,0FFH, 3FH, 3EH,0FEH,0FAH, 3AH
DB 3BH,0FBH, 39H,0F9H,0F8H, 38H, 28H,0E8H,0E9H, 29H,0EBH, 2BH, 2AH,0EAH,0EEH
DB 2EH, 2FH,0EFH, 2DH,0EDH,0ECH, 2CH,0E4H, 24H, 25H,0E5H, 27H,0E7H,0E6H, 26H
DB 22H,0E2H,0E3H, 23H,0E1H, 21H, 20H,0E0H,0A0H, 60H, 61H,0A1H, 63H,0A3H,0A2H
DB 62H, 66H,0A6H,0A7H, 67H,0A5H, 65H, 64H,0A4H, 6CH,0ACH,0ADH, 6DH,0AFH, 6FH
DB 6EH,0AEH,0AAH, 6AH, 6BH,0ABH, 69H,0A9H,0A8H, 68H, 78H,0B8H,0B9H, 79H,0BBH
DB 7BH, 7AH,0BAH,0BEH, 7EH, 7FH,0BFH, 7DH,0BDH,0BCH, 7CH,0B4H, 74H, 75H,0B5H
DB 77H,0B7H,0B6H, 76H, 72H,0B2H,0B3H, 73H,0B1H, 71H, 70H,0B0H, 50H,090H,091H
DB 51H,093H, 53H, 52H,092H, 96H, 56H, 57H,097H, 55H,095H,094H, 54H,09CH, 5CH
DB 5DH,09DH, 5FH,09FH,09EH, 5EH, 5AH, 9AH,09BH, 5BH,099H, 59H, 58H,098H, 88H
DB 48H, 49H, 89H, 4BH,08BH, 8AH, 4AH, 4EH, 8EH, 8FH, 4FH, 8DH, 4DH, 4CH, 8CH
DB 44H, 84H, 85H, 45H, 87H, 47H, 46H, 86H, 82H, 42H, 43H,83H,41H,81H,80H,40H
; CRC校验表高位
TAB6: DB 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H
DB 40H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 00H,0C1H, 81H, 40H, 01H,0C0H
DB 80H, 41H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 00H,0C1H, 81H, 40H, 01H
DB 0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 01H,0C0H, 80H, 41H
DB 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 00H,0C1H, 81H
DB 40H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 01H,0C0H
DB 80H, 41H, 00H,0C1H, 81H, 40H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 01H
DB 0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H
DB 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H
DB 40H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 01H,0C0H
DB 80H, 41H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 00H,0C1H, 81H, 40H, 01H
DB 0C0H, 80H, 41H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H
DB 00H,0C1H, 81H, 40H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H
DB 40H, 01H,0C0H, 80H, 41H, 01H,0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 01H,0C0H
DB 80H, 41H, 00H,0C1H, 81H, 40H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 01H
DB 0C0H, 80H, 41H, 00H,0C1H, 81H, 40H, 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H
DB 00H,0C1H, 81H, 40H, 01H,0C0H, 80H, 41H, 01H,0C0H, 80H,41H,00H,0C1H,81H,40H
;--------------**** 总线末地址溢出判断依据(总线最高地址+1)表 ****-----------------
TAB7:
;功能码: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
DB 00H,08H,18H,05H,02H,08H,05H,00H,00H,00H,00H,00H,00H,00H,00H,08H,05H
LJMP START ;若程序出错,则复位
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?