LIST P=16F877<br /> #INCLUDE P16F877.INC<br /> AH EQU 30H<br /> AL EQU 31H<br /> ACCAHI EQU 32H<br /> ACCALO EQU 33H<br /> EXPA EQU 34H<br /> ACCBHI EQU 35H<br /> ACCBLO EQU 36H<br /> EXPB EQU 37H<br /> C1 EQU 38H<br /> C2 EQU 39H<br /> ACCDHI EQU 40H<br /> ACCDLO EQU 41H<br /> TEMP EQU 42H<br /> SIGN EQU 43H<br /> BB EQU 44H<br /> COUNT1 EQU 45H<br /> COUNT2 EQU 46H<br /> ACCEHI EQU 47H<br /> ACCELO EQU 48H<br /> EXPE EQU 49H<br /> ACCFHI EQU 50H<br /> ACCFLO EQU 51H<br /> EXPF EQU 52H<br /> BB1 EQU 53H<br /> PE EQU 54H<br /> STATUSS EQU 55H<br /> WS EQU 56H<br /> PE1 EQU 57H<br /> RXB1 EQU 58H<br /> RXB2 EQU 59H<br /> TMR1LS EQU 60H<br /> TMR1HS EQU 61H<br /> ACCCHI EQU 62H<br /> ACCCLO EQU 63H<br /> EXPC EQU 64H<br /> RXB3 EQU 65H<br /> R10 EQU 70H<br /> R11 EQU 71H<br /> R12 EQU 72H<br /> R13 EQU 73H<br /> R0 EQU 74H<br /> R1 EQU 75H<br />;<br /> ORG 0<br />MAIN BCF INTCON,GIE ;开总中断<br /> BSF STATUS,RP0<br /> MOVLW 87H ;设AE口为I/O口--<br /> MOVWF ADCON1 <br /> MOVLW 0C1H<br /> MOVWF TRISC <br /> MOVLW 1H<br /> MOVWF TRISB<br /> BCF STATUS,RP0<br /> CLRF PORTD<br /> MOVLW 70H<br /> MOVWF PORTB ;CAN_ALE=0,CAN_CS=1,CAN_RD_WR=1<br /> CALL CANINT ;CAN初始化<br />MA BSF PORTC,1;内灯亮<br /> BSF PORTC,2<br /> CALL DELY<br /> BCF PORTC,2;外灯XING<br /> CALL CALL_F;发送子程序<br /> ;MOVLW 2<br /> ;MOVWF PE<br />;MA1 CALL CAN_R<br />; BTFSS PE1,0<br />; GOTO MA1<br /> CALL CALL_S;接收子程序????<br /> BCF PORTC,1;内灯熄灭<br /> CALL DELY<br /> GOTO MA<br /><br />CALL_S MOVLW 2<br /> MOVWF PE<br /> CALL CAN_R;读状态寄存器<br /> BTFSS PE1,7;总线关闭<br /> GOTO S1<br /> MOVLW 3<br /> MOVWF PE<br /> CALL CAN_R;读中断寄存器,清除中断位<br /> MOVLW 0CH<br /> MOVWF PE1<br /> CLRF PE<br /> CALL CAN_W;方式寄存器的复位位清零<br /> BSF PORTC,2;外灯亮<br /> CALL DELY<br /> BCF PORTC,2;若总线关闭,令外灯亮1秒后熄灭<br /> RETLW 0<br />S1 MOVLW 2<br /> MOVWF PE<br /> CALL CAN_R<br /> BTFSS PE1,1;数据溢出,RXFIFO没有空间存储<br /> GOTO S2<br /> MOVLW 1<br /> MOVWF PE<br /> MOVLW 0CH<br /> MOVWF PE1<br /> CALL CAN_W;清除数据溢出状态位,释放接收缓冲器<br /> BSF PORTC,2;外灯亮<br /> CALL DELY<br /> BCF PORTC,2;令外灯亮1秒后熄灭<br /> CALL DELY<br /> BSF PORTC,2;外灯亮<br /> CALL DELY<br /> BCF PORTC,2;令外灯亮1秒后熄灭,共亮两次<br /> RETLW 0<br />S2 BTFSS PE1,0;接收到可用信息<br /> GOTO S3;缓存无数据,退出接收?<br /> MOVLW 16<br /> MOVWF PE<br /> CALL CAN_R;读接收缓存器首地址中的数据<br /> BTFSS PE1,6;第六位为1,是远程帧无数据<br /> GOTO S4;是数据帧<br /> MOVLW 1<br /> MOVWF PE<br /> MOVLW 4<br /> MOVWF PE1<br /> CALL CAN_W;写命令寄存器,释放接收缓冲器<br /> BSF PORTC,2;外灯亮<br /> CALL DELY<br /> BCF PORTC,2;令外灯亮1秒后熄灭<br /> CALL DELY<br /> BSF PORTC,2;外灯亮<br /> CALL DELY<br /> BCF PORTC,2;令外灯亮1秒后熄灭<br /> BSF PORTC,2;外灯亮<br /> CALL DELY<br /> BCF PORTC,2;令外灯亮1秒后熄灭,共亮三次<br /> GOTO S3;退出接收<br />S4 MOVLW 16<br /> MOVWF PE<br /> CALL CAN_R;读数据帧的第一个字节<br /> MOVF PE1,0;第一个字节取到W<br /> ANDLW 0FH;取数据长度码到W<br /> ADDLW 2<br /> MOVWF R10;长度码加2字节的标识符存R10<br /> INCF PE,1<br /> CALL CAN_R;读下一个字节,标识符的第一字节<br /> MOVF PE1,0<br /> MOVWF R11;第一字节存R11<br /> INCF PE,1<br /> CALL CAN_R<br /> MOVF PE1,0<br /> MOVWF R12;第二字节存R12<br /> INCF PE,1<br /> CALL CAN_R<br /> MOVF PE1,0<br /> MOVWF R13;第三字节存R13<br /> MOVLW 1<br /> MOVWF PE<br /> MOVLW 4<br /> MOVWF PE1<br /> CALL CAN_W;写命令寄存器,释放接收缓冲器<br /> MOVLW 5<br /> MOVWF R0<br />S6 BSF PORTC,2<br /> CALL DELY<br /> BCF PORTC,2<br /> CALL DELY<br /> DECFSZ R0,1<br /> GOTO S6<br />S3 MOVLW 11;退出接收<br /> MOVWF PE<br /> CALL CAN_R;读仲裁丢失捕捉寄存器,释放<br /> INCF PE<br /> CALL CAN_R;读错误代码捕捉寄存器,释放<br /> RETLW 0<br /> <br /> <br /><br /><br />CALL_F MOVLW 2;CAN发送数据子程序<br /> MOVWF PE<br />W3 CALL CAN_R;读SR状态寄存器<br /> BTFSC PE1,4;SJA1000正在接收信息,则等待<br /> GOTO W3<br />W4 CALL CAN_R<br /> BTFSS PE1,3;当前请求的发送未处理完,则等待<br /> GOTO W4<br />W5 CALL CAN_R<br /> BTFSS PE1,2;发送缓存器锁定,则等待<br /> GOTO W5<br /> MOVLW 1;111GAI,命令寄存器,释放接收缓冲器,中止发送单次<br /> MOVWF PE<br /> MOVLW 6<br /> MOVWF PE1<br /> CALL CAN_W;111<br /> MOVLW 16;向发送缓存区写数据<br /> MOVWF PE<br /> MOVLW 1<br /> MOVWF PE1;标准帧格式,数据长度为1字节<br /> CALL CAN_W<br /> CALL DELY1<br /> INCF PE<br /> MOVLW 55H<br /> MOVWF PE1<br /> CALL CAN_W<br /> CALL DELY1<br /> INCF PE<br /> MOVLW 55H<br /> MOVWF PE1;GAI<br /> CALL CAN_W<br /> CALL DELY1<br /> INCF PE<br /> MOVLW 55H<br /> MOVWF PE1;数据为55H,GAI<br /> CALL CAN_W<br /> CALL DELY1<br /> MOVLW 1<br /> MOVWF PE<br /> MOVLW 12H;GAI3???11<br /> MOVWF PE1<br /> CALL CAN_W;设置命令寄存器,开始自发送<br /> BSF PORTC,2<br /> CALL DELY<br /> CALL DELY<br /> CALL DELY<br /> CALL DELY<br /> BCF PORTC,2<br /> BSF PORTC,3<br /> RETLW 0<br /><br /> <br /> <br /><br /><br />CAN_W BCF PORTB,6 ;CS=0_2008/向CAN寄存器写命令子程序<br /> BSF PORTB,7 ;ALE=1<br /> BSF STATUS,RP0 ;<br /> CLRF TRISD ;D口设为输出<br /> BCF STATUS,RP0<br /> MOVF PE,0 ;PE-->PORTD(PE中存CAN寄存器地址)<br /> MOVWF PORTD<br /> CALL DELY1;GAI<br /> BCF PORTB,7 ;ALE=0<br /> CALL DELY1<br /> CLRF PORTD ;清除地址<br /> BCF PORTB,4 ;WR=0<br /> CALL DELY1<br /> MOVF PE1,0 ;PE1-->PORTD(PE1中存CAN寄存器命令信号)<br /> MOVWF PORTD<br /> CALL DELY1<br /> BSF PORTB,4 ;WR=1<br /> CALL DELY1<br /> CLRF PORTD<br /> BSF PORTB,6 ;CS=1<br /> RETLW 0<br /><br />CAN_R BCF PORTB,6 ;CS=0_2008/读CAN寄存器子程序<br /> BSF PORTB,7 ;ALE=1<br /> BSF STATUS,RP0 ;<br /> CLRF TRISD ;D口设为输出<br /> BCF STATUS,RP0<br /> MOVF PE,0 ;访问寄存器地址PE-->PORTD<br /> MOVWF PORTD<br /> CALL DELY1<br /> BCF PORTB,7 ;ALE=0<br /> CALL DELY1<br /> BSF STATUS,RP0<br /> MOVLW 0FFH ;D口设为输入<br /> MOVWF TRISD<br /> BCF STATUS,RP0<br /> CALL DELY1<br /> BCF PORTB,5 ;RD=0<br /> CALL DELY1<br /> MOVF PORTD,0 ;将寄存器内容读入PE1<br /> MOVWF PE1 <br /> CALL DELY1<br /> BSF PORTB,5 ;RD=1<br /> BSF PORTB,6 ;CS=1<br /> RETLW 0<br /><br />CANINT CLRF PE;方式寄存器地址/2008,CAN初始化子程序<br />INT0 MOVLW 09H;GAI2<br /> MOVWF PE1;要写入方式寄存器的数据存PE1<br /> CALL CAN_W<br /> CALL DELY1<br /> CALL CAN_R;111GAI2,没有复位则重写方式寄存器<br /> BTFSS PE1,0<br /> GOTO INT0;111<br /> MOVLW 31<br /> MOVWF PE;PE存CDR地址<br /> MOVLW 0C8H;GAI<br /> MOVWF PE1;c8H-->CDR寄存器,选择PELICAN模式<br /> CALL CAN_W<br /> MOVLW 4;写AMR寄存器<br /> MOVWF R1;<br /> MOVLW 20<br /> MOVWF PE<br />W1 MOVLW 0FFH<br /> MOVWF PE1<br /> CALL CAN_W<br /> INCF PE<br /> DECFSZ R1,1<br /> GOTO W1<br /> MOVLW 4;写ACR寄存器<br /> MOVWF R1<br /> MOVLW 16<br /> MOVWF PE<br />W2 MOVLW 55H<br /> MOVWF PE1<br /> CALL CAN_W<br /> INCF PE<br /> DECFSZ R1,1<br /> GOTO W2<br /> MOVLW 6;BTR0地址/写BTR0寄存器<br /> MOVWF PE<br /> MOVLW 0H;GAI3!!!<br /> MOVWF PE1;3H-->BTR0寄存器,选择500K波特率<br /> CALL CAN_W<br /> MOVLW 7;BTR1地址/写BTR1寄存器<br /> MOVWF PE<br /> MOVLW 1CH;GAI3!!!<br /> MOVWF PE1;0FFH-->BTR1寄存器,选择10K波特率<br /> CALL CAN_W<br /> MOVLW 8;OCR地址/写OCR寄存器<br /> MOVWF PE<br /> MOVLW 0FAH;GAI2!!!!<br /> MOVWF PE1;0AAH-->OCR寄存器<br /> CALL CAN_W<br /> MOVLW 30;接收缓存起始地址寄存器/写寄存器<br /> MOVWF PE<br /> MOVLW 0<br /> MOVWF PE1;0-->接收缓存起始地址寄存器<br /> CALL CAN_W<br /> MOVLW 15;TXERR地址/写TXERR寄存器<br /> MOVWF PE<br /> CLRF PE1<br /> CALL CAN_W<br /> MOVLW 12;读ECC清除寄存器内容<br /> MOVWF PE<br /> CALL CAN_R<br /> CLRF PE;方式寄存器地址<br /> MOVLW 0CH;INT1-----<br /> MOVWF PE1<br /> CALL CAN_W<br /> CALL DELY1<br /> ;CALL CAN_R;GAI2111<br /> ;MOVLW 0CH<br />; SUBWF PE1,0;减<br />; BTFSS STATUS,2;Z=1<br />; GOTO INT1;111GAI3<br /> RETLW 0<br /><br /><br /><br /><br />DELY CLRF COUNT2 ;延时子程序,系统时钟为16MHZ时,延时为1S-2008<br /> CLRF COUNT1<br /> MOVLW 14H<br /> MOVWF WS<br />LOOP INCFSZ COUNT1<br /> GOTO LOOP<br /> INCFSZ COUNT2<br /> GOTO LOOP<br /> DECFSZ WS<br /> GOTO LOOP<br /> MOVLW 4CH<br /> MOVWF COUNT2<br />LOOP1 MOVLW 5<br /> MOVWF COUNT1<br />LOOP2 INCFSZ COUNT1<br /> GOTO LOOP2<br /> DECFSZ COUNT2<br /> GOTO LOOP1<br /> RETLW 0<br /><br />DELY1 MOVLW 30H ;延时子程序<br /> MOVWF COUNT2<br /> CLRF COUNT1<br />LOOP3 INCFSZ COUNT1<br /> GOTO LOOP3<br /> DECFSZ COUNT2<br /> GOTO LOOP3<br /> RETLW 0<br /> END<br />我用的是C1C2口接的两个指示灯,显示程序的状态!<br />我总感觉是SJA1000初始化的问题,或是硬件的问题!<br />我在程序中用的是查询方式接收,即查询SJA1000状态寄存器的第0位为1时接收.<br />CAN_W和CAN_R是模拟SJA1000的写和读子程序.CANINT子程序为初始化子程序,请各位重点帮助看一下!<br />硬件:PIC16F877和SJA1000都是低电平复位,接在一点用按钮复位,PIC和SJA1000都是16MHZ晶振,两个小灯分别接RC1和RC2,SJA1000的ALE、CS、RD、WR接单片机RB7至RB4,SJA1000的RX1接地,MODE接+5V,SJA1000的TX1悬空,SJA1000的TX0、RX0分别接82C250的TXD和RXD端。<br />现在已经调了好久了,能发送就是接收不到!真是急死人了!<br /> <br /> |
|