CAN BUS
CAN BUS initialization
In order to use the CAN libraries in a script, it is necessary to include the appropriate CAN libraries. To do so, the user must add the following line to the includes section:
#include <can>
The CAN initialization function requires three parameters. The first parameter specifies which CAN bus (either CAN1 or CAN2) will be initialized on the module.
Next, the CAN mode must be selected, which can be one of the following: NORMAL, SILENT, or ONE_SHOT. In SILENT mode, the interface only listens to the CAN bus and does not transmit an ACK frame, even when a message is correctly received on the CAN bus. In NORMAL mode, the CAN bus provides an ACK frame. In ONE_SHOT mode, the automatic retransmission feature is disabled.
The final parameter is the CAN bus speed, which, in this case, is set to 500 kBit/s.
CAN BUS initialization and setup
#include <io>
#include <read>
#include <float>
#include <string>
#include <core>
#include <write>
#include <define>
#include <can>
public callback (event)
{
switch(event)
{
case CAN1:
{
}
}
return 0;
}
main()
{
Init(CAN1, NORMAL, 500000); // Initialize CAN1, normal mode, speed: 500kbit/s
while(1)
{
Delay(100);
}
}CAN BUS configuration
Reset filters:
The function CANconfig manages the CAN bus filters. It allows you to either add filters or reset all existing filters.
To reset all filters, follow the example provided below:
CAN BUS reset filters
#include <io>
#include <read>
#include <float>
#include <string>
#include <core>
#include <write>
#include <define>
#include <can>
public callback (event)
{
switch(event)
{
case CAN2:
{
}
}
return 0;
}
main()
{
Init(CAN2, NORMAL, 500000); // Initialize CAN2, normal mode, speed: 500kbit/s
CANconfig(CAN2, RESET_FILTER); // CAN configuration
while(1)
{
Delay(100);
}
}ID filters:
There are several options available for adding new filters. It can be either ID filter, or a mask filter. However, it is important to note that mask and ID filters should not be initialized for the same CAN channel.
CAN network can be configured to work with two different message/frame formats: the standard (described in CAN 2.0 A and CAN 2.0 B) and the extended frame format (only described by CAN 2.0 B). The only difference between the two formats is that the "CAN standard frame" supports a length of 11 bits for the identifier, and the "CAN extended frame" supports a length of 29 bits for the identifier, made up of the 11-bit identifier ("standard identifier") and an 18-bit extension ("identifier extension"). To set which CAN message frame format is used - we can either set it to STANDARD or EXTENDED.
CAN configuration, add ID (11-bit example)
#include <io>
#include <read>
#include <float>
#include <string>
#include <core>
#include <write>
#include <define>
#include <can>
public callback (event)
{
switch(event)
{
case CAN1: // CAN1 callback event
{
//Code in this location will be executed upon successful CAN filter match
}
}
return 0;
}
main()
{
Init(CAN1, NORMAL, 500000);
CANconfig(CAN1, RESET_FILTER); // Reset all filters before setting new
CANconfig(CAN1, ADD_ID, STANDARD, 0x7C6); // Configure Can id which is going to be read
CANconfig(CAN1, ADD_ID, STANDARD, 0x7CF); // Configure Can id which is going to be read
while(1)
{
Delay(100);
}
}CAN configuration, add ID (29-bit example)
#include <io>
#include <read>
#include <float>
#include <string>
#include <core>
#include <write>
#include <define>
#include <can>
public callback (event)
{
switch(event)
{
case CAN1: // CAN1 callback event
{
//Code in this location will be executed upon successful CAN filter match
}
}
return 0;
}
main()
{
Init(CAN1, NORMAL, 500000);
CANconfig(CAN1, RESET_FILTER); // Reset all filters before setting new
CANconfig(CAN1, ADD_ID, EXTENDED, 0x18DB33F1); // Configure Can id which is going to be read
CANconfig(CAN1, ADD_ID, EXTENDED, 0x18FE45CA); // Configure Can id which is going to be read
while(1)
{
Delay(100);
}
}Mask filters:
There are two types of masks: the standard mask (ADD_MASK_STD) and the extended mask (ADD_MASK_EXT). The standard mask consists of 11 bits of information. The extended mask, on the other hand, consists of 29 bits of information. Mask filter is enabled when set in second function variable.
Third function variable represents the expected result we are aiming for after applying the mask. For example, if this variable is set to 0x00FEE900, any CAN ID that results in this value after applying the mask will trigger a callback with a new CAN message.
The final variable is the mask itself. Mask performs bitwise AND operation.
Example 1:
If we configured our mask to be 0x00FFFF00 and expected result is 0x00FEE900 (CANconfig(CAN1, ADD_MASK_EXT, 0x00FEE900, 0x00FFFF00);). And via CAN BUS we receive 0x10FEE95A CAN ID:
A = 0x10FEE95A
B = 0x00FFFF00
A&B = 0x00FEE900
In this example A&B result matches expected result therefore in this scenario we would receive CAN callback.
Example 2:
If we configured our mask to be 0x006BFA00 and expected result is 0x004A8A00 (CANconfig(CAN1, ADD_MASK_EXT, 0x004A8A00, 0x006BFA00);). And via CAN BUS we receive 0x125A8B5A CAN ID:
A = 0x125A8B5A
B = 0x006BFA00
A&B = 0x004A8A00
In this example A&B result matches expected result therefore in this scenario we would receive CAN callback.
Example 3:
If we configured our mask to be 0x12ADAB00 and expected result is 0x12BDEB00 (CANconfig(CAN1, ADD_MASK_EXT, 0x12BDEB00, 0x12ADAB00);). And via CAN BUS we receive 0x125A8B5A CAN ID:
A = 0x125A8B5A
B = 0x12ADAB00
A&B = 0x12088B00
In this example A&B result does not match expected result therefore in this scenario we would not receive CAN callback.
CAN configuration, add mask
#include <io>
#include <read>
#include <float>
#include <string>
#include <core>
#include <write>
#include <define>
#include <can>
public callback (event)
{
switch(event)
{
case CAN1: // CAN1 callback event
{
//Code in this location will be executed upon successful CAN filter match
}
}
return 0;
}
main()
{
Init(CAN1, NORMAL, 500000);
CANconfig(CAN1,RESET_FILTER); // Reset all filters before setting new
CANconfig(CAN1, ADD_MASK_EXT, 0x00FEE900, 0x00FFFF00); //Standard mask would look like so: CANconfig(CAN1, ADD_MASK_STD, 0xFEE, 0xFFF);
while(1)
{
Delay(100);
}
}Reading and writing from/into CAN-BUS
To read or write CAN-BUS message, functions ReadCANmsg and WriteCANmsgcan be called.
It is essential to use read function to read the CAN message in order to proceed with receiving the next message.
The first variable of both functions specifies which CAN-BUS will be used to read or send the message.
The second variable defines the array which is used to send or store CAN message.
After reading CAN message, array data structure will look like so:
CAN_rx_buffer[0] - CAN ID
CAN_rx_buffer[1] - ID type
CAN_rx_buffer[2] - DLC
CAN_rx_buffer[3] - Data[0]
CAN_rx_buffer[4] - Data[1]
CAN_rx_buffer[5] - Data[2]
CAN_rx_buffer[6] - Data[3]
CAN_rx_buffer[7] - Data[4]
CAN_rx_buffer[8] - Data[5]
CAN_rx_buffer[9] - Data[6]
CAN_rx_buffer[10] - Data[7]Reading and Writing information
#include <io>
#include <read>
#include <float>
#include <string>
#include <core>
#include <write>
#include <define>
#include <can>
new CAN_tx_buffer[11];
new CAN_rx_buffer[11];
public callback (event)
{
switch(event)
{
case CAN1: // CAN1 callback event
{
ReadCANmsg(CAN1, CAN_rx_buffer); // Read message from CAN and save in CAN_rx_buffer
}
}
return 0;
}
write_can_message_data_set()
{
CAN_tx_buffer[0] = 0x7CE; // CAN ID: 0x7CE
CAN_tx_buffer[1] = STANDARD; // CAN ID type: Standard
CAN_tx_buffer[2] = 8; // CAN message Number of bytes of data (0-8)
CAN_tx_buffer[3] = 0x21; // CAN Data
CAN_tx_buffer[4] = 0x32; // CAN Data
CAN_tx_buffer[5] = 0x64; // CAN Data
CAN_tx_buffer[6] = 0xAA; // CAN Data
CAN_tx_buffer[7] = 0xBB; // CAN Data
CAN_tx_buffer[8] = 0x11; // CAN Data
CAN_tx_buffer[9] = 0x22; // CAN Data
CAN_tx_buffer[10] = 0x33; // CAN Data
}
main()
{
Init(CAN1, NORMAL, 500000);
CANconfig(CAN1, RESET_FILTER); // Reset all filters before setting new
CANconfig(CAN1, ADD_MASK_EXT, 0x00FEE900, 0x00FFFF00); //Standard mask would look like so: CANconfig(CAN1, ADD_MASK_STD, 0xFEE, 0xFFF);
write_can_message_data_set();
while(1)
{
WriteCANmsg(CAN1,CAN_tx_buffer); //Writes CAN message
Delay(100);
}
}