⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zbint.asm

📁 本程序为集中抄表系统中低压电力线载波数据采集器程序源代码
💻 ASM
字号:
;------------------------------------------------------------------------------------
;载波发送和接收中断服务子程序
;--接收:FRM_PROCESS,SYNB,HEAD_LO,HEAD_HI,REC_WHOLE_BYTE,REC_BIT_LEN,REC_CUR_LEN
;--发送:TXD_READY_FLAG,COUNTER_SEND_DELAY,SEND_BYTE_OVER,SEND_WHOLE_BYTE,SEND_BIT_LEN
;------------------------------------------------------------------------------------
CARRIER:        PUSH    ACC                                          ;压栈ACC
                PUSH    PSW                                          ;压栈PSW
                PUSH    0F0H                                         ;压栈B寄存器
                PUSH    00H                                          ;压栈R0
PUSH    06H
        ;        CLR     ZB_HW                                       ;串行口置载波收发状态
            ;    SETB    RXD                                         ;收发数据线置高准备好接收下一位
                JB      RX_TX,CARRIER_REC                            ;ST7536是否处在接收状态
                JB      TXD_READY_FLAG,CARRIER_SEND
                DJNZ    COUNTER_SEND_DELAY,JMP_EXIT
                SETB    TXD_READY_FLAG
		MOV	SEND_BIT_LEN,#8		             ;发送的位数=8
                SJMP    JMP_EXIT
;--------------------------------------------------
;载波发送
CARRIER_SEND:
                JB      SEND_BYTE_OVER,JMP_EXIT                      ;当前字节发送完否
WAIT_FOR_304CYCLES:

WAIT_01:
                CPL     WATCH_DOG
                MOV     R6,#70
WAIT_02:
                NOP
                NOP
                DJNZ    R6,WAIT_02

                MOV     A,SEND_WHOLE_BYTE		             ;先发字节的低位
                CLR     C
                RLC     A
                MOV     SEND_WHOLE_BYTE,A                            ;
                JC      SETB_TXD_1
                CLR     TXD
                SJMP    SEND_NEXT_BIT           
SETB_TXD_1:
                SETB    TXD
SEND_NEXT_BIT:
                DEC     SEND_BIT_LEN                                 ;已发送的位数加1
                MOV     A,SEND_BIT_LEN
                CJNE    A,#00H,JMP_EXIT                              ;8位发送完否
                SETB    SEND_BYTE_OVER                               ;置字节发送完标志
                MOV     SEND_BIT_LEN,#8                              ;已发送的位数清零,准备发送下一字节
                LJMP    EXIT_INT
;-------------------------------------------------
;载波接收
;同步字节09AF接收判断:
CARRIER_REC:
		JB      FRM_PROCESS,JMP_EXIT                         ;当前帧命令处理完否?未处理完时,跳出中断,不处理该字节
                JB      SYNB,RECEIVE0                                ;判断同步头09AF,;--先发高字节09H(HEAD_HI)的低位,依次类推
                SETB    R_LEDC				   	     ;收到正确信息后亮,然后收到干扰信息后接收灯灭
                JNB     RXD,CLR_CY
                SETB    C
                SJMP    SETB_CY
CLR_CY:         CLR     C
SETB_CY:
                MOV     A,HEAD_LO
		RLC     A                                            ;每收1位同步字右移1位
		MOV     HEAD_LO,A
		MOV     A,HEAD_HI
		RLC     A
		MOV     HEAD_HI,A			  	     ;先收高字节09H(HEAD_HI)的低位,依次类推
		CJNE    A,#0AAH,JMP_EXIT                             ;同步头第1字节为#09H?
                MOV     A,HEAD_LO
		CJNE    A,#0AAH,JMP_EXIT                             ;同步头第2字节为#0AFH?
		MOV     HEAD_LO,#0FFH
                MOV     HEAD_HI,#0FFH
                SETB    SYNB
                MOV     REC_BIT_LEN,#00H		             ;8位字节数清零
JMP_EXIT:       LJMP    EXIT_INT
;----------------------------
;接收数据容错判断程序: 连续接收3字节,逐位比较得出正确字节。
RECEIVE0:
                JNB      RXD,REST_CY
                SETB     C
                SJMP     SETB_CY_BIT
