这几天一直在忙活 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);
}