You are on page 1of 3

// intact in order to encourage you to visit our web site

// at www.zanthic.com home of the CAN-4-USB interface


// This simple program was written as a quick and easy
// example of initializing and testing the msCAN port (V2.14)
// on an MC9S12 processor. No warranty implied or given.
// This program was written as a single file for
// simplicity and only some of the registers are included.
// Written by Steve Letkeman Feb 2004
// compiled using the ICC12 compiler from imagecraft (www.imagecraft.com)
// Vector file not included but only contains two entries, start at 0xFFFE
// and the CAN0 receive interrupt vector pointing to CAN_Receive()
// sends CAN ID 1 (29 bit) at power up and receives ID 2 (29 bit) and
// echos back to ID 1 when received
#define CAN0CTL0 *(unsigned char volatile *)(0x0140)
#define CAN0CTL1 *(unsigned char volatile *)(0x0141)
#define CAN0BTR0 *(unsigned char volatile *)(0x0142)
#define CAN0BTR1 *(unsigned char volatile *)(0x0143)
#define CAN0RFLG *(unsigned char volatile *)(0x0144)
#define CAN0RIER *(unsigned char volatile *)(0x0145)
#define CAN0TFLG *(unsigned char volatile *)(0x0146)
//#define CAN0TIER *(unsigned char volatile *)(0x0147)
//#define CAN0TARQ *(unsigned char volatile *)(0x0148)
//#define CAN0TAAK *(unsigned char volatile *)(0x0149)
#define CAN0TBSEL *(unsigned char volatile *)(0x014A)
#define CAN0IDAC *(unsigned char volatile *)(0x014B)
//#define CAN0RXERR *(unsigned char volatile *)(0x014E)
//#define CAN0TXERR *(unsigned char volatile *)(0x014F)
#define CAN0IDAR0 *(unsigned char volatile *)(0x0150)
#define CAN0IDAR1 *(unsigned char volatile *)(0x0151)
#define CAN0IDAR2 *(unsigned char volatile *)(0x0152)
#define CAN0IDAR3 *(unsigned char volatile *)(0x0153)
#define CAN0IDMR0 *(unsigned char volatile *)(0x0154)
#define CAN0IDMR1 *(unsigned char volatile *)(0x0155)
#define CAN0IDMR2 *(unsigned char volatile *)(0x0156)
#define CAN0IDMR3 *(unsigned char volatile *)(0x0157)
#define CAN0IDAR4 *(unsigned char volatile *)(0x0158)
#define CAN0IDAR5 *(unsigned char volatile *)(0x0159)
#define CAN0IDAR6 *(unsigned char volatile *)(0x015A)
#define CAN0IDAR7 *(unsigned char volatile *)(0x015B)
#define CAN0IDMR4 *(unsigned char volatile *)(0x015C)
#define CAN0IDMR5 *(unsigned char volatile *)(0x015D)
#define CAN0IDMR6 *(unsigned char volatile *)(0x015E)
#define CAN0IDMR7 *(unsigned char volatile *)(0x015F)
#define CAN0RXFG (unsigned char volatile *)(0x0160)
#define CAN0TXFG (unsigned char volatile *)(0x0170)
#define CANE 0x80
#define INITAK 1
#define INITRQ 1
#define SLPRQ 2
#define SLPAK 2
void SendCANMessage(unsigned char NumBytes, unsigned char *BufPntr);
void CANInit(void);
void main(void)
{
unsigned char BufPntr[8];
CANInit();
asm("cli");
BufPntr[0]=0x11;
BufPntr[1]=0x22;
BufPntr[2]=0x33;
BufPntr[3]=0x44;
BufPntr[4]=0x55;
BufPntr[5]=0x66;
BufPntr[6]=0x77;
BufPntr[7]=0x88;
SendCANMessage(8, BufPntr); // send a CAN packet with 8 bytes of data
while(1); // wait here for receive interupt
}
// #############################################################################
// Incoming CAN messages will be caught here
#pragma interrupt_handler CAN_Receive
void CAN_Receive(void)
{
unsigned char Temp[8];
Temp[0]=*(CAN0RXFG+4); // Grab the first data byte
// currently no checking for number of bytes etc
SendCANMessage(1, Temp); // send it back
CAN0RFLG |=1; // clear rec flag
}
// #############################################################################
void SendCANMessage(unsigned char NumBytes, unsigned char *BufPntr)
{
unsigned char NACAN,C;
while(!CAN0TFLG); // wait for available buffer
NACAN=CAN0TFLG; // get the next available CAN buffer
CAN0TBSEL=NACAN;
*(CAN0TXFG+0)=0x00; // set the transmit ID
*(CAN0TXFG+1)=0x08; // extended ID (29 bit)
*(CAN0TXFG+2)=0x00;
*(CAN0TXFG+3)=0x02; // ID=00-00-00-01
if (NumBytes>8) NumBytes=8;
for (C=0;C<NumBytes;C++)
*(CAN0TXFG+4+C)=*BufPntr++; // store the data
*(CAN0TXFG+0x0C)=NumBytes; // set number of bytes to send
NACAN=CAN0TBSEL;
CAN0TFLG =NACAN; // transmit
}
// #############################################################################
void CANInit(void)
{
CAN0CTL0 |= INITRQ; // set INITRQ, this will also set INITAK
while (!(CAN0CTL1 & INITAK)); // wait for init mode to occur
CAN0CTL1 = CANE; // Set CANE just in case this is the first time after reset
CAN0BTR0=0x03;
CAN0BTR1=0x32; // for a CAN Baud of 500kbps at 16Mhz crystal
CAN0IDMR0=0x00;
CAN0IDMR1=0x08; //IDE=1
CAN0IDMR2=0x00;
CAN0IDMR3=0x00;
CAN0IDAR0=0x00;
CAN0IDAR1=0x18; // SRR&IDE=1
CAN0IDAR2=0x00;
CAN0IDAR3=0x04; // ID=2, remote frame (bit 0)=0
// set the second filter to must match 0xFFFFFFFF
CAN0IDMR4=0;
CAN0IDMR5=8; //IDE=1
CAN0IDMR6=0;
CAN0IDMR7=0;
CAN0IDAR4=0xFF;
CAN0IDAR5=0xFF;
CAN0IDAR6=0xFF;
CAN0IDAR7=0xFF;
CAN0IDAC=0; // set filters to 2 32 bit acceptance filters
CAN0CTL0 &= ~INITRQ; // clear INITRQ
while (CAN0CTL1 & INITAK);
CAN0CTL1 |= CANE; // Set CANE just in case this is the first time after reset
CAN0RIER |= 1; // enable receive interrupt
}

You might also like