REST_CY:
                CLR    C
SETB_CY_BIT:
              ;  MOV     C,RXD					;接收下一位
                MOV     A,REC_WHOLE_BYTE                        ;要接收的当前字节
                RLC     A                                       ;右移1位
                MOV     REC_WHOLE_BYTE,A		        ;重新存入接收寄存器
                INC     REC_BIT_LEN                             ;当前接收位长度+1
                MOV     A,REC_BIT_LEN
                CJNE    A,#8,RECE_SECOND_BYTE                   ;8位接收完毕否?
                MOV     ZBREC_FIRST_BYTE,REC_WHOLE_BYTE         ;第一次接收到的数据暂存
                LJMP    EXIT_INT
RECE_SECOND_BYTE:
                CJNE    A,#16,RECE_THIRD_BYTE                   ;16位接收完毕否?
                MOV     ZBREC_SECOND_BYTE,REC_WHOLE_BYTE        ;第二次接收到的数据暂存
                LJMP    EXIT_INT
RECE_THIRD_BYTE:
                CJNE    A,#24,JUDGE_REC_TIMES                   ;24位接收完毕否?
                MOV     ZBREC_THIRD_BYTE,REC_WHOLE_BYTE         ;第三次接收到的数据暂存
                MOV     REC_BIT_LEN,#00H                        ;3字节接收完毕,接收位字节计数器清零
;-------------------------
;错误校正程序
ERROR_CORRECTION:
                MOV     B,#08H                                  ;3字节比较次数
                CLR     C                                       ;清进位位为0
ERROR_JUDGE_STA:
                MOV     A,ZBREC_FIRST_BYTE                      ;取出接收首字节
                RRC     A                                       ;右移一位
                MOV     ZBREC_FIRST_BYTE,A                      ;重存首字节
                JC      ERROR_JUDGE_AA                          ;判断当前位为1否?
                MOV     A,ZBREC_SECOND_BYTE                     ;取出接收第2字节
                RRC     A                                       ;右移一位
                MOV     ZBREC_SECOND_BYTE,A                     ;重存第2字节
                JC      ERROR_JUDGE_BB                          ;判断当前位为1否?
                MOV     A,ZBREC_THIRD_BYTE                      ;取出接收第3字节
                RRC     A                                       ;右移一位
                MOV     ZBREC_THIRD_BYTE,A                      ;重存第3字节
ERROR_JUDGE_00:
                MOV     A,REC_WHOLE_BYTE                        ;取出接收正确字节寄存器存储数据
                CLR     C                                       ;3字节相同位有至少2位为0则清进位位
                RRC     A                                       ;右移一位
                MOV     REC_WHOLE_BYTE,A                        ;重存
ERROR_NEXT_BIT:
                DJNZ    B,ERROR_JUDGE_STA                       ;判断8位比较完否?
                AJMP    FRM_JUDGE                               ;转帧处理程序
ERROR_JUDGE_AA:
                MOV     A,ZBREC_SECOND_BYTE                     ;取出接收第2字节
                RRC     A                                       ;右移一位
                MOV     ZBREC_SECOND_BYTE,A                     ;重存第2字节
                JC      ERROR_JUDGE_CC                          ;判断当前位为1否?
ERROR_JUDGE_BB:
                MOV     A,ZBREC_THIRD_BYTE                      ;取出接收第3字节
                RRC     A                                       ;右移一位
                MOV     ZBREC_THIRD_BYTE,A                      ;重存第3字节
                JC      ERROR_JUDGE_01                          ;判断当前位为1否?
                AJMP    ERROR_JUDGE_00                          ;1字节为1,2字节为0,3字节为0正确字节该位置为0
ERROR_JUDGE_CC:
                MOV     A,ZBREC_THIRD_BYTE                      ;取出接收第3字节
                RRC     A                                       ;右移一位
                MOV     ZBREC_THIRD_BYTE,A                      ;重存第3字节
