打印

用PIC+SJA1000完成的自测试程序,能发不能收!请高手帮助解决一

[复制链接]
3204|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
splyc|  楼主 | 2008-2-16 09:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 LIST    P=16F877
        #INCLUDE    P16F877.INC
        AH      EQU     30H
        AL      EQU     31H
        ACCAHI  EQU     32H
        ACCALO  EQU     33H
        EXPA    EQU     34H
        ACCBHI  EQU     35H
        ACCBLO  EQU     36H
        EXPB    EQU     37H
        C1    EQU     38H
        C2    EQU     39H
        ACCDHI  EQU     40H
        ACCDLO  EQU     41H
        TEMP    EQU     42H
        SIGN    EQU     43H
        BB    EQU     44H
    COUNT1    EQU    45H
    COUNT2    EQU    46H
    ACCEHI    EQU    47H
    ACCELO    EQU    48H
    EXPE    EQU    49H
    ACCFHI    EQU    50H
    ACCFLO    EQU    51H
    EXPF    EQU    52H
    BB1    EQU    53H
    PE    EQU    54H
    STATUSS    EQU    55H
    WS    EQU    56H
    PE1    EQU    57H
    RXB1    EQU    58H
    RXB2    EQU    59H
    TMR1LS    EQU    60H
    TMR1HS    EQU    61H
    ACCCHI    EQU    62H
    ACCCLO    EQU    63H
    EXPC    EQU    64H
    RXB3    EQU    65H
    R10        EQU    70H
    R11        EQU    71H
    R12        EQU    72H
    R13        EQU    73H
    R0        EQU    74H
    R1        EQU    75H
;
        ORG    0
 MAIN    BCF    INTCON,GIE    ;开总中断
    BSF    STATUS,RP0
    MOVLW    87H        ;设AE口为I/O口--
    MOVWF    ADCON1    
    MOVLW    0C1H
    MOVWF    TRISC      
    MOVLW   1H
    MOVWF   TRISB
    BCF    STATUS,RP0
    CLRF    PORTD
    MOVLW   70H
    MOVWF   PORTB    ;CAN_ALE=0,CAN_CS=1,CAN_RD_WR=1
    CALL    CANINT        ;CAN初始化
MA    BSF    PORTC,1;内灯亮
    BSF        PORTC,2
    CALL    DELY
    BCF        PORTC,2;外灯XING
    CALL    CALL_F;发送子程序
    ;MOVLW    2
    ;MOVWF    PE
;MA1    CALL    CAN_R
;    BTFSS    PE1,0
;    GOTO    MA1
    CALL    CALL_S;接收子程序????
    BCF    PORTC,1;内灯熄灭
    CALL    DELY
    GOTO    MA

CALL_S    MOVLW    2
    MOVWF    PE
    CALL    CAN_R;读状态寄存器
    BTFSS    PE1,7;总线关闭
    GOTO    S1
    MOVLW    3
    MOVWF    PE
    CALL    CAN_R;读中断寄存器,清除中断位
    MOVLW    0CH
    MOVWF    PE1
    CLRF    PE
    CALL    CAN_W;方式寄存器的复位位清零
    BSF    PORTC,2;外灯亮
    CALL     DELY
    BCF    PORTC,2;若总线关闭,令外灯亮1秒后熄灭
    RETLW    0
S1    MOVLW    2
    MOVWF    PE
    CALL    CAN_R
    BTFSS    PE1,1;数据溢出,RXFIFO没有空间存储
    GOTO    S2
    MOVLW    1
    MOVWF    PE
    MOVLW    0CH
    MOVWF    PE1
    CALL    CAN_W;清除数据溢出状态位,释放接收缓冲器
    BSF    PORTC,2;外灯亮
    CALL     DELY
    BCF    PORTC,2;令外灯亮1秒后熄灭
    CALL     DELY
    BSF    PORTC,2;外灯亮
    CALL     DELY
    BCF    PORTC,2;令外灯亮1秒后熄灭,共亮两次
    RETLW    0
S2    BTFSS    PE1,0;接收到可用信息
    GOTO    S3;缓存无数据,退出接收?
    MOVLW    16
    MOVWF    PE
    CALL    CAN_R;读接收缓存器首地址中的数据
    BTFSS    PE1,6;第六位为1,是远程帧无数据
    GOTO    S4;是数据帧
    MOVLW    1
    MOVWF    PE
    MOVLW    4
    MOVWF    PE1
    CALL    CAN_W;写命令寄存器,释放接收缓冲器
    BSF    PORTC,2;外灯亮
    CALL     DELY
    BCF    PORTC,2;令外灯亮1秒后熄灭
    CALL     DELY
    BSF    PORTC,2;外灯亮
    CALL     DELY
    BCF    PORTC,2;令外灯亮1秒后熄灭
    BSF    PORTC,2;外灯亮
    CALL     DELY
    BCF    PORTC,2;令外灯亮1秒后熄灭,共亮三次
    GOTO    S3;退出接收
S4    MOVLW    16
    MOVWF    PE
    CALL    CAN_R;读数据帧的第一个字节
    MOVF    PE1,0;第一个字节取到W
    ANDLW    0FH;取数据长度码到W
    ADDLW    2
    MOVWF    R10;长度码加2字节的标识符存R10
    INCF    PE,1
    CALL    CAN_R;读下一个字节,标识符的第一字节
    MOVF    PE1,0
    MOVWF    R11;第一字节存R11
    INCF    PE,1
    CALL    CAN_R
    MOVF    PE1,0
    MOVWF    R12;第二字节存R12
    INCF    PE,1
    CALL    CAN_R
    MOVF    PE1,0
    MOVWF    R13;第三字节存R13
    MOVLW    1
    MOVWF    PE
    MOVLW    4
    MOVWF    PE1
    CALL    CAN_W;写命令寄存器,释放接收缓冲器
    MOVLW    5
    MOVWF    R0
S6    BSF    PORTC,2
    CALL    DELY
    BCF    PORTC,2
    CALL    DELY
    DECFSZ    R0,1
    GOTO    S6
S3    MOVLW    11;退出接收
    MOVWF    PE
    CALL    CAN_R;读仲裁丢失捕捉寄存器,释放
    INCF    PE
    CALL    CAN_R;读错误代码捕捉寄存器,释放
    RETLW    0
    
    


CALL_F    MOVLW    2;CAN发送数据子程序
    MOVWF    PE
W3    CALL    CAN_R;读SR状态寄存器
    BTFSC    PE1,4;SJA1000正在接收信息,则等待
    GOTO    W3
W4    CALL    CAN_R
    BTFSS    PE1,3;当前请求的发送未处理完,则等待
    GOTO    W4
W5    CALL    CAN_R
    BTFSS    PE1,2;发送缓存器锁定,则等待
    GOTO    W5
    MOVLW    1;111GAI,命令寄存器,释放接收缓冲器,中止发送单次
    MOVWF    PE
    MOVLW    6
    MOVWF    PE1
    CALL    CAN_W;111
    MOVLW    16;向发送缓存区写数据
    MOVWF    PE
    MOVLW    1
    MOVWF    PE1;标准帧格式,数据长度为1字节
    CALL    CAN_W
    CALL    DELY1
    INCF    PE
    MOVLW    55H
    MOVWF    PE1
    CALL    CAN_W
    CALL    DELY1
    INCF    PE
    MOVLW    55H
    MOVWF    PE1;GAI
    CALL    CAN_W
    CALL    DELY1
    INCF    PE
    MOVLW    55H
    MOVWF    PE1;数据为55H,GAI
    CALL    CAN_W
    CALL    DELY1
    MOVLW    1
    MOVWF    PE
    MOVLW    12H;GAI3???11
    MOVWF    PE1
    CALL    CAN_W;设置命令寄存器,开始自发送
    BSF    PORTC,2
    CALL    DELY
    CALL    DELY
    CALL    DELY
    CALL    DELY
    BCF    PORTC,2
    BSF    PORTC,3
    RETLW    0

    
    


CAN_W    BCF    PORTB,6        ;CS=0_2008/向CAN寄存器写命令子程序
    BSF        PORTB,7        ;ALE=1
    BSF    STATUS,RP0    ;
    CLRF    TRISD        ;D口设为输出
    BCF    STATUS,RP0
    MOVF    PE,0        ;PE-->PORTD(PE中存CAN寄存器地址)
    MOVWF    PORTD
    CALL    DELY1;GAI
    BCF    PORTB,7        ;ALE=0
    CALL    DELY1
    CLRF    PORTD        ;清除地址
    BCF    PORTB,4        ;WR=0
    CALL    DELY1
    MOVF    PE1,0        ;PE1-->PORTD(PE1中存CAN寄存器命令信号)
    MOVWF    PORTD
    CALL    DELY1
    BSF    PORTB,4        ;WR=1
    CALL    DELY1
    CLRF    PORTD
    BSF    PORTB,6        ;CS=1
    RETLW    0

CAN_R    BCF    PORTB,6        ;CS=0_2008/读CAN寄存器子程序
    BSF        PORTB,7        ;ALE=1
    BSF    STATUS,RP0      ;
    CLRF    TRISD        ;D口设为输出
    BCF    STATUS,RP0
    MOVF    PE,0        ;访问寄存器地址PE-->PORTD
    MOVWF    PORTD
    CALL    DELY1
    BCF    PORTB,7        ;ALE=0
    CALL    DELY1
    BSF    STATUS,RP0
    MOVLW    0FFH        ;D口设为输入
    MOVWF    TRISD
    BCF    STATUS,RP0
    CALL    DELY1
    BCF    PORTB,5        ;RD=0
    CALL    DELY1
    MOVF    PORTD,0        ;将寄存器内容读入PE1
    MOVWF    PE1    
    CALL    DELY1
    BSF    PORTB,5        ;RD=1
    BSF    PORTB,6        ;CS=1
    RETLW    0

