Table of Contents

CAN messaging

Requirements: [HW] Controller

Theory

From Wikipedia, the free encyclopedia

Controller–area network (CAN or CAN-bus) is a vehicle bus standard designed to allow microcontrollers and devices to communicate with each other within a vehicle without a host computer.

CAN is a message based protocol, designed specifically for automotive applications but now also used in other areas such as industrial automation and medical equipment.

Development of the CAN-bus started originally in 1983 at Robert Bosch GmbH. The protocol was officially released in 1986 at the Society of Automotive Engineers (SAE) congress in Detroit, Michigan. The first CAN controller chips, produced by Intel and Philips, came on the market in 1987. Bosch published the CAN 2.0 specification in 1991.

CAN is one of five protocols used in the OBD-II vehicle diagnostics standard, mandatory for all cars and light trucks sold in the United States since 1996, and the EOBD standard, mandatory for all petrol vehicles sold in the European Union since 2001 and all diesel vehicles since 2004.

Practice

ARM-CAN controller board LM3S5632 MCU is programmed with the help of Texas Instruments (former Luminary Micro) StellarisWare software library. The library includes all the functions to alter microcontroller's registers. LM3S5632 incorporates CAN 2.0 controller with 32 message objects which can be used to automatically transmit and receive messages.

Most common functions to deal with CAN controller are CANMessageSet and CANMessageGet. The first one is used to configure one of the 32 message objects to send or receive a message, another one is used to read the message which was sent or received. They both use tCANMsgObject structure to specify message ID, mask, flags and payload.

The following program demonstrates how to set up CAN controller and wait for a message:

//*****************************************************************************
//
// CAN message receiving.
//
//*****************************************************************************
 
#include <inc/hw_ints.h>
#include <inc/hw_memmap.h>
#include <inc/hw_types.h>
#include <driverlib/sysctl.h>
#include <driverlib/can.h>
 
//*****************************************************************************
//
// Main function.
//
//*****************************************************************************
int main(void)
{	
	tCANMsgObject psMsg;
	unsigned char pucData[8];
 
	//
	// Set the clocking to run from the PLL at 50MHz
	//
	SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
	   SYSCTL_XTAL_8MHZ);
 
	//
	// Enable peripherals.
	//	
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);		
 
	//
	// Configure CAN pins.
	//
	GPIOPinTypeCAN(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);	
 
	//
	// Enable the CAN controller.
	//    
	CANInit(CAN0_BASE);
	CANBitRateSet(CAN0_BASE, SysCtlClockGet(), CAN_BITRATE);
	CANEnable(CAN0_BASE);	
 
	//
	// Create receive message object.
	//	
	psMsg.ulMsgID     = 0x01;
	psMsg.ulMsgIDMask = 0xFF;
	psMsg.ulFlags     = MSG_OBJ_NO_FLAGS;	
	psMsg.pucMsgData  = pucData;
 
	//
	// Set message object on box 1.
	//
	CANMessageSet(CAN0_BASE, 1, &psEchoMsg, MSG_OBJ_TYPE_RX);
 
	//
	// Loop forever.
	//
	while (1)
	{	
		//
		// CAN message received ?
		//
		if (CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT) & 1)
		{
			//
			// Get the message.
			//
			CANMessageGet(CAN0_BASE, CAN_MSG_OBJ_RX, &psMsg, true);
 
			//
			// Access pucData here.
			// To get the length of the data read psMsg.ulMsgLen
			//
		}
	}
}