ERROR_JUDGE_01:
                MOV     A,REC_WHOLE_BYTE                        ;取出接收正确字节寄存器存储数据
                SETB    C                                       ;任意2位或以上位为1,置进位为1
                RRC     A                                       ;右移一位
                MOV     REC_WHOLE_BYTE,A                        ;重存
                AJMP    ERROR_NEXT_BIT
JUDGE_REC_TIMES:
                SUBB   A,#25                                    ;判断接收位数大于25否?
                JC     EXIT_INT                                 ;<=24,继续接收
                MOV    REC_BIT_LEN,#00H                         ;>24,表示出错,接收位长度清0
                SJMP   ERROR_CORRECTION                         ;转接收数据错误冗余修正判断
;----------------------
;接收帧正确否判断程序:
FRM_JUDGE:
                MOV     R0,#REC_HEAD                                 ;判断接收缓冲区首字节为帧头68H否
                CJNE    @R0,#68H,FINDING_HEAD                        ;帧头是否找到?
                MOV     A,REC_WHOLE_BYTE
                CJNE    A,#16H,SAVE_BYTE
                MOV     R0,#REC_DATA_FEILD_LEN                       ;接收到的字节为16H,且数据域长度不为0
                CJNE    @R0,#00H,FINDING_END                         ;是否帧尾?
                SJMP    SAVE_BYTE                                    ;非帧尾,是帧内中间字节(ADDR OR CODE) 保存
FINDING_HEAD:   MOV     A,REC_WHOLE_BYTE
                CJNE    A,#68H,NOT_HEAD
                SJMP    SAVE_BYTE                                    ;是帧头,保存
NOT_HEAD:       SJMP    ERROR_HANDLE
FINDING_END:    MOV     R0,#REC_DATA_FEILD_LEN
                MOV     A,#07H
                ADD     A,@R0		                             ;帧尾字节应在的位置
                DEC     A                                            ;若是帧尾,当前接收到的字节数比应接收到的字节数少1
                CJNE    A,REC_CUR_LEN,SAVE_BYTE                      ;非帧尾,是帧内的字节,保存
                SETB    FRM_PROCESS                                  ;置帧处理标志,保存帧尾
                CLR     SYNB                                         ;清同步头
SAVE_BYTE:      MOV     A,REC_CUR_LEN
                CLR     C
                SUBB    A,#REC_BUF_LEN+1                    	     ;接收的总长度是否超过20个字节?
                JNC     ERROR_HANDLE
                MOV     A,#REC_BUF                                   ;是帧内的字节,保存
                ADD     A,REC_CUR_LEN                                ;计算在帧内应存放的地址
                MOV     R0,A
                MOV     A,REC_WHOLE_BYTE
                MOV     @R0,A
                INC     REC_CUR_LEN                                  ;当前接收到的帧字节数+1
                JNB     FRM_PROCESS,EXIT_INT                         ;和校验
                MOV     A,REC_CUR_LEN
                DEC     A
                DEC     A
                MOV     B,A
                ADD     A,#REC_BUF                                   ;校验和的地址
                MOV     R0,A
                MOV     A,@R0
                PUSH    A                                            ;校验和压栈
                MOV     R0,#REC_BUF
                MOV     A,#00
CHECK_SUM:      ADD     A,@R0
                INC     R0
                DJNZ    B,CHECK_SUM
                MOV     B,A
                POP     A
                CJNE    A,B,ERROR_HANDLE                             ;和校验错,清FRM_PROCESS
		CLR     R_LEDC					     ;收到正确信息后亮.
                SJMP    EXIT_INT
ERROR_HANDLE:	SETB	R_LEDC				             ;接收灯灭
                MOV     REC_CUR_LEN,#00H                             ;当前帧长度清0
                MOV     R0,#REC_BUF
                MOV     B,#REC_BUF_LEN
CLR_REC1:       MOV     @R0,#00H
                INC     R0
                DJNZ    B,CLR_REC1
                CLR     FRM_PROCESS
		CLR     SYNB                                         ;直接接收时,不判同步头,该指令可不要
EXIT_INT:
         ;       SETB    ZB_HW                                        ;串行口初始置红外接收状态
POP   06H
                POP     00H
                POP     0F0H
                POP     PSW
                POP     ACC
                RETI

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -