modbus2002-1d.asm
来自「自已编写的MODBUS程序」· 汇编 代码 · 共 1,722 行 · 第 1/4 页
ASM
1,722 行
;*******************************************************
; 文件名:研究所7\\D:\DJW\ASM\MODBUS2002-1d.asm *
; 本次修改日期:2002/01/10 *
; 版本:MODBUSCHEN---001 *
; 程序编写:董建伟、程为彬 *
; 程序用途:MODBUS总线通讯接口 *
;*******************************************************
;--------------------回路波特率寄存器---------------
;RAM--28H
CHUANKOU_FSH3 BIT 44H ;串行口只工作于方式3
JI_JIAOYAN BIT 46H ;奇校验, 否则偶校验!
JIAOYAN BIT 47H ;需要校验,否则不校验
;------------------与主板通讯故障标志---------------
;RAM--2DH
ZUTAI1_ERR BIT 68H ;一类组态错误
ZUTAI2_ERR BIT 69H ;二类组态错误
ZUTAI3_ERR BIT 6AH ;三类组态错误
JIAOYAN_CPU_ERR BIT 6CH ;与CPU通讯校验出错
TIME_O_CPU BIT 6DH ;与CPU通讯超时
FEIFA_CPU BIT 6EH ;CPU发回非法命令
TONGXUN_CPU_ERR BIT 6FH ;与CPU通讯故障
;-------------------程序循环用标志------------------
;RAM--2EH
T35 BIT 70H ;T35(即3.5T)计时到
MANG BIT 71H ;从机忙(标志位)
ZHITING_MODE BIT 72H ;只听模式判断位
JIESHOU_WAN BIT 73H ;有/无接收数据
TONGXUN_ZX BIT 74H
;总线/CPU通讯状态(1=与总线通讯,0 =与CPU通讯)
GUANGBO BIT 75H ;广播状态
;-------------------总线通讯故障标志----------------
;RAM--2FH
CHANGDU_Z_ERR BIT 78H ;总线长度错误
SHUJU_Z_ERR BIT 79H ;总线数据错误
DIZHI_Z_ERR BIT 7AH ;总线地址错误
GONGNENG_Z_ERR BIT 7BH ;总线功能码错误
CRC_ERR BIT 7CH ;CRC校验错误
MODE17 BIT 7DH ;总线功能F17标志位
;-------------------T2波特率发生器启动位------------
TR2 BIT 0CAH ;定时/计数器2允许位
;-------------------与主板通讯用寄存器---------------
LONG_S_CPU EQU 18H ;发送给CPU的数据的长度
LONG_R_CPU EQU 19H ;接收到的CPU数据长度
;------------------与回路通讯用寄存器-----------------
LONG_S_BUS EQU 1AH ;发送到总线的数据长度
LONG_R_BUS EQU 1BH ;接收到的总线数据长度
;--------------------与主板通讯用寄存器---------------
DIZHI_R_CPU EQU 1CH ;终存CPU来数据首址
CISHU_CPU EQU 1DH ;与CPU通讯次数
CISHU_T35 EQU 1EH ;T35计数次数寄存器
;-----------------回路波特率寄存器(同上)------------
BOTELU EQU 28H ;本卡波特率寄存器
;------------------T2专用寄存器-----------------------
TL2 EQU 0CCH ;定时/计数器2(低位字节)
TH2 EQU 0CDH ;定时/计数器2(高位字节)
RLDL EQU 0CAH ;定时/计数器2(低位字节)再装载
RLDH EQU 0CBH ;定时/计数器2(高位字节)再装载
T2CON EQU 0C8H ;定时/计数器2控制寄存器
RCAP2L EQU 0CAH ;TIME2自动重装载低位
RCAP2H EQU 0CBH ;TIME2自动重装载高位
;---------------------------存储器RAM区分配-------------------
; 接收总线数据区: 30H--47H ;发送总线数据区: 48H--4FH
; 发送CPU数据区: 50H--57H ;接收CPU数据区: 58H--5FH
; 堆栈区: 60H--7FH ( 共32字节)
;---------------------------控制寄存器分配--------------------
;80H,81H--线圈输出继电器(高位/低位) 注:高位=0无效
;82H,83H--输入状态寄存器1(高位/低位) 注:高位=0无效
;84H,85H--输入状态寄存器2(高位/低位) 注:高位=0无效
;86H,87H--输入状态寄存器3(特殊状态)(高位/低位) 注:高位=0无效
;88H,89H--扭矩反馈值(高位/低位) 0-FFFFH
;8AH,8BH--阀位反馈值(高位/低位) 0-FFFFH
;8CH,8DH--控制寄存器(高位/低位) 未用!!
;8EH,8FH--阀位寄存器(高位/低位) 0-FFFFH
;90H,91H--死区寄存器(高位/低位) 0-FF00H(低位为00H)
;92H,93H--MIT寄存器(高位/低位) 0-FF00H(低位为00H)
;94H,95H--低信阀位(高位/低位) 0-FFFFH
;96H,97H--高信阀位(高位/低位) 0-FFFFH
;98H,99H--从机忙(高位/低位) 0-FFFFH
;9AH,9BH--总线访问计数器(高位/低位) 0-FFFFH
;9CH,9DH--本卡地址寄存器(高位/低位) 注:高位=0无效
;9EH,9FH--本卡波特率暂存器(高位/低位) 注:高位=0无效
;A0H,A1H--CPU诊断寄存器(高位/低位) 注:高位=0无效
;A7H--0ABH--上电/手动/死循环判断寄存器区(“89C55”的ASCII码)
;-------------------------------------------------------------
ORG 0000H
LJMP START
ORG 001BH ;T1中断服务程序入口
LJMP T1_INT
ORG 0023H ;接收中断服务程序入口
LJMP SIO_INT
ORG 0100H
;--------------------------初始化------------------------------
;默认回路波特率设为38400BPS------------默认回路波特率设为38400BPS
START:
MOV SCON, #0D0H ;设定串行口工作于方式3允许接收
MOV SP, #5FH ;设置堆栈
MOV PSW, #00 ;RAM--00区
MOV TMOD, #11H ;设定T1,T0工作方式=1
MOV TCON, #00 ;清TR1,TF1,
MOV IE, #00 ;禁止中断
MOV IP, #08H ;置T1中断优先级高
MOV P1, #0FFH
CLR P1.4 ;总线使用权初始化
CLR P1.6
CLR P0.0 ;清通讯卡(CC2)
CLR P2.7
CLR P2.1
SETB P2.3
CLR SM2
;-----------------------上电复位/看门狗复位判断----------------
MOV R0, #0A7H
CJNE @R0,#38H,MAKE_1 ; '8'
INC R0
CJNE @R0,#39H,MAKE_1 ; '9'
INC R0
CJNE @R0,#43H,MAKE_1 ; 'C'
INC R0
CJNE @R0,#35H,MAKE_1 ; '5'
INC R0
CJNE @R0,#35H,MAKE_1 ; '5'
LCALL T2_MAKE ;串行口波特率设定
AJMP MAKE_END
;-----------------------RAM区初始化----------------------------
MAKE_1: ;上电/清零区
MOV R0, #5FH ;RAM区00H---5FH初始化(全置为00)
MAKE_2: MOV @R0, #00H
DJNZ R0, MAKE_2
MOV R0, #68H ;RAM区80H---0FFH初始化
MAKE_3: MOV @R0, #00H
INC R0
CJNE R0,#0FFH,MAKE_3
;-------------------------硬上电复位置标志---------------------
MOV R0, #0A7H ;将89C55的ACSII写入A7H-ABH单元
MOV @R0, #38H ; '8'
INC R0
MOV @R0, #39H ; '9'
INC R0
MOV @R0, #43H ; 'C'
INC R0
MOV @R0, #35H ; '5'
INC R0
MOV @R0, #35H ; '5'
;----------------------取总线通讯回路默认参数值--------------------
MOV R0, #88H ;暂不用
MOV @R0, #00H
INC R0
MOV @R0, #00H ;扭矩反馈=0
MOV R0, #8AH
MOV @R0, #00H
INC R0
MOV @R0, #00H ;阀位反馈=0
MOV R0, #8EH
MOV @R0, #00H
INC R0
MOV @R0, #00H ;阀位设定=0
MOV R0, #90H
MOV @R0, #32H
INC R0
MOV @R0, #00H ;死区=5.0%=3200H/6400H
MOV R0, #92H
MOV @R0, #32H
INC R0
MOV @R0, #00H ;MIT=5.0S=3200H/6400H
MOV R0, #94H
MOV @R0, #00H
INC R0
MOV @R0, #00H ;低信阀位=0%
MOV R0, #96H
MOV @R0, #0FFH
INC R0
MOV @R0, #0FFH ;高信阀位=100%
MOV R0, #98H
MOV @R0, #00H
INC R0
MOV @R0, #00H ;从机忙次数=0
MOV R0, #9AH
MOV @R0, #00H
INC R0
MOV @R0, #00H ;总线访问次数=0
;-----------------------A卡/B卡取回路地址和波特率----------------
;注: 此过程成功后,MODBUS卡方可工作
FETCH_CPU:
MOV LONG_S_CPU,#01H ;发送给CPU的数据长度
MOV LONG_R_CPU,#03H ;接收CPU送来数据长度
MOV 50H, #01H ;默认送A卡命令码
JNB P1.7, FETCH_1
MOV 50H, #02H
FETCH_1:
LCALL COMM_CPU ;取设定参数,并转回总线通讯
CLR ES
JB TONGXUN_CPU_ERR,FETCH_ERR;与CPU通讯故障
CLR C
MOV A, 59H ;取回的地址有效?
SUBB A, #0F8H
JNC FETCH_ERR
CLR C ;取回的波特率代码有效?
MOV A, 5AH
SUBB A, #09H
JNC FETCH_ERR
MOV BOTELU, 5AH ;存波特率
MOV R0, #9DH
MOV @R0, 59H ;存地址
MOV R0, #9FH
MOV @R0, 5AH ;存波特率
SETB TONGXUN_ZX
CLR JIESHOU_WAN
SJMP MAKE_END
FETCH_ERR:
SETB ZUTAI1_ERR
SETB TONGXUN_CPU_ERR ;与CPU通讯总故障
MOV A, #0FFH ; 出错出错出错出错出错出错
CPL P1.0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CPL P2.2 ;清看门狗
SJMP FETCH_CPU
;**************///////主程序循环判断区////////**************
;---------------------无接受总线数据的循环------------------
MAKE_END:
SETB SM0
SETB SM1
CLR SM2 ;接收地址模式
SETB REN
CPL P2.2 ;清看门狗
CLR MANG ;清忙
SETB ES ;允许接收中断
JB JIESHOU_WAN,MAIN_C ;有待处理数据?
CLR T35 ;T35=0
CLR GUANGBO
SJMP MAKE_END
;--------------------有接受总线数据的循环-------------------
MAIN_C: MOV 20H, #30H
MOV A, LONG_R_BUS
DEC A
DEC A
CLR CRC_ERR ;清CRC_ERR标志
MOV 22H, A
LCALL CRC ;进行CRC校验
MOV A, 22H ;CRC校验通过吗?
ADD A, #30H
MOV R0, A
MOV A, @R0
XRL A, 23H
JNZ MAIN_CRC_ERR ;CRC出错,转CRC出错处理
INC R0
MOV A, @R0
XRL A, 24H
JNZ MAIN_CRC_ERR ;CRC出错,转CRC出错处理
CLR CRC_ERR
CLR GUANGBO ;广播标志处理:置位/复位。
MOV A, 30H ;地址=本卡或广播?
JNZ MAIN_D
SETB GUANGBO
MAIN_D: MOV R0, #9BH ;总线访问次数寄存器低位地址(高位在前)
MOV A, @R0
CLR C
ADD A, #01H ;总线访问次数加1
MOV @R0, A ;存总线访问次数低位
CLR A
DEC R0
ADDC A, @R0
MOV @R0, A ;存总线访问次数高位
JNB ZHITING_MODE,MAIN_E ;只听模式
MOV R7, 31H ;F08功能?
CJNE R7, #08,MAIN_F
MOV R7, 33H
CJNE R7, #01H,MAIN_F ;F08/01功能?
LJMP FUNC08_5_0
MAIN_F:
CLR JIESHOU_WAN
CLR MODE17
AJMP MAKE_END
MAIN_E: CLR JIESHOU_WAN ;JIESHOU_WAN=0
CLR ES ;禁止接收中断
CLR MODE17 ;MODE17=0
SETB MANG ;置开始处理接收数据标志
;---------------------------功能散转程序---------------------------
MOV A, 31H ;取总线功能码(存于31H中)
CLR C
DEC A
MOV B, A
SUBB A, #11H ;功能码越限(>=17?)?
JNC JMP_1
MOV A, B ;取总线功能码(存于31H中)
JMP_2: MOV B, #03H
MUL AB
MOV DPTR, #TAB0 ;送散转表首址
JMP @A+DPTR ;散转
AJMP MAKE_END
JMP_1: MOV A, #09H
SJMP JMP_2
MAIN_CRC_ERR:
SETB CRC_ERR ;置CRC校验未通过标志位
CLR JIESHOU_WAN ;JIESHOU_WAN=0
CLR MODE17 ;MODE17=0
CLR GUANGBO ;清广播标志.
AJMP MAKE_END
;---------------------****功能F01处理子程序****----------------
FUNCTION01:
LCALL OVER_FLOW ;判断地址,长度是否溢出.
JB SHUJU_Z_ERR,FUNC01_3 ;数据错误(长度溢出)?
JB DIZHI_Z_ERR,FUNC01_3 ;地址错误(地址溢出)?
;SJMP FUNC01_COMM_END
;------------****与CPU通讯,读输出线圈(8个)寄存器****------------
FUNC01_COMM:
MOV LONG_S_CPU,#01H
MOV LONG_R_CPU,#02H
MOV 50H, #03H ;与CPU通讯命令码=03H
LCALL COMM_CPU
JNB TONGXUN_CPU_ERR,FUNC01_COMM_OVER
MOV 4AH, #04H ;与CPU通讯故障
LJMP ERROR_TREAT
FUNC01_COMM_OVER: ;数据存取
MOV R0, #80H
MOV @R0, #00H
INC R0
MOV @R0, 59H
;----------------****功能F01与主板通讯结束****---------------------
FUNC01_COMM_END:
MOV A, 33H
MOV R0, #81H ;送输出线圈继电器地址(81H)
MOV B, @R0
MOV R7, A
JZ FUNC01_1 ;起始地址为0吗?
MOV A, B ;送数据
FUNC01_0:
CLR C ;C=0
RRC A
DJNZ R7, FUNC01_0 ;未完继续
MOV B, A ;暂存
FUNC01_1:
MOV A, #01H
MOV R7, 35H
FUNC01_2:
CLR C ;C=0
RLC A
DJNZ R7, FUNC01_2
DEC A
ANL A, B ;求有效数据
MOV 4BH, A ;送返回的数据
MOV 48H, 30H ;存返回地址
MOV 49H, 31H ;送返回的功能码
MOV 4AH, #01H ;送返回数据字节数
MOV 22H, #04H ;数据长度为4
MOV 20H, #48H ;起始地址为48H
LCALL CRC ;CRC计算使用RAM01区
MOV 4CH, 23H ;存CRC低位
MOV 4DH, 24H ;存CRC高位
MOV LONG_S_BUS,#06H ;送发送总线数据长度
LJMP EXIT
FUNC01_3:
LJMP ERROR_TREAT
;------------------------****功能F02处理子程序****-----------------
FUNCTION02:
LCALL OVER_FLOW ;判断地址,长度是否溢出.
JB SHUJU_Z_ERR,FUNC01_3 ;数据错误?
JB DIZHI_Z_ERR,FUNC01_3 ;地址错误?
;-------------------****与CPU通讯,读全部输入状态****--------------
;SJMP FUNC02_COMM_END
FUNC02_COMM:
MOV LONG_S_CPU,#01H ;与CPU通讯。
MOV LONG_R_CPU,#04H
MOV 50H,#04H ;命令=04H
; MOV DIZHI_R_CPU,#82H
LCALL COMM_CPU
JNB TONGXUN_CPU_ERR,FUNC02_COMM_OVER
MOV 4AH,#04H
LJMP ERROR_TREAT
FUNC02_COMM_OVER: ;数据存取
MOV R0,#83H
MOV @R0,59H ;高位不写,未用
MOV R0,#85H
MOV @R0,5AH
MOV R0,#87H
MOV @R0,5BH
;----------------****功能F02与主板通讯结束****---------------------
FUNC02_COMM_END:
MOV A, 35H ; 取长度
MOV B, #08H
DIV AB ;A商,B余数
MOV 4AH, A ;暂存
MOV A, B
JZ FUNC02_1
INC 4AH
FUNC02_1:
MOV R0, #87H ;送输入状态寄存器3地址
MOV A, @R0
MOV R1, A
MOV R0, #85H ;送输入状态寄存器2地址
MOV A, @R0
MOV R2, A
MOV R0, #83H ;送输入状态寄存器1地址
MOV A, @R0
MOV R3, A
MOV A, 35H ;取数据位长度
XRL A, #18H
JZ FUNC02_4 ;不需要任何移位 ?
MOV A, 35H
ADD A, 33H ;长度+首址=末址
MOV R7, A
MOV A, #18H
SUBB A, R7
JZ FUNC02_3 ;不用左移
MOV R7, A
FUNC02_2:
CLR C
MOV A, R3
RLC A
MOV R3, A
MOV A, R2
RLC A
MOV R2, A
MOV A, R1
RLC A
MOV R1, A
DJNZ R7, FUNC02_2
FUNC02_3:
MOV A, #18H
CLR C
SUBB A, 35H ;得到右移次数
MOV R7, A
FUNC02_3_A:
CLR C ;c=0
MOV A, R1
RRC A
MOV R1, A
MOV A, R2
RRC A
MOV R2, A
MOV A, R3
RRC A
MOV R3, A
DJNZ R7, FUNC02_3_A
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?