CAN and PLL - MC9S12XDT512

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

CAN and PLL - MC9S12XDT512

2,093 次查看
ernestsnaith
Contributor I
I have set up a program on a PC to send a CAN message to the microcontroller, an interrupt is raised on recieve and various messages are sent back on CAN bus to the PC.
 
Until today everything has been working fine. However after bumping up the bus freq using the PLL, the recieve interupt is not raised. However the micro will still transmit messages to the PC succefully if this the recieve part is bypassed.Why is the recieve interupt not getting raised?
 
I have not selected the bus clock as CANCLK source and am still able to communicate in one direction. (micro to PC) but not the other way. I have tried various combinations of Time sequences and sync jump widths and still had no luck.
 
Has anyone any suggestions? Cheers
 
CW4.6 MC9S12XDT512
 
Relevant Code:
//***************************************************************************************interrupt 38 void CANRECEIVE(){  temp++;      if (CAN0RFLG_RXF)         //check if register is full. did get thru filter  {    if (CAN0RXIDR0 == 0x06 && CAN0RXIDR1 == 0x40) // Correct ID?    {      data1 = CAN0RXDSR0;   //take data from packet      CAN0RFLG_RXF = 1;     //Release buffer (a one sets a flag to zero)      MapSend();    }  }    }  //***************************************************************************************void CAN_INIT(void) {  CAN0CTL0 = 0x01;    //initialisation mode  while (! (CAN0CTL1&0x01)) {}; //waits for initialisation mode  CAN0CTL1 = 0x80;      // enable CAN  CAN0BTR1 = 0x3A;   //3A  CAN0BTR0 = 0x01;   //03     //Setting up filter   CAN0IDAC = 0x10;    // Set four 16-bit Filters  CAN0IDAR0 = 0xC0;   CAN0IDMR0 = 0xFF;    //ignore 3rd MSB   CAN0IDAR1 = 0x00;  CAN0IDMR1 = 0xFF;    //only check first 3 )  CAN0CTL0 = 0x00;    // Exit Initialization Mode    while ((CAN0CTL1&0x00) != 0) {}  // Wait for Normal Mode     CAN0RIER = 0xBD;  //enable all interrupt requests  CAN0TARQ = 0; //disable abort request register  CAN0TIER = 0;  //transmit buffer empty interrupts disabled  CAN0TXDLR = 8;}//***************************************************************************************void CanSend(void)   {    CAN0TBSEL = CAN0TFLG;  // Select lowest empty buffer     CAN0RFLG = 0x40;   // wake up    //writing to packet    CAN0TXIDR0 = TXID0;        .............          CAN0TXDSR7 = TXData[7];          CAN0TXDLR = TXLength;    while (!CAN0CTL0_SYNCH){}  //wait until node is synchronised with bus    CAN0TFLG = CAN0TBSEL;       //Start transmission (writing 1 clears the flag)    while (CAN0TFLG != 0x07){} //wait until message is sent  }//***************************************************************************************void main(void) {     int j;  EnableInterrupts;    // PLL SETUP  SYNR=19;                  // clock multiply (+1)  REFDV=1;                  // clock divide   (+1)  while (!(CRGFLG_LOCK));   // sync  CLKSEL_PLLSEL=1;     CAN_INIT(); // CAN initialisation  MapSend();      for (;;)   {  }}

 
标签 (1)
0 项奖励
回复
2 回复数

669 次查看
Lundin
Senior Contributor IV
If you have set the CAN prescaler to be derived from the oscillator, it is quite possible that it skips the PLL. I'm not sure about that, but I would try to use the bus clock instead.

Using a faster baudrate could also bring out possible hardware problems in the light. The two most common ones when using CAN is no signal ground between the nodes, or no terminating resistors on the bus.


Edit: Another thing. You should enable CAN before entering sleep or init modes. It is not possible to enter sleep mode before CAN is enabled, so your code will never do that, which will force the tx pin on the CAN bus into recessive mode. This might give you problems in some cases.

Message Edited by Lundin on 2008-03-04 08:51 AM
0 项奖励
回复

669 次查看
ernestsnaith
Contributor I
I have just discovered that If the CAN_init function is run before setting up the PLL it all works.
 
Cheers
0 项奖励
回复