CANINT    CLRF    PE;方式寄存器地址/2008,CAN初始化子程序
INT0    MOVLW    09H;GAI2
    MOVWF    PE1;要写入方式寄存器的数据存PE1
    CALL    CAN_W
    CALL    DELY1
    CALL    CAN_R;111GAI2,没有复位则重写方式寄存器
    BTFSS    PE1,0
    GOTO    INT0;111
    MOVLW    31
    MOVWF    PE;PE存CDR地址
    MOVLW    0C8H;GAI
    MOVWF    PE1;c8H-->CDR寄存器,选择PELICAN模式
    CALL    CAN_W
    MOVLW  4;写AMR寄存器
    MOVWF  R1;
    MOVLW  20
    MOVWF  PE
W1    MOVLW    0FFH
    MOVWF    PE1
    CALL    CAN_W
    INCF    PE
    DECFSZ    R1,1
    GOTO    W1
    MOVLW  4;写ACR寄存器
    MOVWF  R1
    MOVLW    16
    MOVWF    PE
W2    MOVLW    55H
    MOVWF    PE1
    CALL    CAN_W
    INCF    PE
    DECFSZ    R1,1
    GOTO    W2
    MOVLW    6;BTR0地址/写BTR0寄存器
    MOVWF    PE
    MOVLW    0H;GAI3!!!
    MOVWF    PE1;3H-->BTR0寄存器,选择500K波特率
    CALL    CAN_W
    MOVLW    7;BTR1地址/写BTR1寄存器
    MOVWF    PE
    MOVLW    1CH;GAI3!!!
    MOVWF    PE1;0FFH-->BTR1寄存器,选择10K波特率
    CALL    CAN_W
    MOVLW    8;OCR地址/写OCR寄存器
    MOVWF    PE
    MOVLW    0FAH;GAI2!!!!
    MOVWF    PE1;0AAH-->OCR寄存器
    CALL    CAN_W
    MOVLW    30;接收缓存起始地址寄存器/写寄存器
    MOVWF    PE
    MOVLW    0
    MOVWF    PE1;0-->接收缓存起始地址寄存器
    CALL    CAN_W
    MOVLW    15;TXERR地址/写TXERR寄存器
    MOVWF    PE
    CLRF    PE1
    CALL    CAN_W
    MOVLW    12;读ECC清除寄存器内容
    MOVWF    PE
    CALL    CAN_R
    CLRF    PE;方式寄存器地址
    MOVLW    0CH;INT1-----
    MOVWF    PE1
    CALL    CAN_W
    CALL    DELY1
    ;CALL    CAN_R;GAI2111
    ;MOVLW    0CH
;    SUBWF    PE1,0;减
;    BTFSS    STATUS,2;Z=1
;    GOTO    INT1;111GAI3
    RETLW    0




DELY    CLRF    COUNT2        ;延时子程序,系统时钟为16MHZ时,延时为1S-2008
    CLRF    COUNT1
    MOVLW    14H
    MOVWF    WS
LOOP    INCFSZ    COUNT1
    GOTO    LOOP
    INCFSZ    COUNT2
    GOTO    LOOP
    DECFSZ    WS
    GOTO    LOOP
    MOVLW    4CH
    MOVWF    COUNT2
LOOP1    MOVLW    5
    MOVWF    COUNT1
LOOP2    INCFSZ    COUNT1
    GOTO    LOOP2
    DECFSZ    COUNT2
    GOTO    LOOP1
    RETLW    0

DELY1    MOVLW    30H        ;延时子程序
    MOVWF    COUNT2
    CLRF    COUNT1
LOOP3    INCFSZ    COUNT1
    GOTO    LOOP3
    DECFSZ    COUNT2
    GOTO    LOOP3
    RETLW    0
    END
我用的是C1C2口接的两个指示灯,显示程序的状态!
沙发
splyc|  楼主 | 2008-2-16 17:24 | 只看该作者

是不是代码太长,吓到大家了!

我总感觉是SJA1000初始化的问题,或是硬件的问题!
我在程序中用的是查询方式接收,即查询SJA1000状态寄存器的第0位为1时接收.
CAN_W和CAN_R是模拟SJA1000的写和读子程序.CANINT子程序为初始化子程序,请各位重点帮助看一下!
硬件: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端。
现在已经调了好久了,能发送就是接收不到!真是急死人了!

使用特权

评论回复
板凳
xwj| | 2008-2-16 18:56 | 只看该作者

呵呵,谁会去帮你分析程序啊? 而且还是汇编的...

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

19

帖子

0

粉丝