Hello,
I am trying to work with the MSCAN-Module of the HCS12.
I have CAN-Dongle for a PC and try to send a CAN Message from the PC
to the HCS12. I receive the message with the HCS12 and show the data
at some LED's. But at the Computer I always get the Error-Message
BUSHEAVY.
Could you have a look at my code for the HCS12 and tell me what's
wrong. Perhaps the baud rate is wrong.
I do not understand how to set the baud rate completely. Perhaps
someone can tell me how it works and what baud rate I set in my code.
Sorry, for the bad english. I am still learning.
void main(void)
{
DDRB = 0xFF; // DataDirection-PortB Output
PORTB = 0xFF;
init();
CAN0RFLG= 0xc3;
CAN0RIER= 0x01;
cli(); //enable the global interrupts
while (!(CAN0CTL0 & 0x80))
{
PORTB= ~CAN0RXFG[4];
CAN0RFLG= 0x01;
}
} /*** end of main ***/
void init(void)
{
//CAN0CTL1 = 0x80; //Modul on
CAN0CTL0 = 0x01;
while (!(CAN0CTL1 & 0x01));
CAN0BTR0 = 0x41; // Timequanta
CAN0BTR1 = 0x23; // Timequanta
CAN0CTL1 = 0x80; // Modul on
CAN0IDAC |= 0x30; // Filter closed
CAN0CTL0 |= 0x80;
CAN0CTL0= 0x00; // Exit Initialization Mode
while((CAN0CTL1 & 0x00) != 0);
}
void sei(void)
{
_asm("sei");
}
void cli(void)
{
_asm("cli");
}
------------------------------------

(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )
here's some sample code from years ago that is a little out of date but
it should be enough
to help you figure out what's going on
steve
// This file may be freely distributed as long as this header remains
// 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
*(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
}
forum_user77 wrote:
>
> Hello,
>
> I am trying to work with the MSCAN-Module of the HCS12.
>
> I have CAN-Dongle for a PC and try to send a CAN Message from the PC
> to the HCS12. I receive the message with the HCS12 and show the data
> at some LED's. But at the Computer I always get the Error-Message
> BUSHEAVY.
>
> Could you have a look at my code for the HCS12 and tell me what's
> wrong. Perhaps the baud rate is wrong.
>
> I do not understand how to set the baud rate completely. Perhaps
> someone can tell me how it works and what baud rate I set in my code.
>
> Sorry, for the bad english. I am still learning.
>
> void main(void)
> {
> DDRB = 0xFF; // DataDirection-PortB Output
> PORTB = 0xFF;
> init();
>
> CAN0RFLG= 0xc3;
> CAN0RIER= 0x01;
> cli(); //enable the global interrupts
>
> while (!(CAN0CTL0 & 0x80))
> {
> PORTB= ~CAN0RXFG[4];
> CAN0RFLG= 0x01;
> }
> } /*** end of main ***/
>
> void init(void)
> {
> //CAN0CTL1 = 0x80; //Modul on
> CAN0CTL0 = 0x01;
>
> while (!(CAN0CTL1 & 0x01));
>
> CAN0BTR0 = 0x41; // Timequanta
> CAN0BTR1 = 0x23; // Timequanta
> CAN0CTL1 = 0x80; // Modul on
>
> CAN0IDAC |= 0x30; // Filter closed
>
> CAN0CTL0 |= 0x80;
>
> CAN0CTL0= 0x00; // Exit Initialization Mode
> while((CAN0CTL1 & 0x00) != 0);
> }
>
> void sei(void)
> {
> _asm("sei");
> }
>
> void cli(void)
> {
> _asm("cli");
> }
> ------------------------------------------------------------------------
>
> No virus found in this incoming message.
> Checked by AVG.
> Version: 7.5.524 / Virus Database: 270.1.0/1492 - Release Date: 09/06/2008 10:29 AM
>
------------------------------------
______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.
(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )
Hello,
> Hello,
>
> I am trying to work with the MSCAN-Module of the HCS12.
>
> I have CAN-Dongle for a PC and try to send a CAN Message from the PC
> to the HCS12. I receive the message with the HCS12 and show the data
> at some LED's. But at the Computer I always get the Error-Message
> BUSHEAVY.
>
> Could you have a look at my code for the HCS12 and tell me what's
> wrong. Perhaps the baud rate is wrong.
>
> I do not understand how to set the baud rate completely. Perhaps
> someone can tell me how it works and what baud rate I set in my code.
First of all what's your MSCAN module clock? Using CLKSRC bit you select
either oscilator clok or bus clock. Suppose you have 16MHz CAN module clock.
Clock period 62.5ns.
Now suppose you want 20kbps. Bit time 50us.
Then bit time is 50us/62.5ns = 800 CAN module clock periods long. If CAN
spec and CAN module allowed to use 62.5ns time quantas, then these 800 would
be time quantas in our chosen 50us long bit time. Hope it's clear. But if
you look at CANBTR1 register description, you will see that you can't have
so many time quantas in single bit time. You should prescale your module
clock to get longer time quantas.
You probably read already that one can bit time consists of 3 parts: a
synchronization segment, timesegment 1 and timesegment2. Sync segment is
always 1 timequanta long, timesegment1 can be from 1 to 16 time quantas
long, and timesegment2 can be 1 to 8 time quantas long. So the single bit
time can be from 3 to 27 time quantas long. There are more restrictions and
you shouldn't all bit time lengths from 3 to 27Tq. My advice is try to set
baudrate prescaler so that one bit time is 16 Tq. So 800 / 16 = 50 without
remainder. That's your prescaler, and you write to CANBTR0 BRP bits 50-1=49.
Again. Module clock 16MHz, prescaler 50, 16 time quantas per bit. Syncseg is
1 Tq, and you have to divide the remaining 15Tqs into Tseg1 and Tseg2. Tseg1
and Tseg2 ratio defines the moment CAN module samples bit value from the
bus. Some standards require higher Tseg1/Tseg2 ratio, some lower. It could
be for example 85%. So 16 * (100-85%) is about 2. That's your timesegment2
length. You init CANBTR1 Tseg2 bits with 2-1=1. Timesegment1 is 16-1-2 = 13.
And you init CANBTR1 Tseg1 bits with 13-1=12.
Hope it helps
Edward
>
> Sorry, for the bad english. I am still learning.
>
> void main(void)
> {
> DDRB = 0xFF; // DataDirection-PortB Output
> PORTB = 0xFF;
> init();
>
> CAN0RFLG= 0xc3;
> CAN0RIER= 0x01;
> cli(); //enable the global interrupts
>
> while (!(CAN0CTL0 & 0x80))
> {
> PORTB= ~CAN0RXFG[4];
> CAN0RFLG= 0x01;
> }
> } /*** end of main ***/
>
> void init(void)
> {
> //CAN0CTL1 = 0x80; //Modul on
> CAN0CTL0 = 0x01;
>
> while (!(CAN0CTL1 & 0x01));
>
> CAN0BTR0 = 0x41; // Timequanta
> CAN0BTR1 = 0x23; // Timequanta
> CAN0CTL1 = 0x80; // Modul on
>
> CAN0IDAC |= 0x30; // Filter closed
>
> CAN0CTL0 |= 0x80;
>
> CAN0CTL0= 0x00; // Exit Initialization Mode
> while((CAN0CTL1 & 0x00) != 0);
> }
>
> void sei(void)
> {
> _asm("sei");
> }
>
> void cli(void)
> {
> _asm("cli");
> }
> ------------------------------------

(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )