AT90CAN128的CAN编程

来源:互联网 发布:网络测试仪精明鼠 编辑:程序博客网 时间:2024/06/06 17:25

这几天一直在忙活 AT90CAN128的CAN编程,几天终于有眉目了。其实他的can用起来不复杂,只是一开始没有仔细看手册,走了不少弯路。

编译器ICCAVR

4M晶振

50K波特率

void can_init(void)
{
    // CAN Controller initialization
    // CAN Controller initialization

    // CAN System Clock: 400.0 kHz
    CANBT1=0x12;
    // Propagation Time Segement: 7.500 us
    // Re-Sync Jump Width: 2.500 us
    CANBT2=0x04;
    // Sample Point(s): 3
    // Phase Segment 1: 5.000 us
    // Phase Segment 2: 5.000 us
    CANBT3=0x13;
    // CAN Timer Clock Period: 2.000 us
    CANTCON=0x00;

    //--------------can_MOB INITIAL-------------------
    //MOB0=RX
    CANPAGE  = 0x00;                                                              //MOB0,自动增量,初值为0
    CANSTMOB = 0;
    CANCDMOB = 0x80;  // RX                                                       //can2a,DLC=8
    CANIDT4 = 0x00;                                                               //
    CANIDT3 = 0x00;                                                               //
    CANIDT2 = 0x00;                                                               //
    CANIDT1 = 0x00;                                                               //

    CANIDM4  = 0x00;                                                              //                             11111 100
    CANIDM3  = 0x00;                                                              //                             11111 111
    CANIDM2  = 0x00;                                                              //                             11111 111
    CANIDM1  = 0x00;                                                              //CANIDM4-1数据校验屏蔽寄存器  00000 111

    //MOB1=TX
    CANPAGE = 0x10;
    CANSTMOB = (1<<6);  //txok
    CANCDMOB = 0x08;
    CANIDT4 = 0x00;                                                               //
    CANIDT3 = 0x00;                                                               //
    CANIDT2 = 0xe0;                                                               //
    CANIDT1 = 0x00;                                                               //

    CANIDM4  = 0x00;                                                              //                             11111 100
    CANIDM3  = 0x00;                                                              //                             11111 111
    CANIDM2  = 0x00;                                                              //                             11111 111
    CANIDM1  = 0x00;                                                              //CANIDM4-1数据校验屏蔽寄存器  00000 111

    // CAN Interrupts:
    // Timer Overrun: Off
    // General Errors: Off
    // Frame Buffer: Off
    // MOb Errors: Off
    // Transmit: Off
    // Receive: Off
    // Bus Off: Off
    // All, except Timer Overrun: On
    CANGIE=0xf0;
    // MOb0: Enabled, MOb1: Enabled, MOb2: Disabled, MOb3: Disabled, MOb4: Disabled, MOb5: Disabled, MOb6: Disabled, MOb7: Disabled
    CANEN2=0xff;
    // MOb8: Disabled, MOb9: Disabled, MOb10: Disabled, MOb11: Disabled, MOb12: Disabled, MOb13: Disabled, MOb14: Disabled
    CANEN1=0xff;
    // MOb0..7 Interrupts: MOb0: On, MOb1: On, MOb2: Off, MOb3: Off, MOb4: Off, MOb5: Off, MOb6: Off, MOb7: Off
    CANIE2=0x03;
    // MOb8..14 Interrupts: MOb8: Off, MOb9: Off, MOb10: Off, MOb11: Off, MOb12: Off, MOb13: Off, MOb14: Off
    CANIE1=0x00;
    // Highest Interrupt Priority: MOb0
    CANHPMOB=0x00;

    CANGCON |= 0x02;      //CAN控制器启动

}

// CAN interrupt service routine
#pragma interrupt_handler can_isr:19
void can_isr(void)
{
    // Place your code here
    unsigned char i, flag;

    CANGIE &= ~(1<<ENRX);                  //关接收中断****
    LED_RUN(ON);
    flag = CANSIT2;
    //-----------------------------------------------------
    if (flag & (1<<0))
    {
        CANPAGE = 0<<4;
        for(i = 0; i < 8; i++)
        {
            data_buf[i]=CANMSG;           //取得8个字节的数据
        }
        CANPAGE = 0<<4;
        CANSTMOB &= ~(1<<RXOK);                //清中断标志****
        CANCDMOB = 0x80;                       //接收使能
    }
    if (flag & (1<<1))
    {
        CANPAGE = 1<<4;
        CANSTMOB &= ~(1<<TXOK);                //清中断标志****
    }
    //------------------------------------------------------
    LED_RUN(OFF);
    CANGIE |=(1<<ENRX);
}

void can_send (unsigned char n)
{
    unsigned char i;

    CANGIE &= ~(1<<ENRX);

    CANPAGE = (n<<4);                              //MOB_n, auto increment, index 0
    if (CANSTMOB & (1<<TXOK))
    {
        CANSTMOB &= ~(1<<TXOK);

        for(i = 0; i < 8; i++)
        {
            CANMSG = data_buf[i];
        }
        CANCDMOB = 0x48;
    }

    CANGIE |=(1<<ENRX);
}

原创粉丝点击