📄 hwint.bak
字号:
;---------------------------------------------------------------------------------------------------
;红外串口通信子程序
;接收一正确帧,置正确帧标志
;HW_FRM_PROCESS BIT 21H.2 ;帧正在处理标志,处理完后要清零
;HW_LEADER_CHARACTER BIT 21H.3 ;接收到正确前导字节标志
;HW_FRAMES_HEAD_RECEVED BIT 21H.4 ;红外帧正在接收标志
;接收缓冲在CPU内高128字节,只能间接读写.
;---------------------------------------------------------------------------------------------------
INFRA_CARRIER:
CLR ES ;关串行中断
CLR REN ;禁止接收
CPL WATCH_DOG ;清狗
PUSH PSW ;保护状态字及A,B寄存器
PUSH ACC
PUSH B
PUSH 00H
PUSH 01H
RECE_FRAME_START:
JBC RI,HW_RECE_HEAD_BYTE ;允许接收中断位=1否?
LJMP HW_RECE_FRAME_END ;没接收中断,等待
HW_RECE_HEAD_BYTE:
MOV A,SBUF ;有中断,读接收缓冲寄存器
MOV HW_REC_WHOLE_BYTE,A ;接收一字节送RAM ;接收一字节送RAM
JB HW_FRAMES_HEAD_RECEVED,HW_FRAME_JUDGE ;帧在接收否?
CJNE A,#0FEH,HW_JUDGE_RECE_HEAD ;是前导字节#0FEH否?
SETB HW_LEADER_CHARACTER ;是前导字,置标志
LJMP HW_RECE_FRAME_END
HW_JUDGE_RECE_HEAD:
JNB HW_LEADER_CHARACTER,NOT_HEAD_BYTE ;判断前导字已接收过否?
AJMP HW_FRAME_JUDGE
NOT_HEAD_BYTE:
LJMP HW_NOT_HEAD
;--------------------------------------------------------
;前导字已接收过,判断帧
HW_FRAME_JUDGE:
MOV R0,#HW_REC_HEAD1 ;帧头判断
CJNE @R0,#68H,HW_FINDING_HEAD ;帧头是否已接收并存过?
MOV A,HW_REC_WHOLE_BYTE
CJNE A,#16H,HW_SAVE_RECE_BYTE ;判断是帧尾否?
AJMP HW_RECE_DATA_LONGER
HW_FINDING_HEAD: MOV A,HW_REC_WHOLE_BYTE
CJNE A,#68H,HW_NOT_HEAD
SETB HW_FRAMES_HEAD_RECEVED ;帧头已接收标志
LJMP HW_SAVE_RECE_BYTE ;是帧头,保存
HW_NOT_HEAD:
LJMP HW_CLR_RECE_SBUF ;清接收缓冲区
RECE_ERR:
LJMP HW_RECE_FRAME_END ;转接收结束
HW_RECE_DATA_LONGER:
MOV R0,#HW_REC_DATA_FEILD_LEN ;取数据域长度,接收区首地址+09H
MOV A,@R0
CLR C ;数据域长度<32?,大于32时,接收数据错
SUBB A,#32
JC HW_REC_FRAME_LONGER
LJMP HW_CLR_RECE_SBUF ;大于32时,接收数据错,重新开始接收
HW_REC_FRAME_LONGER:
MOV R0,#HW_REC_DATA_FEILD_LEN
MOV A,#12
HW_JUDGE_FRAMES_LONTH:
ADD A,@R0 ;帧尾字节应在的位置
DEC A ;若是帧尾,当前接收到的字节数比应接收到的字节数少1
CJNE A,HW_REC_CUR_LEN,HW_SAVE_RECE_BYTE ;非帧尾,是帧内的字节,保存
SETB HW_FRM_PROCESS ;置帧处理标志,保存帧尾
HW_SAVE_RECE_BYTE:
MOV A,HW_REC_CUR_LEN ;当前接收字节长度
CLR C
SUBB A,#HW_REC_BUF_LEN+1 ;接收的总长度是否超过32个字节?
JNC HW_CLR_RECE_SBUF
HW_DLB_RULES:
MOV A,#HW_REC_BUF ;是帧内的字节,保存
;存储接收到的字节:
HW_RECE_BYTES_AND_SAVE:
ADD A,HW_REC_CUR_LEN ;计算在帧内应存放的地址
MOV R0,A
MOV A,HW_REC_WHOLE_BYTE
MOV @R0,A
INC HW_REC_CUR_LEN ;当前接收到的帧字节数+1
JNB HW_FRM_PROCESS,HW_RECE_FRAME_END ;和校验
MOV A,HW_REC_CUR_LEN ;当前接收字节长度
DEC A
DEC A
MOV B,A
HW_DLB_RULES_PROCESS:
ADD A,#HW_REC_BUF ;校验和的地址
MOV R0,A
MOV A,@R0
PUSH A ;校验和压栈
MOV R0,#HW_REC_BUF
MOV A,#00H
HW_CHECK_SUM: ADD A,@R0
INC R0
DJNZ B,HW_CHECK_SUM
MOV B,A
POP A
CJNE A,B,HW_CLR_RECE_SBUF ;和校验错,清HW_FRM_PROCESS
CLR S_LEDR ;红外接收灯亮
LJMP HW_RECE_FRAME_END
HW_CLR_RECE_SBUF:
SETB S_LEDR ;红外接收灯灭
MOV HW_REC_CUR_LEN,#00H ;当前帧长度清0
MOV R0,#HW_REC_BUF ;清接收缓冲区62字节
MOV B,#HW_REC_BUF_LEN
HW_CLR_RECE_LOOP:
MOV @R0,#00H
INC R0
DJNZ B,HW_CLR_RECE_LOOP
CLR HW_LEADER_CHARACTER
CLR HW_FRAMES_HEAD_RECEVED
CLR HW_FRM_PROCESS
HW_RECE_FRAME_END:
POP 01H
POP 00H
POP B
POP ACC
POP PSW ;出栈
SETB REN ;允许接收
SETB ES ;开串行中断
RETI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -