📄 can.c
字号:
LIST P=18F258
INCLUDE "P18F258.INC"
CZS1 EQU 20H ;
CZS2 EQU 21H ;
XHCS1 EQU 22H ;
XHCS2 EQU 23H ;
ZD0QC EQU 24H ;中断0启(停)车标志位(0位为启车、1位为停车)
ZD1QC EQU 25H ;中断1启(停)车标志位(0位为启车、1位为停车)
JSBZW EQU 26H ;can接收标志位
TFZD0BJ EQU 27H ;停止发送中断0启/停车报警
TFZD1BJ EQU 28H ;停止发送中断1启/停车报警
STATUS_TEMP EQU 29H ;
W_TEMP EQU 2AH ;
BSR_TEMP EQU 2BH ;
QQY EQU 2CH ;启前运
TQY EQU 2DH ;停前运
QHY EQU 2EH ;启后运
THY EQU 2FH ;停后运
M EQU 30H ;
K EQU 31H ;
Q EQU 32H ;
ORG 0X00
GOTO MAIN
ORG 0X08
GOTO CAN_INTSERVE ;转向CAN/INT0中断服务子程序
ORG 0X30
;************************ 初始化子程序 *****************************
INITIAL:
CLRWDT ;喂狗(约18*128=2304ms)
CLRF PORTB ;清数据锁存器来初始化PORTB
CLRF LATB ;清除数据输出锁存器
movlw 0BH ;将端口RB的方向控制码0Bh先送w
movwf TRISB ;再转到方向寄存器,RB0/RB1/RB3为输入,余为输出
CLRF CZS1
CLRF CZS2
CLRF XHCS1
CLRF XHCS2
CLRF ZD0QC
CLRF ZD1QC
CLRF JSBZW
CLRF TFZD0BJ
CLRF TFZD1BJ
CLRF QQY
CLRF TQY
CLRF QHY
CLRF THY
CLRF PORTB
BCF PORTB,4
BCF PORTB,5
BCF PORTB,6
BCF PORTB,7
;设置CAN的波特率为5K,在Fosc=4M时,Tbit=200us,假设BRP=39h, 则TQ=[2*(1+BRP)]/Fosc=2*(1+39)/4=20us。
;NOMINAL BIT RATE=10TQ,SJW=1,Sync_Seg=1TQ,Prog _Seg=1TQ,Phase_Seg1=4TQ,Phase_Seg2=4TQ
MOVLW 80H
MOVWF CANCON ;请求进入CAN配置模式REQOP=100
WAIT:
CLRWDT
BTFSS CANSTAT,OPMODE2 ;等待进入CAN配置模式OPMODE=100
GOTO WAIT
MOVLW 0X27
MOVWF BRGCON1 ;设置SJW和BRP,SJW=1TQ,BRP=39H
MOVLW 0X98
MOVWF BRGCON2 ;设置Phase_Seg1=4TQ和Prog _Seg=1TQ
MOVLW 0X43
MOVWF BRGCON3 ;设置Phase_Seg2=4TQ
MOVLW 0XFF
MOVWF BSR ;TXB0D0到TXB0D7的地址在F60h以内,需
;要指定BSR
;设置发送邮箱0标识符号和发送的数据
MOVLW 0X00;0X19 ;最终放TXB0SIDH中
MOVWF CZS1
RLNCF CZS1
RLNCF CZS1
RLNCF CZS1
MOVLW 0F8H
ANDWF CZS1,1
MOVLW 0X11;0X3B ;
MOVWF CZS2
RRNCF CZS2
RRNCF CZS2
RRNCF CZS2
RRNCF CZS2
RRNCF CZS2
MOVLW 07H
ANDWF CZS2,1
MOVF CZS2,W
ADDWF CZS1,1
MOVFF CZS1,TXB0SIDH
MOVLW 0X11;0X3B ;最终放TXB0SIDL中
MOVWF CZS2
MOVLW 03H
ANDWF CZS2,1
MOVLW 0X11;0X3B ;
MOVWF CZS1
RLNCF CZS1
RLNCF CZS1
RLNCF CZS1
MOVLW 0E0H
ANDWF CZS1,1
MOVF CZS1,W
ADDWF CZS2,1
BSF CZS2,3
MOVFF CZS2,TXB0SIDL
MOVLW 09H ;
MOVWF TXB0EIDH
MOVLW 00H ;
MOVWF TXB0EIDL ;设置发送缓冲器0的扩展标识符,本程序采用
;扩展标识符
MOVLW 0X08
MOVWF TXB0DLC ;设置数据长度为8个字节
MOVLW 0X00
MOVWF TXB0D0
MOVLW 0X00
MOVWF TXB0D1
MOVLW 0X00
MOVWF TXB0D2
MOVLW 0X00
MOVWF TXB0D3
MOVLW 0X00
MOVWF TXB0D4
MOVLW 0X00
MOVWF TXB0D5
MOVLW 0X00
MOVWF TXB0D6
MOVLW 0X00
MOVWF TXB0D7 ;写发送缓冲器数据区的数据
;设置接收邮箱0的标识符和初始化数据
MOVLW 0X40
MOVWF RXB0CON ;仅仅接收扩展标识符的有效信息
MOVLW 0X00
MOVWF RXB0SIDH
MOVLW 0X08
MOVWF RXB0SIDL
MOVLW 0X00
MOVWF RXB0EIDH
MOVLW 0X00
MOVWF RXB0EIDL ;设置接收缓冲器0的扩展标识符
MOVLW 0X00
MOVWF RXM0SIDH
MOVLW 0XFF
MOVWF RXM0SIDL
MOVLW 0XFF
MOVWF RXM0EIDH
MOVLW 0X00
MOVWF RXM0EIDL ;初始化接收屏蔽
MOVLW 0X00
MOVWF RXF0SIDH
MOVLW 0X49 ;只接收帧ID为XX0911XX的数据
MOVWF RXF0SIDL
MOVLW 0X11 ;
MOVWF RXF0EIDH
MOVLW 0X00
MOVWF RXF0EIDL ;初始化接收滤波器0
MOVLW 0X08
MOVWF RXB0DLC ;设置接收缓冲器0的数据区长度
MOVLW 0X00
MOVWF RXB0D0
MOVLW 0X00
MOVWF RXB0D1
MOVLW 0X00
MOVWF RXB0D2
MOVLW 0X00
MOVWF RXB0D3
MOVLW 0X00
MOVWF RXB0D4
MOVLW 0X00
MOVWF RXB0D5
MOVLW 0X00
MOVWF RXB0D6
MOVLW 0X00
MOVWF RXB0D7 ;初始化接收缓冲器0的数据区数据
;*********CAN初始化子程序***********
CAN_INITIAL
;初始化CAN模块的I/O控制寄存器
MOVLW 0X00
MOVWF CIOCON
;使CAN进入某种工作模式模式
MOVLW 0X00
MOVWF CANCON ;=0X40,进入自测试模式;
;=0x00,正常操作模式
WAIT1
MOVF CANSTAT
ANDLW 0XE0
SUBLW 0X00
BTFSS STATUS,Z ;等待进入CAN正常操作模式OPMODE=000
GOTO WAIT1
;初始化CAN的中断
MOVLW 0X00
MOVWF PIR3 ;清所有CAN中断标志
MOVLW 0X01
MOVWF IPR3 ;接收缓冲器0的接收中断为最高优先级
BSF PIE3,RXB0IE ;使能接收缓冲器0的接收中断
RETURN
;*********INTO初始化子程序***********
INT0_INITIAL
MOVLW 0E0H ;禁止B口弱上拉//INT0和INT1上升沿触发
MOVWF INTCON2 ;
BCF INTCON,INT0IF ;清除INT0的中断标志
BSF INTCON,INT0IE ;INT0中断使能
RETURN
;*********INT1初始化子程序***********
INT1_INITIAL
MOVLW 48H ;
MOVWF INTCON3 ;使能INT1,INT1为高优先级,清INT1中断标志。禁止INT2
RETURN
;*********接收缓冲器0接收中断服务程序(高优先极)***********
CAN_INTSERVE
MOVWF W_TEMP ;W_TEMP在公共存储区低端
MOVFF STATUS,STATUS_TEMP ;STATUS_TEMP可在程序的任何位置寻址
MOVFF BSR,BSR_TEMP ;BSR可在程序的任何位置寻址用户中断服务程序
BTFSS PIR3,RXB0IF ;
GOTO ZDINT0 ;
BSF JSBZW,0
BCF PIR3,RXB0IF ;清接收中断标志
BCF RXB0CON,RXFUL ;打开接收缓冲器来接收新信息
ZDINT0
BTFSS INTCON,INT0IF ;检测INT0的中断标志
GOTO ZDINT1
BTFSS PORTB,0
GOTO GRXH1
CALL D10MS
BTFSS PORTB,0
GOTO GRXH1
BCF INTCON,INT0IF ;清除INT0的中断标志;
INCF XHCS1 ;
MOVF XHCS1,W ;
SUBLW 01H ;
BTFSS STATUS,Z ;
GOTO BSDYC0 ;不是第一次
BSF ZD0QC,0 ;置启车标志位
BCF ZD0QC,1 ;清停车标志位
GOTO ZDINT1
BSDYC0
BSF ZD0QC,1 ;置停车标志位
BCF ZD0QC,0 ;清启车标志位
CLRF XHCS1
GOTO ZDINT1
GRXH1 BCF INTCON,INT0IF ;清除INT0的中断标志;
ZDINT1
BTFSS INTCON3,INT1IF ;检测INT1的中断标志
GOTO RETI
BTFSS PORTB,1
GOTO GRXH2
CALL D10MS
BTFSS PORTB,1
GOTO GRXH2
BCF INTCON3,INT1IF ;清除INT1的中断标志;
INCF XHCS2 ;
MOVF XHCS2,W ;
SUBLW 01H ;
BTFSS STATUS,Z ;
GOTO BSDYC1 ;不是第一次
BSF ZD1QC,0 ;置启车标志位
BCF ZD1QC,1 ;清停车标志位
GOTO RETI
BSDYC1
BSF ZD1QC,1 ;置停车标志位
BCF ZD1QC,0 ;清启车标志位
CLRF XHCS2
GOTO RETI
GRXH2
BCF INTCON3,INT1IF ;清除INT1的中断标志;
RETI
MOVFF BSR_TEMP,BSR ;恢复BSR
MOVF W_TEMP,0 ;恢复WREG
MOVFF STATUS_TEMP,STATUS ;恢复STATUS
RETFIE
;****************主程序******************
MAIN:
NOP
CLRF INTCON ;禁止所有中断
CALL INITIAL ;初始化
CALL CAN_INITIAL ;CAN初始化
CALL INT0_INITIAL ;INTO初始化
CALL INT1_INITIAL ;INT1初始化
BSF INTCON,GIE ;总中断使能
BSF INTCON,PEIE ;外围中断使能
LOOP
CLRWDT
BTFSC JSBZW,0
CALL JSDXH ;接收到主机信号
BTFSC ZD0QC,0
CALL FSZD0QCJB ;发送前运启车警报
BTFSC ZD0QC,1
CALL FSZD0TCJB ;发送前运停车警报
BTFSC ZD1QC,0
CALL FSZD1QCJB ;发送后运启车警报
BTFSC ZD1QC,1
CALL FSZD1TCJB ;发送后运停车警报
GOTO LOOP
DD1 ;点动(前运)2007.6.11
CLRWDT
BTFSC PORTB,0
GOTO DD1
CALL D10US
BTFSC PORTB,0
GOTO DD1
BSF ZD0QC,1
;CALL FSZD0TCJB ;发送前运停车警报
GOTO LOOP
DD2 ;点动(后运)
CLRWDT
BTFSC PORTB,1
GOTO DD2
CALL D10US
BTFSC PORTB,1
GOTO DD2
BSF ZD1QC,1
;CALL FSZD1TCJB ;发送后运停车警报
GOTO LOOP ;2007.6.11
;*********接收到主机停发CAN信号子程序***********
JSDXH
BCF INTCON,GIE ;关总中断使能
MOVF RXB0EIDL,W
SUBLW 0X21 ;
BTFSS STATUS,Z ;命令字为21则停止发启车警报(前运)
GOTO ZD0TCTF
MOVF RXB0D0,W ;第一个数据帧为22则说明当前条件下不允许启车
SUBLW 0X22
BTFSC STATUS,Z
GOTO TIAO111
BCF ZD0QC,0
;BSF TFZD0BJ,0
BSF PORTB,5
BCF PORTB,6
INCF XHCS1
GOTO TIAOCHU
ZD0TCTF
MOVF RXB0EIDL,W
SUBLW 0X22 ;
BTFSS STATUS,Z ;命令字为22则停止发停车警报(前运)
GOTO ZD1QCTF
BCF ZD0QC,1
;BSF TFZD0BJ,1
BCF PORTB,5
BSF PORTB,6
CLRF XHCS1
GOTO TIAOCHU
ZD1QCTF
MOVF RXB0EIDL,W
SUBLW 0X23 ;
BTFSS STATUS,Z ;命令字为23则停止发启车警报(后运)
GOTO ZD1TCTF
MOVF RXB0D0,W ;第一个数据帧为22则说明当前条件下不允许启车
SUBLW 0X22
BTFSC STATUS,Z
GOTO TIAO222
BCF ZD1QC,0
;BSF TFZD1BJ,0
BSF PORTB,7
BCF PORTB,4
INCF XHCS2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -