最近研究这块芯片,也找了点资料,现在整理完的程序如下,和大家分享。
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"
/****************************************************************/
/* CAN initialization */
/****************************************************************/
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)));
}
/****************************************************************/
/* CAN transmission via mailbox 1 (polling) */
/****************************************************************/
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);
}
/****************************************************************/
/* CAN reception evia mailbox 0 (polling) */
/****************************************************************/
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"
/* Initialize UART */
void usart0_init( unsigned int baudrate )
{
/* Set the baud rate */
UBRR0H = (unsigned char) (baudrate>>8);
UBRR0L = (unsigned char) baudrate;
/* Enable UART receiver and transmitter */
UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );
/* Set frame format: 8N1 */
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}
/* Read and write functions */
unsigned char usart0_receive( void )
{
/* Wait for incomming data */
while ( !(UCSR0A & (1<<RXC0)) );
/* Return the data */
return UDR0;
}
void usart0_transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !(UCSR0A & (1<<UDRE0)) );
/* Start transmittion */
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
|