0 оценок0% нашли этот документ полезным (0 голосов)
42 просмотров3 страницы
This document contains code for initializing and testing a CAN port on an MC9S12 microcontroller. It defines registers for the CAN port and sets up two CAN message filters. The code sends a test message at startup and echos back any messages received with ID 2. It is intended as a simple example for communicating over CAN.
This document contains code for initializing and testing a CAN port on an MC9S12 microcontroller. It defines registers for the CAN port and sets up two CAN message filters. The code sends a test message at startup and echos back any messages received with ID 2. It is intended as a simple example for communicating over CAN.
Авторское право:
Attribution Non-Commercial (BY-NC)
Доступные форматы
Скачайте в формате TXT, PDF, TXT или читайте онлайн в Scribd
This document contains code for initializing and testing a CAN port on an MC9S12 microcontroller. It defines registers for the CAN port and sets up two CAN message filters. The code sends a test message at startup and echos back any messages received with ID 2. It is intended as a simple example for communicating over CAN.
Авторское право:
Attribution Non-Commercial (BY-NC)
Доступные форматы
Скачайте в формате TXT, PDF, TXT или читайте онлайн в Scribd
// 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 }