📄 从控测试程序.asm
字号:
MOV A,#10000011B
MOVX @DPTR,A
STRY_M13:
INC R5
POP ACC
CLR C
DJNZ R7,STRY_M11
MOV A,CURR_SRY00
MOV B,A
SETB C
CLR A
MOV R5,#0
MOV R7,#8
;-------------------根据从继电器开、关标志-------------------
STRY_S01:
RLC A
PUSH ACC
ANL A,B
JZ STRY_S02
MOV A,R5
LCALL OpenSlaveRelay
PUSH B
MOV DPTR,#METER_INF ; 电表当前信息首地址
MOV B,#5
MUL AB
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A ; 计算指定地址
INC DPTR
POP B
MOV A,#10000000B ;不过是不是=11000000H啊?
MOVX @DPTR,A
SJMP STRY_S03
STRY_S02:
MOV A,R5
LCALL CloseSlaveRelay
PUSH B
MOV DPTR,#METER_INF ; 电表当前信息首地址
MOV B,#5
MUL AB
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A ; 计算指定地址
INC DPTR
POP B
MOV A,#10000000B
MOVX @DPTR,A
STRY_S03:
INC R5
POP ACC
CLR C
DJNZ R7,STRY_S01
MOV A,CURR_SRY01
MOV B,A
SETB C
CLR A
MOV R5,#8
MOV R7,#8
STRY_S11:
RLC A
PUSH ACC
ANL A,B
JZ STRY_S12
MOV A,R5
LCALL OpenSlaveRelay
push b
MOV DPTR,#METER_INF ; 电表当前信息首地址
MOV B,#5
MUL AB
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A ; 计算指定地址
INC DPTR
POP B
MOV A,#10000000B
MOVX @DPTR,A
SJMP STRY_S13
STRY_S12:
MOV A,R5
LCALL CloseSlaveRelay
MOV DPTR,#METER_INF ; 电表当前信息首地址
MOV B,#5
MUL AB
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A ; 计算指定地址
INC DPTR
POP B
MOV A,#10000000B
MOVX @DPTR,A
STRY_S13:
INC R5
POP ACC
CLR C
DJNZ R7,STRY_S11
SETB ET1 ;开定时器1
SETB F_FLAG ; 分时间段限制电流比较标志 =1真确
RET
;********************************************************
;串口中断处理
;接收数据格式:地址+命令长度+命令+校验和
;注意: 命令长度不包括地址
;********************************************************
Serial:
PUSH PSW
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH DSP
PUSH AUXR1
SETB RS0
SETB RS1 ;
MOV DSP,#0
MOV AUXR1,#0 ;不过
JNB RI,SR_EX ; receive? not receive reti
CLR RI ; ---receive interrupt
;
MOV HALF_MINUTE,#0 ; 复位计数器
;
;------------------z 4.1\
clr line_led ;通讯上了就点亮 led
MOV A,SBUF
CJNE A,#0FFH,JI
LJMP RECE
JI:
CJNE A,ADDRESS,SR_EX ; compair the address
RECE:
CLR SM2 ; 不过
LCALL ReceiveData ; receive the command_length
JC SR_EX ; c=1 fail c=0 success
MOV DPTR,#RD_BUF ; 串行接收缓冲区 96byte 3a0h--3ffh
MOVX @DPTR,A ; save the command_length
MOV R5,A ; save the counter of receive
DEC R5 ; counter=counter-1
SR_00:
INC DPTR ; rd_buf+1
LCALL ReceiveData ; receive the command and checksum
JC SR_EX
MOVX @DPTR,A ; save the date
DJNZ R5,SR_00 ; do until counter=0
LCALL Command ; 调用命令解析 mao change
; lcall Command1
SR_EX: SETB SM2
CLR RS485_TR ; set 485 receive
POP AUXR1
POP DSP
POP DPL
POP DPH
POP B
POP ACC
POP PSW
RETI
Command:
MOV A,#0E0H
LCALL CheckJYH ; check Receive_date_buf
JZ CMD_000 ; a=0,success; a=other fail
RET ; check is error,ret
Command1: MOV DPTR,#RD_BUF ; 串行接收缓冲区
mov r0,#0
movx a,@dptr
;mov r1
add a,r0
mov r0,a
inc dptr
ret
;************************************************************
;功能:读取1电表的读数
; BYTE0=命令长度
; BYTE1=命令字
; BYTE2=电表号
; BYTE3=时
; BYTE4=分
; BYTE5=秒
; BYTE6=校验和
;从控地址+命令长度+命令字10H+电表号+时+分+秒+校验和
;************************************************************
CMD_000:
MOV DPTR,#RD_BUF+1 ; 读电表读数 10H
MOVX A,@DPTR
CJNE A,#RF_RP,CMD0_1
CMD_0: MOV DPTR,#RD_BUF
MOVX A,@DPTR
CJNE A,#7,CMD0_0 ; 检查数据包字节数
MOV DPTR,#RD_BUF+2
MOVX A,@DPTR
ANL A,#0F0H
JZ CMD0_2 ; 检查电表号是否正常
CMD0_0:
LJMP CMD0_EX ;电表号》16退出
CMD0_1: AJMP CMD_1 ;
CMD0_2:
MOV R5,ADDRESS ; R5中存放校验和 从本机地址开始
MOV A,ADDRESS
LCALL SendData ;1、发送从控地址
MOV DPTR,#RD_BUF+2
MOVX A,@DPTR
PUSH ACC
LCALL SendData
ADD A,R5
MOV R5,A ; 2、发送电表号
MOV A,#50H ;高4位=5,电表读数有效
JNB ERR_RATE,YES_C1 ;费率表出错标志 =1出错
ORL A,#05H ;低4位=5,分时计费时间表出错
YES_C1:
LCALL SendData
ADD A,R5
MOV R5,A ;3、发送有电表读数标志 #55
MOV DPTR,#POINT_BUF ; 存放每个电表的电表数,每个电表占用4*4+1个字节,对应4种费率,
; Byte0-3 费率1电表数
; Byte4-7 费率2电表数
; Byte8-11 费率3电表数
; Byte12-15 费率4电表数
; Byte16 JYH
POP ACC ; 弹出电表号
MOV B,#17
MUL AB
ADD A,DPL
MOV DPL,A
MOV A,B
ADDC A,DPH
MOV DPH,A ;找到相应电表的读数
MOV R7,#17
CMD0_00: MOVX A,@DPTR
LCALL SendData
ADD A,R5
MOV R5,A
INC DPTR
DJNZ R7,CMD0_00 ;4、发送17个电表读数
MOV A,R5
CPL A
INC A
LCALL SendData ;5、发送总校验和
RET
;------------------------------------------------
; 好象没有用到
;------------------------------------------------
NO_CHANGE:
POP ACC
MOV A,#00H
JNB ERR_RATE,NO_C1
ORL A,#05H
NO_C1:
LCALL SendData
ADD A,R5
MOV R5,A ; 发送无电表读数标志 #00
MOV R7,#17
CMD0_01: CLR A
LCALL SendData
NOP
NOP
DJNZ R7,CMD0_01 ; 发送17个电表读数
MOV A,R5
CPL A
INC A
LCALL SendData
CMD0_EX:
RET
;*****************************************
;功能:读电表状态
; BYTE0=命令长度
; BYTE1=命令字
; BYTE2=时
; BYTE3=分
; BYTE4=秒
; BYTE5=校验和
;从控地址+命令长度+命令字11H+时+分+秒+校验和
;*****************************************
CMD_1: CJNE A,#RF_IN,CMD_2_
MOV DPTR,#RD_BUF
MOVX A,@DPTR
CJNE A,#6,CMD1_EX ; 判断命令长度
INC DPTR;命令字
INC DPTR;时
MOVX A,@DPTR
MOV R1,A
ANL A,#0F0H
SWAP A
MOV B,#10
MUL AB
MOV B,A
MOV A,R1
ANL A,#0FH
ADD A,B
MOV HOUR,A
INC DPTR
MOVX A,@DPTR
MOV R1,A
ANL A,#0F0H
SWAP A
MOV B,#10
MUL AB
MOV B,A
MOV A,R1
ANL A,#0FH
ADD A,B
MOV MINUTE,A ; 保存时间 取出时、分转化成十进制存储到RAM单元
JB FLAG_REQUE,CMD1_0 ;系统信息请求标志 =0时请求
MOV A,#RD_REQUE ; 请求系统信息
LCALL SendData
CMD1_EX:
RET
CMD_2_:
LJMP CMD_2
CMD1_0:
MOV R5,#0
MOV A,ADDRESS
LCALL SendData ; 发送从控号
MOV DPTR,#METER_INF ; 指向电表当前信息区首地址 主继电器状态/从继电器状态/当前功率/跳电电流/跳电功率
MOV R7,#16
CMD1_1:
MOVX A,@DPTR
LCALL SendData ; 主继电器状态
PUSH ACC
ANL A,#11011111B
MOVX @DPTR,A
POP ACC
ADD A,R5
MOV R5,A
INC DPTR
MOVX A,@DPTR
LCALL SendData
ADD A,R5
MOV R5,A ; 从继电器状态
INC DPTR
MOVX A,@DPTR
LCALL SendData
ADD A,R5 ; 当前功率
MOV R5,A
INC DPTR
MOVX A,@DPTR
LCALL SendData
ADD A,R5
MOV R5,A ; 跳电电流
INC DPTR
MOVX A,@DPTR
LCALL SendData
ADD A,R5
MOV R5,A ; 跳电功率
INC DPTR
DJNZ R7,CMD1_1 ; 发送80字节电表信息
MOV A,R5
CPL A
INC A
LCALL SendData
ADD A,R5
MOV R5,A ; 发送电表信息校验和
ADD A,ADDRESS
CPL A
INC A
LCALL SendData ; 发送总校验和
RET
;**************************
;功能:写某个电表读数
; WRITE A POINT
; BYTE0=命令长度
; BYTE1=命令字
; BYTE2=电表号
; BYTE3=POINT 0/RATE 0
; BYTE4=POINT 1/RATE 0
; BYTE5=POINT 2/RATE 0
; BYTE6=POINT 3/RATE 0
; BYTE7=POINT 0/RATE 1
; BYTE8=POINT 1/RATE 1
; BYTE9=POINT 2/RATE 1
; BYTE10=POINT 3/RATE 1
; BYTE11=POINT 0/RATE 2
; BYTE12=POINT 1/RATE 2
; BYTE13=POINT 2/RATE 2
; BYTE14=POINT 3/RATE 2
; BYTE15=POINT 0/RATE 3
; BYTE16=POINT 1/RATE 3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -