📄 pic16c74_485.asm
字号:
MOVWF FSR
MOVF INDF,W ;调出接收到的第一个字符
XORLW START_RC ;比较起始字符
BTFSS STATUS,Z ;相同向下执行,否则退出
GOTO OUT_TEST_RCFIFO
;~~~~~~~~~~~~ TEST ADDRESSH ~~~~~~~~~~~
INCF FSR,F ;ADDRESS+1
MOVF INDF,W
XORLW ADDRESSH ;比较地址高位
BTFSS STATUS,Z
GOTO OUT_TEST_RCFIFO
;~~~~~~~~~~~ TEST ADDRESSL ~~~~~~~~~~~~~
INCF FSR,F ;ADDRESS+1
MOVF INDF,W
XORLW ADDRESSL ;比较地址低位
BTFSS STATUS,Z
GOTO OUT_TEST_RCFIFO
;~~~~~~~~~~ TEST END_ASCII ~~~~~~~~~~
INCF FSR,F ;ADDRESS+1 COMMAND_H
INCF FSR,F ;ADDRESS+1 COMMAND_L
INCF FSR,F ;ADDRESS+1
MOVF INDF,W
XORLW END_ASCII
BTFSS STATUS,Z
GOTO OUT_TEST_RCFIFO
;/////若起始字符、地址、结束字符都正确,则解析命令执行输出\\\\\\\\\\\\\\\\\\\\\\\\\\
;~~~~~~~~~~ TEST DATA ADDRESSH ~~~~~~~~~~
MOVLW RC_FSR_S
MOVWF FSR ;起始字符地址
INCF FSR,F ;ADDRESS+1 地址字符地址H
INCF FSR,F ;ADDRESS+1 地址字符地址L
INCF FSR,F ;ADDRESS+1
MOVF INDF,W ;调出命令高字节
MOVWF COMMAND_ASCII_H ;存储到
;~~~~~~~~~~ TEST DATA ADDRESSL ~~~~~~~~~~
INCF FSR,F ;ADDRESS+1
MOVF INDF,W
MOVWF COMMAND_ASCII_L
CALL COMMAND_CODE ;指令译码
OUT_TEST_RCFIFO
BANKSEL PIE1
BSF PIE1,RCIE ;允许接收中断
BANKSEL PORTC
RETURN
;************************命令译码子程序*******************
COMMAND_CODE
COM_DATA_CODE
MOVLW 0x30 ;判断ASCII是否小于30
SUBWF COMMAND_ASCII_H,W
BTFSS STATUS,C ;F-W<0置0, F-W>=0置1
RETURN ;<30退出
MOVLW 0x47 ;判断ASCII是否小于等于46
SUBWF COMMAND_ASCII_H,W
BTFSC STATUS,C ;F-W<0置0, F-W>=0置1
RETURN ;>47退出
MOVLW 0x3A ;判断ASCII是小于等于39
SUBWF COMMAND_ASCII_H,W
BTFSS STATUS,C ;F-W<0置0, F-W>=0置1
GOTO TEST_C_A_L ;YES <40表示在39>=X>=30范围内,去测试低位数据
MOVLW 0x41 ;>=40则判断ASCII是否小于30
SUBWF COMMAND_ASCII_H,W ;判断ASCII是否小于41
BTFSS STATUS,C ;F-W<0置0, F-W>=0置1
RETURN ;<41退出
TEST_C_A_L ;>=41 继续执行
MOVLW 0x30
SUBWF COMMAND_ASCII_L,W
BTFSS STATUS,C
RETURN ;退出
MOVLW 0x47
SUBWF COMMAND_ASCII_L,W
BTFSC STATUS,C ;通过以上几步已经将数据限制在了47>X>30,
RETURN
MOVLW 0x3A ;判断ASCII是小于等于39
SUBWF COMMAND_ASCII_L,W
BTFSS STATUS,C ;F-W<0置0, F-W>=0置1
GOTO COM_CODE ;YES <40表示在39>=X>=30范围内,去解码
MOVLW 0x41 ;>=40则判断ASCII是否小于30
SUBWF COMMAND_ASCII_L,W ;判断ASCII是否小于41
BTFSS STATUS,C ;F-W<0置0, F-W>=0置1
RETURN ;<41退出
COM_CODE
CLRF COMMAND ;清空命令寄存器
MOVLW 0x030
SUBWF COMMAND_ASCII_H,W ;减去查表的偏差0x30,将高4位接收到的命令ASCII送W
CALL ATH_TABEL ;查表将高4位ASCII转换为数字
IORWF COMMAND,F ;与运算,将高4位转换的数字送COMMAND的低4位
SWAPF COMMAND,F ;转换COMMAND高4位与低4位的位置,将COMMAND??H数字送高4位
MOVLW 0x030
SUBWF COMMAND_ASCII_L,W ;减去查表的偏差0x30,将低4位接收到的命令ASCII送W
CALL ATH_TABEL ;查表将低4位ASCII转换为数字
IORWF COMMAND,F ;与运算,将低4位转换的数字送COMMAND的低4位
BSF MYSTATUS,1 ;解码完成允许D口数据输出
RETURN
;**************************端口输出子程序********************
PORTD_OUT
BANKSEL MYSTATUS
BCF MYSTATUS,1 ;清除标志位,防止重复调用
MOVF COMMAND,W ;调出数据,
MOVWF PORTD ;送D口
;^^^^^^^^插入装配数据部分^^^^^^^^^^^^
BANKSEL TX_CP
CLRF TX_CP ;初始化个数指针
MOVLW TX_FSR_S ;初始化首地址
MOVWF FSR ;首地址送开始字符
MOVLW START_TX
MOVWF INDF
INCF TX_CP,F ;要发送个数+1 0+1=1
INCF FSR,F ;地址+1,送地址高位
MOVLW ADDRESSH
MOVWF INDF
INCF TX_CP,F ;要发送个数+1 1+1=2
INCF FSR,F ;地址+1,送地址低位
MOVLW ADDRESSL
MOVWF INDF
INCF TX_CP,F ;要发送个数+1 2+1=3
INCF FSR,F ;地址+1,送结束字符位
MOVLW END_ASCII
MOVWF INDF ;装配完成
INCF TX_CP,F ;要发送个数+1 3+1=4
;^^^^^^^^^^^^^^^^^^^^^^^^^^
CALL START_TX_S
RETURN
;***************************STRAT_TX**************************
START_TX_S
BANKSEL PORTC
CALL Delay1ms ;延迟时间防止RS485的线路被别的占用,导致数据发送不完整\甚至发送不出去
CALL Delay1ms ;
BSF PORTC,0 ;MAX485 为发送状态 (PC.0=1)
CALL Delay1ms ;延迟时间稳定端脚
CALL Delay1ms ;延迟时间稳定端脚
MOVLW TX_FSR_S ;初始化首地址
MOVWF TX_FSR
MOVLW 0x01 ;给TX_CP计数器加上偏移量
ADDWF TX_CP,F
BANKSEL PIE1
BSF PIE1,TXIE ;开启发送中断,允许发送的时候将数据送出
BANKSEL PORTC
RETURN
;***************************发送数据中断服务*****************************
TX_Service
;[方法一]----------------------------------------------------------------
; 说明:必须加上前面的TX_CP偏移量
; 首先判断是否发送完毕,多执行了一次发送中断
BANKSEL TX_CP
MOVF TX_CP,W
BTFSC STATUS,Z ;判断传送完毕否?
GOTO TX_END ;完毕了,转到结束部分
DECF TX_CP,F ;TX_CP-1, 个数
MOVF TX_FSR,W ;地址指针
MOVWF FSR
MOVF INDF,W ;调出数据
MOVWF TXREG ;到发送缓冲区
INCF TX_FSR,F ;地址指针+1
RETURN
;--------------------------------------------------------------------
;[方法二]------------------------------------------------------------
; 说明:!!!必须加上延时程序,否则出错.
; 使用此方法可以不用前面的TX_CP偏移量
; 最后判断是否发送完毕,不用多执行一次发送中断.
; BANKSEL TX_FSR
; MOVF TX_FSR,W ;调出地址指针;
; MOVWF FSR ;指向地址
; MOVF INDF,W ;调出数据,
; MOVWF TXREG ;发送数据
; CALL Delay256us ;!!!!!!!!!!!!!!!!!!!!!
; INCF TX_FSR,F ;地址指针+1
; DECF TX_CP,F ;TX_CP-1, 个数-1
; MOVLW
; MOVF TX_CP,W ;
; BTFSS STATUS,Z ;判断传送完毕否?
; RETURN ;没有,退出本服务
;-----------------------------------------------------------------------
TX_END
BANKSEL PIE1
BCF PIE1,TXIE ;关闭发送中断允许
BANKSEL TX_FSR
BCF PORTC,0 ;设置MAX485 为接收状态
RETURN
;[方法三]--------------------------------发送数据服务---------------------
; 说明: 此方法为查询方式,没有使用中断,因此在使用时要取消发送中断允许位
; 必须加上延时程序,否则别说我没有告诉你.
;TX_Service;
; BANKSEL PORTC
; BSF PORTC,0 ;MAX485 为发送状态
; MOVLW TX_FSR_S ;初始化首地址
; MOVWF TX_FSR
;TEST_TXIF
; CLRWDT
; BANKSEL PIR1
; BTFSS PIR1,TXIF ;判断是否允许发送
; GOTO TEST_TXIF ;否,继续判断
; BANKSEL TX_FSR
; MOVF TX_FSR,W ;允许发送,地址指针
; MOVWF FSR
; MOVF INDF,W ;调出数据,
; MOVWF TXREG ;发送数据
; CALL Delay256us !!!!!!!!!!!!!!!!!
; INCF TX_FSR,F ;地址指针+1
; DECF TX_CP,F ;TX_CP-1, 个数-1
; MOVF TX_CP,W ;
; BTFSS STATUS,Z ;判断传送完毕否?
; GOTO TEST_TXIF ;没有继续判断发送
;TX_END
; BANKSEL PORTC ;完毕了,
; BCF PORTC,0 ;设置MAX485 为接收状态
; RETURN
;----------------------------------------------------------------------
;**************************TMR1中断服务程序**************************
TMR1_Service
BANKSEL PIE1 ;BANK1
BCF PIE1,TMR1IE ;禁止接收定时器中断,
BANKSEL PIR1 ;BANK0
CLRF T1CON
BCF PIR1,TMR1IF ;清除中断标志
CLRF RC_CP ;清除接收计数器 复位接收计数器,允许下次接收
MOVLW RC_FSR_S
MOVWF RC_FSR ;复位地址指针。
RETURN
;========延时子程序=============================
Delay256us:
MOVLW 0x0FF
MOVWF Delay256us_Reg
Loop256us:
CLRWDT
DECFSZ Delay256us_Reg,F
GOTO Loop256us
RETURN
Delay1ms:
MOVLW 0x004
MOVWF Delay1ms_Reg
Loop1ms:
CALL Delay256us
DECFSZ Delay1ms_Reg,F
GOTO Loop1ms
RETURN
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -