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 + -
显示快捷键?