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.

Tiva-C CAN communication not working

Hello ,

I'm trying to send something on CAN and it doesn't work. I have put the scope to monitoring the TX pin PB5 and the signal is fix to 3.3V, no serial signal transmitted.

My code is bellow:

//*****************************************************************************
//
// simple_tx.c - Example demonstrating simple CAN message transmission.
//
// Copyright (c) 2010-2017 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//*****************************************************************************

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/can.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"

//*****************************************************************************
//
// A counter that keeps track of the number of times the TX interrupt has
// occurred, which should match the number of TX messages that were sent.
//
//*****************************************************************************
volatile uint32_t g_ui32MsgCount = 0;

//*****************************************************************************
//
// A flag to indicate that some transmission error occurred.
//
//*****************************************************************************
volatile bool g_bErrFlag = 0;


//*****************************************************************************
//
// This function provides a 1 second delay using a simple polling method.
//
//*****************************************************************************
void
SimpleDelay(void)
{
SysCtlDelay(16000000 / 3);
}

//*****************************************************************************
//
// This function is the interrupt handler for the CAN peripheral. It checks
// for the cause of the interrupt, and maintains a count of all messages that
// have been transmitted.
//
//*****************************************************************************
void
CANIntHandler(void)
{
uint32_t ui32Status;

ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

if(ui32Status == CAN_INT_INTID_STATUS)
{
ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);

g_bErrFlag = 1;
}
else if(ui32Status == 1)
{
CANIntClear(CAN0_BASE, 1);

g_ui32MsgCount++;

g_bErrFlag = 0;
}
else
{

}
}

//*****************************************************************************
//
// Configure the CAN and enter a loop to transmit periodic CAN messages.
//
//*****************************************************************************
int
main(void)
{
tCANMsgObject sCANMessage;
uint32_t ui32MsgData;
uint32_t tx_cnt;
uint32_t rx_cnt;
uint8_t *pui8MsgData;

pui8MsgData = (uint8_t *)&ui32MsgData;

SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

SysCtlPeripheralEnable(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);

CANInit(CAN0_BASE);

CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);

CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

IntEnable(INT_CAN0);

CANEnable(CAN0_BASE);

ui32MsgData = 0;

sCANMessage.ui32MsgID = 0x101;
sCANMessage.ui32MsgIDMask = 0;
sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
sCANMessage.ui32MsgLen = sizeof(pui8MsgData);
sCANMessage.pui8MsgData = pui8MsgData;

while(1)
{
CANErrCntrGet(CAN0_BASE, &tx_cnt, &rx_cnt) ;

CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);

SimpleDelay();

ui32MsgData++;
}
}

 

  • Did you connect your device to the CAN network via the CAN transceiver and the network has at least two nodes in it?
  • Hello Charles Tsai,

    Yes i have connected the CAN rx and tx to a CAN transceiver and still nothing.
    How can i know that the problem is the transceiver and not my application ?

    When i debug the application the program goes to interrupt after first send an the status reg has the value = 229 (  0b11100101 ) and from the datasheet i understood that this bits means ( buss off , error counter > 96 , error pasiv state , 0 , 0, last 3 bits = bit 0 error )

  • Hi,
    The CAN protocol specifies the transmit and receive error counters. The error counters start at zero and are incremented (upon error) and decremented (upon a successful tx/rx). When bus-off bit is set it means that controller switches off from the bus.

    I will suggest you take the simple_tx and simple_rx examples for the CAN module and run them on two separate nodes in your CAN network. These two examples are proven to work. Many customers start with these two examples in their CAN network. If these two examples fail then it is likely there is something wrong on the transceiver hookup. You might want to check if you have proper termination resistor on the CAN bus. If these two examples work then you can compare the examples to your own code and see where the difference is.
  • Hello,

    I have changed the CAN transceiver. Im using an MCP2551 CAN transceiver now and is working well with my code.

    Thanks Charles for your support.

    Best regards,

    Radu