#include <ioCAN128v.h> struct MOb { unsigned long id; unsigned char data [8]; }; void can_init (void); void can_tx (struct MOb msg); void can_rx (struct MOb msg); void can_init (void) { unsigned char i,j; //reset CAN interface CANGCON |= (1<<SWRES); //reset all MObs for ( i=0; i<15; i++) { CANPAGE = (i<<4); //select MOb CANCDMOB = 0; //disable MOb CANSTMOB = 0; //clear status CANIDT1 = 0; //clear ID CANIDT2 = 0; CANIDT3 = 0; CANIDT4 = 0; CANIDM1 = 0; //clear mask CANIDM2 = 0; CANIDM3 = 0; CANIDM4 = 0; for ( j=0; j<8; j++) CANMSG = 0; //clear data } // set CAN -> baudrate // bit timing -> datasheet 264 (check table) // 250Kbps 16MHz cpu-clk CANBT1 = 0x0E;//16M/8=2M CANBT2 = 0x04;//3QT CANBT3 = 0x13;//2+2=4 // clear CAN interrupt registers CANGIE = 0; // none interrupts CANIE1 = 0; // none interrupts on MObs CANIE2 = 0; CANSIT1 = 0; CANSIT2 = 0; //start CAN interface CANGCON = (1<<1); //wait until module ready while (!(CANGSTA & (1<<ENFG))); } void can_tx (struct MOb msg) { unsigned char i; //enable MOb1, auto increment index, start with index = 0 CANPAGE = (1<<4); //set IDE bit, length = 8 CANCDMOB = (1<<IDE) | (8<<DLC0); //write 29 Bit identifier msg.id <<= 3; CANIDT4 = (unsigned char) (msg.id&0xF8); CANIDT3 = (unsigned char) (msg.id>>8); CANIDT2 = (unsigned char) (msg.id>>16); CANIDT1 = (unsigned char) (msg.id>>24); //put data in mailbox for (i=0; i<8; i++) CANMSG = msg.data [i]; //enable transmission CANCDMOB |= (1<<CONMOB0); //wait until complete while (!(CANSTMOB & (1<<TXOK))); //reset flag CANSTMOB &= ~(1<<TXOK); } void can_rx (struct MOb msg) { unsigned char i; CANHPMOB=0; //select MOb0 CANPAGE = 0x00; //select MOb0 //clear MOb flags CANSTMOB = 0; // select ID which can be receive CANIDT4 = (unsigned char)(msg.id << 3); CANIDT3 = (unsigned char)(msg.id >> 5); CANIDT2 = (unsigned char)(msg.id >> 13); CANIDT1 = (unsigned char)(msg.id >> 21); // set mask in order to receive only the message with the ID CANIDM4 = 248; CANIDM3 = 255; CANIDM2 = 255; CANIDM1 = 255; // enable extended ID CANIDM4 |= (1<<IDEMSK); // enable reception and CANCDMOB=(1<<CONMOB1) | (1<<IDE); // wait until reception is complete while(!(CANSTMOB&(1<<RXOK))); // reset flag CANSTMOB &= ~(1<<RXOK); // get data for (i=0; i<(CANCDMOB&0xf); i++) msg.data [i] = CANMSG; //get identifier which has to be the same like ID msg.id = 0; msg.id |= ((unsigned long) CANIDT1<<24); msg.id |= ((unsigned long) CANIDT2<<16); msg.id |= ((unsigned long) CANIDT3<<8); msg.id |= (CANIDT4&0xF8); msg.id >>= 3; }