| 
 
|  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口接的两个指示灯,显示程序的状态! | 
 |