can.h ******************************************************************************/ #ifndef __can_h__ #define __can_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); #endif **************************************************************************************************************** #include <avr/io.h> #include "can.h" void can_init (void) { //reset CAN interface CANGCON |= (1<<SWRES); //reset all MObs for (unsigned char 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 (unsigned char j=0; j<8; j++) CANMSG = 0; //clear data } // set CAN -> baudrate // bit timing -> datasheet 264 (check table) // 250Kbps 16MHz cpu-clk CANBT1 = 0x0E;for CANBT2 = 0x04; CANBT3 = 0x13; // 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<<ENASTB); //wait until module ready while (!(CANGSTA & (1<<ENFG))); } void can_tx (struct MOb msg) { //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 (unsigned char i=0; i<8; i++) CANMSG = msg.data ; //enable transmission CANCDMOB |= (1<<CONMOB0); //wait until complete while (!(CANSTMOB & (1<<TXOK))); //reset flag CANSTMOB &= ~(1<<TXOK); } void can_rx (struct MOb msg) { CANHPMOB=0; //select MOb0 CANPAGE = 0x00; //select MOb0 //clear MOb flags CANSTMOB = 0; // select ID which can be receive CANIDT4 = (uint8_t) (msg.id << 3); CANIDT3 = (uint8_t) (msg.id >> 5); CANIDT2 = (uint8_t) (msg.id >> 13); CANIDT1 = (uint8_t) (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 (unsigned char i=0; i<(CANCDMOB&0xf); i++) msg.data = 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; } ************************************************************************************************************************** #include <avr/io.h> #include <stdlib.h> #include "usart0.h" #include "can.h" // message to receive struct MOb msg={0x1,{0,0,0,0,0,0,0,0}}; // toggle the LED on the Crumb-Board #define toggleLED() (DDRB^=(1<<7)) int main(){ // init usart on 19200 8N1 at 16 MHz cpu clock usart0_init(51); // greet the world usart0_transmit_string("Hello World\n"); // init the can interface can_init(); while(1){ // send can message can_rx(msg); toggleLED(); } } *************************************************************************************** usart0.c #include <avr/io.h> #include "usart0.h" void usart0_init( unsigned int baudrate ) { UBRR0H = (unsigned char) (baudrate>>8); UBRR0L = (unsigned char) baudrate; UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) ); UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); } unsigned char usart0_receive( void ) { while ( !(UCSR0A & (1<<RXC0)) ); return UDR0; } void usart0_transmit( unsigned char data ) { while ( !(UCSR0A & (1<<UDRE0)) ); UDR0 = data; } void usart0_transmit_string(char* p){ while (*p) usart0_transmit(*p++); } ******************************************************************************************************************* usart0.h #ifndef __usart0_h__ #define __usart0_h__ void usart0_init( unsigned int baudrate ); unsigned char usart0_receive( void ); void usart0_transmit( unsigned char data ); void usart0_transmit_string(char* p); #endif