This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PM: help needed in CAN module programming

Part Number: TM4C123GH6PM

Hi everybody,

i am trying to use CAN module to send data between 2 tm4c123 launchpad ..

here is the code of reciever: 

int main(){
	  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
	  tCANMsgObject sMsgObjectRx ;
	  CAN0Rx_Init() ;

	  sMsgObjectRx.ui32MsgID = 0x400 ;
	  sMsgObjectRx.ui32Flags = MSG_OBJ_NO_FLAGS ;

	  CANMessageSet(CAN0_BASE, 1, &sMsgObjectRx, MSG_OBJ_TYPE_RX) ;
	  CANEnable(CAN0_BASE) ;

	  while(1){
	      while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & 1) == 0)
	      {
	      //
	      // Read the message out of the message object.
	      //
	      CANMessageGet(CAN0_BASE, 1, &sMsgObjectRx, true);
	      }
	      uint8_t data = sMsgObjectRx.pui8MsgData[0];
	      if (data == 0x33)
	          GPIO_PORTF_DATA_R ^= 0x04 ;
	  }

}

void CAN0Rx_Init(void) {

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB) ;
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB)){} ;
    GPIOPinConfigure(GPIO_PB4_CAN0RX) ;
    GPIOPinConfigure(GPIO_PB5_CAN0TX) ;
    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4|GPIO_PIN_5) ;


    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0) ;
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CAN0)){} ;
    CANInit(CAN0_BASE) ;
    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000) ;
    CANEnable(CAN0_BASE) ;



}

and here is the transmitter code:

int main(void){
	  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
	  CAN0_Init() ;
	  PORTF_Init() ;

	  uint8_t ui8data = 0x33 ;
	  uint8_t * pui8data ;
	  tCANMsgObject sMsgObjectTx ;

	  sMsgObjectTx.ui32MsgID = 0x400 ;
	  sMsgObjectTx.ui32Flags = 0 ;
	  sMsgObjectTx.ui32MsgLen = 1 ;
	  pui8data = &ui8data ;
	  sMsgObjectTx.pui8MsgData = pui8data ;

	  CANEnable(CAN0_BASE) ;

	  while(1){
	      CANMessageSet(CAN0_BASE, 1, &sMsgObjectTx, MSG_OBJ_TYPE_TX) ;
	      GPIO_PORTF_DATA_R ^= 0x02 ;
	      SysTick80_Delay_10ms(300) ;

	  }
return 0;
}


void CAN0_Init(void) {

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB) ;
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB)){}
    GPIOPinConfigure(GPIO_PB4_CAN0RX) ;
    GPIOPinConfigure(GPIO_PB5_CAN0TX) ;
    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4|GPIO_PIN_5) ;

    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0) ;
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CAN0)){}
    CANInit(CAN0_BASE) ;
    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000) ;
}

i used the on board led to toggle indicating a transmission command executed. however, the receiver does NOT  response.

any one can help? 

thanks,

Sarea

  • Hi Sarea,
    How did you connect the two MCU? Did you use the transceivers and have proper termination the CAN bus?
  • Charles

    the 2 boards connected to mcp2551 and mcp2515 ... and i use a 120 ohm terminated simple wire.

    regards,

    Sarea

  • sarea hariri said:
    the 2 boards connected to mcp2551 and mcp2515

    The MCP2551 is NRND, so you probably should be using a different chip for the transceiver.

    The MCP2515 is a CAN controller/Protocol chip, you already have that on the TM4C and the TIVAWare code you are using won't drive it.

    sarea hariri said:
    and i use a 120 ohm terminated simple wire.

    This may not be a problem but at 500kbd, I'd want to use a cable with proper impedance, not just a simple pair of wires.

    Robert

  • Hi Sarea,

    First of all you have while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & 1) == 0). Why are you comparing to 0, not 1? If the receiver receives a data the NEWDATA will be set.

    Please use the scope to see if the transmitter is transmitting the data?
  • 	  while(1){
    	      while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & 1) == 0)
    	      {
    	      //
    	      // Read the message out of the message object.
    	      //
    	      CANMessageGet(CAN0_BASE, 1, &sMsgObjectRx, true);
    	      }
    	      uint8_t data = sMsgObjectRx.pui8MsgData[0];
    	      if (data == 0x33)
    	          GPIO_PORTF_DATA_R ^= 0x04 ;
    	  }
    

    Walk through this fragment by hand with CANStatusGet always set to 1 and data always being assigned 0x33. How fast does the output toggle? Do you think you could see that?

    	      while((CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & 1) == 0)
    

    I believe this check does the exact reverse of what you intended.

    	      if (data == 0x33)
    	          GPIO_PORTF_DATA_R ^= 0x04 ;
    

    Finally, this is an accident waiting to happen. Never use single lines in a conditional, always use blocks. Fairly simple to make and hard to spot types produce valid code that will not do what you want if you use this construct.

    Robert

  • Hi Robert,
    Thanks. I think our replies cross each other on the same comment.