CAN Library
mikroBasic PRO for ARM provides a library (driver) for working with the ARM CAN module.
The CAN is a very robust protocol that has error detection and signalization, self–checking and fault confinement. Faulty CAN data and remote frames are re-transmitted automatically, similar to the Ethernet.
Data transfer rates depend on distance. For example, 1 Mbit/s can be achieved at network lengths below 40m while 250 Kbit/s can be achieved at network lengths below 250m. The greater distance the lower maximum bitrate that can be achieved. The lowest bitrate defined by the standard is 200Kbit/s. Cables used are shielded twisted pairs.
CAN supports two message formats:
- Standard format, with 11 identifier bits and
- Extended format, with 29 identifier bits
Important :
- Consult the CAN standard about CAN bus termination resistance.
- CAN library routines require you to specify the module you want to use. To use the desired CAN module, simply change the letter x in the routine prototype for a number from 0 to 3.
- Number of CAN modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Library Routines
- CANxSetOperationMode
- CANxGetOperationMode
- CANxInitialize
- CANxInitializeAdvanced
- CANxSetBaudRate
- CANxSetMask
- CANSetMask
- CANxSetFilter
- CANSetFilterScale16
- CANSetFilterScale32
- CANxReadMessage
- CANxRead
- CANxWriteMessage
- CANxWrite
- CANxConfigureMessage
- CANxBitRateSet
- CANSlaveStartBank
CANxSetOperationMode
| Prototype |
// for Stellaris MCUs :
sub procedure CANxSetOperationMode(dim mode, wait_flag as longword) // for ST MCUs :sub function CANxSetOperationMode(dim CAN_OperatingMode as byte) as byte |
|---|---|
| Description |
Sets the CAN module to requested mode. |
| Parameters |
|
| Returns |
|
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. |
| Example |
' set the CAN1 module into configuration mode (wait inside CAN1SetOperationMode until this mode is set) CAN1SetOperationMode(_CAN_MODE_CONFIG, 0xFF) |
| Notes |
|
CANxGetOperationMode
| Prototype |
sub function CANxGetOperationMode() as longword |
|---|---|
| Description |
The function returns current operation mode of the CAN module. See CAN_OP_MODE constants or device datasheet for operation mode codes. Valid only for Stellaris devices. |
| Parameters |
None. |
| Returns |
Current operation mode. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. |
| Example |
' check whether the CAN1 module is in Normal mode and if it is then do something. if (CAN1GetOperationMode() = _CAN_MODE_NORMAL) then ... end if |
| Notes |
|
CANxInitialize
| Prototype |
// for Stellaris MCUs with dedicated PORT functions and ST MCUs:
sub procedure CANxInitialize(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG as word, flags as longword) // for Stellaris MCUs with alternative PORT functions on GPIO pins :sub procedure CANxInitialize(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG as word, dim flags as longword, dim module as ^const Module_Struct) |
||||||||
|---|---|---|---|---|---|---|---|---|---|
| Description |
Initializes the CAN module. The internal CAN module is set to :
|
||||||||
| Parameters |
|
||||||||
| Returns |
Nothing. |
||||||||
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. |
||||||||
| Example |
' initialize the CAN1 module with appropriate baud rate and message acceptance flags along with the sampling rules
dim Can_Init_Flags as word
...
Can_Init_Flags = _CAN_MODE_NORMAL and ' Form value to be used
_CAN_MODE_LOOP and ' with CAN1Initialize
_CAN_MODE_SILENT
CAN1Initialize(1,3,3,3,1,Can_Init_Flags) ' initialize the CAN1 module
|
||||||||
| Notes |
|
||||||||
CANxInitializeAdvanced
| Prototype |
sub procedure CANxInitializeAdvanced(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG as word, dim flags as longword, dim module as ^ const module_Struct) |
|||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Description |
Initializes the CAN with desired CAN module pinout for ST devices. The internal CAN module is set to :
|
|||||||||
| Parameters |
|
|||||||||
| Returns |
Nothing. |
|||||||||
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. |
|||||||||
| Example |
' initialize the CAN1 module with appropriate baud rate and message acceptance flags along with the sampling rules
dim Can_Init_Flags as word
...
Can_Init_Flags = _CAN_MODE_NORMAL and ' Form value to be used
_CAN_MODE_LOOP and ' with CAN1Initialize
CAN1InitializeAdvanced(1,3,3,3,1,Can_Init_Flags, @_GPIO_MODULE_CAN1_PA11_12) ' initialize the CAN1 module
|
|||||||||
| Notes |
|
|||||||||
CANxSetBaudRate
| Prototype |
sub procedure CANxSetBaudRate(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG as word) |
|---|---|
| Description |
Sets CAN baud rate. Due to complexity of the CAN protocol, you can not simply force a bps value. Instead, use this function when CAN is in Config mode. Refer to datasheet for details. Valid only for Stellaris devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. CAN must be in Config mode, otherwise the function will be ignored. See CANxSetOperationMode. |
| Example |
CAN1SetBaudRate(1,3,3,3,1) ' set the CAN1 module baud rate |
| Notes |
|
CANxSetMask
| Prototype |
sub procedure CANxSetMask(dim objID as longword, dim maskValue as longword, dim flags as longword) |
|---|---|
| Description |
The function configures appropriate mask for advanced message filtering. Valid only for Stellaris devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. CAN must be in Config mode, otherwise the function will be ignored. See CANxSetOperationMode. |
| Example |
'/ set appropriate filter mask and message type value CAN1SetOperationMode(_CAN_MODE_CONFIG,0xFF) ' set CONFIGURATION mode (CAN1 module must be in config mode for mask settings) CAN1SetMask(1, -1, _CAN_CONFIG_USE_DIR_FILTER) ' set all mask1 bits to ones |
| Notes |
|
CANSetMask
| Prototype |
sub procedure CANSetMask(dim Filter_Number as byte, dim maskValue as longword, dim CAN_FILTAR_FLAGS as byte) |
|---|---|
| Description |
The function configures appropriate mask for advanced message filtering. Valid only for ST devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. CAN must be in Config mode, otherwise the function will be ignored. See CANxSetOperationMode. |
| Example |
' set appropriate filter mask and message type value CAN1SetOperationMode(_CAN_MODE_CONFIG,0xFF) ' set CONFIGURATION mode (CAN1 module must be in config mode for mask settings) CANSetMask(1, -1, _CAN_FILTER_ENABLED) ' set all mask1 bits to ones |
| Notes |
|
CANxSetFilter
| Prototype |
sub procedure CANxSetFilter(dim objID as longword, dim filterValue as longword, dim flags as longword) |
|---|---|
| Description |
Function sets message filter. Given Valid only for Stellaris devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. CAN must be in Config mode, otherwise the function will be ignored. See CANxSetOperationMode. |
| Example |
' set appropriate filter value and message type CAN1SetOperationMode(_CAN_MODE_CONFIG,0xFF) ' set CONFIGURATION mode (CAN1 module must be in config mode for filter settings) CAN1SetFilter(1, -1, _CAN_MASK_3, _CAN_BUFFER_0, _CAN_CONFIG_XTD_MSG) ' set id of filter_B1_F1 to 1st node ID |
| Notes |
|
CANSetFilter
| Prototype |
sub procedure CANSetFilter(dim Filter_Number as byte, dim ID as longword, dim CAN_FILTAR_FLAGS as longword) |
|---|---|
| Description |
Function sets message filter. Given Valid only for ST devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. CAN must be in Config mode, otherwise the function will be ignored. See CANxSetOperationMode. |
| Example |
|
| Notes |
|
CANSetFilterScale16
| Prototype |
sub procedure CANSetFilterScale16(dim Filter_Number as byte, dim CAN_FILTAR_FLAGS as byte, dim ID as longword, dim mask_or_ID as longword, dim ID1 as longword, dim mask1_or_ID1 as longword) |
|---|---|
| Description |
To optimize and adapt the filters to the application needs, each filter can be scaled independently. This routine applies two 16-bit filters to the STDID[10:0], RTR and IDE bits. Valid only for ST devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. CAN must be in Config mode, otherwise the function will be ignored. See CANxSetOperationMode. |
| Example |
|
| Notes |
|
CANSetFilterScale32
| Prototype |
sub procedure CANSetFilterScale16(dim Filter_Number as byte, dim CAN_FILTAR_FLAGS as byte, dim ID as longword, dim mask_or_ID as longword) |
|---|---|
| Description |
To optimize and adapt the filters to the application needs, each filter can be scaled independently. This routine applies one 32-bit filter to the STDID[10:0], IDE, EXTID[17:0] and RTR bits. Valid only for ST devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. CAN must be in Config mode, otherwise the function will be ignored. See CANxSetOperationMode. |
| Example |
|
| Notes |
|
CANxReadMessage
| Prototype |
sub function CANxReadMessage(dim objID as longword, dim byref msgId as longword, dim byref pMsgData as byte[8], dim byref msgLen, flags as longword) as longword |
|---|---|
| Description |
The function reads message from the desired message object and processes it in the following way :
Valid only for Stellaris devices. |
| Parameters |
|
| Returns |
|
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. The CAN module must be in a mode in which receiving is possible. See CANxSetOperationMode. |
| Example |
if (msg_rcvd = CAN1ReadMessage(objID, @msgId, pMsgData, @msgLen, @flags)) then begin ... end; |
| Notes |
|
CANxRead
| Prototype |
// for Stellaris devices
sub function CANxRead(dim byref msgId as longword, dim byref pMsgData as byte[8], dim byref msgLen, flags as longword) as longword // for ST devicessub function CANxRead(dim FIFONumber as byte, dim byref id as longword, dim byref data_ as byte[8], dim byref datalen as char, dim byref CAN_RX_MSG_FLAGS as byte) as byte
|
|---|---|
| Description |
The function reads and processes the message from the first message object configured for reception that has received data in the following way :
|
| Parameters |
|
| Returns |
|
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. The CAN module must be in a mode in which receiving is possible. See CANxSetOperationMode. |
| Example |
' check the CAN1 module for received messages. If any was received do something.
dim msg_rcvd, rx_flags, data_len as word
data as byte[8]
msg_id as longint
...
CAN1SetOperationMode(_CAN_MODE_NORMAL,0xFF) ' set NORMAL mode (CAN1 module must be in mode in which receive is possible)
...
rx_flags = 0 ' clear message flags
if (msg_rcvd = CAN1Read(msg_id, data, data_len, rx_flags)<>0) then
...
end if
|
| Notes |
|
CANxWriteMessage
| Prototype |
sub function CANxWriteMessage(dim objID, msgId as longword, dim byref pMsgData as byte[8], dim byref msgLen, flags as longword) as longword |
|---|---|
| Description |
The function writes the message to the desired message object. Valid only for Stellaris devices. |
| Parameters |
|
| Returns |
|
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. The CAN module must be in mode in which transmission is possible. See CANxSetOperationMode. |
| Example |
' send message extended CAN message with appropriate ID and data
dim tx_flags as word
data as byte[8]
msg_id as longint
...
CAN1SetOperationMode(_CAN_MODE_NORMAL,0xFF) ' set NORMAL mode (CAN1 must be in mode in which transmission is possible)
tx_flags = _CAN_TX_PRIORITY_0 and
_CAN_TX_XTD_FRAME and
_CAN_TX_NO_RTR_FRAME ' set message flags
CAN1WriteBuffer(msg_id, data, _CAN_BUFFER_0, 1, tx_flags)
|
| Notes |
|
CANxWrite
| Prototype |
sub function CANxWrite(msgId as longword, dim byref pMsgData as byte[8], dim byref msgLen, flags as longword) as longword |
|---|---|
| Description |
The function writes message in the first available message object configured for transmission. |
| Parameters |
|
| Returns |
|
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. The CAN module must be in mode in which transmission is possible. See CANxSetOperationMode. |
| Example |
' send message extended CAN message with appropriate ID and data
dim tx_flags as word
data as byte[8]
msg_id as longint
...
CAN1SetOperationMode(_CAN_MODE_NORMAL,0xFF) ' set NORMAL mode (CAN1 must be in mode in which transmission is possible)
tx_flags = _CAN_TX_PRIORITY_0 and
_CAN_TX_XTD_FRAME and
_CAN_TX_NO_RTR_FRAME ' set message flags
CAN1Write(msg_id, data, 1, tx_flags)
|
| Notes |
|
CANxConfigureMessage
| Prototype |
sub procedure CANxConfigureMessage(dim objID, flags as longword) |
|---|---|
| Description |
The function configures message object. Valid only for Stellaris devices. |
| Parameters |
|
| Returns |
Nothing. |
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. |
| Example |
|
| Notes |
|
CANxBitRateSet
| Prototype |
sub function CANxBitRateSet(dim ulSourceClock, bitRate as longword) as longword |
|---|---|
| Description |
This function is used to set the CAN bit timing values to a nominal setting based on a desired bit rate. Valid only for Stellaris devices. |
| Parameters |
|
| Returns |
|
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. |
| Example |
|
| Notes |
|
CANSlaveStartBank
| Prototype |
sub procedure CANSlaveStartBank(dim CAN_BankNumber as byte) |
|---|---|
| Description |
This routine is used to set the starting bank filter for the CAN slave module. Valid only for ST devices. |
| Parameters |
|
| Returns |
|
| Requires |
MCU with the CAN module. MCU must be connected to the CAN transceiver (MCP2551 or similar) which is connected to the CAN bus. |
| Example |
|
| Notes |
|
CAN Constants
There is a number of constants predefined in CAN library. To be able to use the library effectively, you need to be familiar with these. You might want to check the example at the end of the chapter.
CAN_OP_MODE Constants
CAN_OP_MODE constants define CAN operation mode. Function CANxSetOperationMode expects one of these as its argument:
// Stellaris Constants _CAN_MODE_NORMAL _CAN_MODE_DISABLE _CAN_MODE_LOOP _CAN_MODE_SILENT _CAN_MODE_CONFIG _CAN_MODE_BASIC _CAN_MODE_LOOP_WITH_SILENT // ST Constants _CAN_OperatingMode_Initialization _CAN_OperatingMode_Normal _CAN_OperatingMode_Sleep
CAN_CONFIG_FLAGS Constants
CAN_CONFIG_FLAGS constants define flags related to CAN module configuration. Functions CANxInitialize and CANxSetBaudRate expect one of these (or a bitwise combination) as their argument:
_CAN_CONFIG_AUTO_RETRY_ENABLED _CAN_CONFIG_AUTO_RETRY_DISABLED
CAN_TX_MSG_FLAGS Constants
CAN_TX_MSG_FLAGS are flags related to transmission of a CAN message:
_CAN_TX_STD_FRAME _CAN_TX_XTD_FRAME _CAN_TX_NO_RTR_FRAME _CAN_TX_RTR_FRAME
You may use bitwise and to adjust the appropriate flags. For example:
' form value to be used with CANSendMessage:
send_config = _CAN_TX_XTD_FRAME and
_CAN_TX_NO_RTR_FRAME
...
CAN1Write(id, data, 1, send_config)
CAN_RX_MSG_FLAGS Constants
CAN_RX_MSG_FLAGS are flags related to reception of CAN message. If a particular bit is set; corresponding meaning is TRUE or else it will be FALSE.
// Stellaris Constants _CAN_RX_REMOTE_FRAME // Set if this is a remote frame _CAN_RX_DATA_LOST // Set if some data is lost _CAN_RX_NEW_DATA // Indicate that there is new data in this message _CAN_RX_EXTENDED_ID // Set if extended message _CAN_RX_USE_ID_FILTER // Set the flag to indicate if ID masking was used _CAN_RX_USE_EXT_FILTER // Set if extended bit was used in filtering _CAN_RX_USE_DIR_FILTER // Set if direction filtering was enabled // ST Constants _CAN_RX_XTD_FRAME _CAN_RX_RTR_FRAME
You may use bitwise and to adjust the appropriate flags. For example:
if (MsgFlag and _CAN_RX_DATA_LOST) <> 0 then ... ' We have lost our previous message. end if
CAN_MESSAGE_OBJECT Constants
CAN_MESSAGE_OBJECT constants define CAN message object configuration. Function CANxConfigureMessage expects one of these as its argument:
_CAN_CONFIG_TYPE_TX _CAN_CONFIG_TYPE_TX_REMOTE _CAN_CONFIG_TYPE_RX _CAN_CONFIG_TYPE_RX_REMOTE _CAN_CONFIG_TYPE_RXTX_REMOTE _CAN_CONFIG_FIFO _CAN_CONFIG_TX_INT_ENABLE _CAN_CONFIG_RX_INT_ENABLE _CAN_CONFIG_XTD_MSG _CAN_CONFIG_STD_MSG
CAN_MASK Constants
CAN_MASK constants define mask codes. Function CANxSetMask expects one of these as its argument:
// Stellaris Constants _CAN_CONFIG_XTD_MSG _CAN_CONFIG_STD_MSG _CAN_CONFIG_USE_DIR_FILTER // ST Constants _CAN_FILTER_ID_MASK_MODE _CAN_FILTER_ID_LIST_MODE _CAN_FILTER_USE_FIFO0 _CAN_FILTER_USE_FIFO1 _CAN_FILTER_STD_MSG _CAN_FILTER_XTD_MSG _CAN_FILTER_DISABLED _CAN_FILTER_ENABLED
CAN_FILTER Constants
CAN_FILTER constants define filter codes. Function CANxSetFilter expects one of these as its argument:
_CAN_CONFIG_XTD_MSG _CAN_CONFIG_STD_MSG // ST Constants _CAN_FILTER_ID_MASK_MODE _CAN_FILTER_ID_LIST_MODE _CAN_FILTER_USE_FIFO1 _CAN_FILTER_DISABLED _CAN_FILTER_ENABLED
Library Example
The example demonstrates CAN protocol. The 1st node initiates the communication with the 2nd node by sending some data to its address. The 2nd node responds by sending back the data incremented by 1. The 1st node then does the same and sends incremented data back to the 2nd node, etc.
Code for the first CAN node:
Stellaris
program CAN_1st
dim Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags, Rx_Data_Len as longword
RxTx_Data as byte[8]
Rx_ID as longint
Msg_Rcvd as longword
const ID_1st as longint = 12111
const ID_2nd as longint = 3 ' node IDs
main:
GPIO_Digital_Output(@GPIO_PORTJ, _GPIO_PINMASK_ALL)
GPIO_PORTJ_DATA = 0
Can_Init_Flags = _CAN_CONFIG_AUTO_RETRY_ENABLED ' CAN init flags
Can_Send_Flags = _CAN_TX_XTD_FRAME and _CAN_TX_NO_RTR_FRAME' form value to be used with CAN0Write
Can_Rcv_Flags = 0
CAN0Initialize(1,3,3,3,1,Can_Init_Flags) ' initialize CAN
CAN0SetOperationMode(_CAN_MODE_CONFIG,0xFF) ' set CONFIGURATION mode
CAN0ConfigureMessage(1, _CAN_CONFIG_XTD_MSG and _CAN_CONFIG_TYPE_TX) ' configure message object for transmitting
CAN0ConfigureMessage(2, _CAN_CONFIG_XTD_MSG and _CAN_CONFIG_TYPE_RX) ' congigure message object for receiving
CAN0SetMask(2, 0xFFFFFFFF, _CAN_CONFIG_XTD_MSG) ' set all mask bits to ones
CAN0SetFilter(2, ID_2nd, _CAN_CONFIG_XTD_MSG) ' set filter
CAN0SetOperationMode(_CAN_MODE_NORMAL,0xFF) ' set NORMAL mode
RxTx_Data[0] = 9
CAN0WriteMessage(1, ID_1st, RxTx_Data, 1, Can_Send_Flags)
while TRUE
Msg_Rcvd = CAN0ReadMessage(2, Rx_ID , RxTx_Data , Rx_Data_Len, Can_Rcv_Flags) ' receive message
if ((Rx_ID = ID_2nd) and (Msg_Rcvd <> 0)) <> 0 then ' if message received check id
GPIO_PORTJ_DATA = RxTx_Data[0] ' id correct, output data at PORTJ
RxTx_Data[0] = RxTx_Data[0] + 1 ' increment received data
Delay_ms(10)
CAN0WriteMessage(1, ID_1st, RxTx_Data, 1, Can_Send_Flags) ' send incremented data back
end if
wend
end.
STM32
program CAN_1st
dim Can_Init_Flags as longword
Can_Send_Flags, Can_Rcv_Flags, Rx_Data_Len as byte
RxTx_Data as byte[8]
Rx_ID as longword
Msg_Rcvd as longword
const ID_1st as longint = 12111
const ID_2nd as longint = 3 ' node IDs
main:
GPIO_Digital_Output(@GPIOE_BASE, 0xFF00)
GPIOE_ODR = 0
Can_Init_Flags = 0 '
Can_Send_Flags = 0 ' clear flags
Can_Rcv_Flags = 0 '
Can_Send_Flags = _CAN_TX_XTD_FRAME and ' with CANWrite
_CAN_TX_NO_RTR_FRAME
Can_Init_Flags = _CAN_CONFIG_AUTOMATIC_RETRANSMISSION and ' form value to be used
_CAN_CONFIG_RX_FIFO_NOT_LOCKED_ON_OVERRUN and ' with CANInit
_CAN_CONFIG_TIME_TRIGGERED_MODE_DISABLED and
_CAN_CONFIG_TX_FIFO_PRIORITY_BY_IDINTIFIER and
_CAN_CONFIG_WAKE_UP
CAN1InitializeAdvanced(1,5,4,4,1,Can_Init_Flags, @_GPIO_MODULE_CAN1_PD01) ' Initialize CAN module
CAN1SetOperationMode(_CAN_OperatingMode_Initialization) ' set CONFIGURATION mode
CANSetFilter(0, ID_2nd,_CAN_FILTER_ENABLED and _CAN_FILTER_ID_MASK_MODE and _CAN_FILTER_XTD_MSG)
CANSetMask(0, 0xFFFFFFFF,_CAN_FILTER_ENABLED and _CAN_FILTER_ID_MASK_MODE and _CAN_FILTER_XTD_MSG)
CAN1SetOperationMode(_CAN_OperatingMode_Normal) ' set NORMAL mode
RxTx_Data[0] = 9 ' set initial data to be sent
CAN1Write(ID_1st, RxTx_Data, 1, Can_Send_Flags) ' send initial message
while TRUE
Msg_Rcvd = CAN1Read(0, Rx_ID , RxTx_Data , Rx_Data_Len, Can_Rcv_Flags) ' receive message
if ((Rx_ID = ID_2nd) and (Msg_Rcvd <> 0)) then
GPIOE_ODR = word(RxTx_Data[0]) << 8 ' id correct, output data at PORTE
inc(RxTx_Data[0]) ' increment received data
Delay_ms(10)
CAN1Write(ID_1st, RxTx_Data, 1, Can_Send_Flags) ' send incremented data back
end if
wend
end.
Code for the second CAN node:
Stellaris
program CAN_2nd
dim Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags, Rx_Data_Len as longword
RxTx_Data as byte[8]
Rx_ID as longint
Msg_Rcvd as longword
const ID_1st as longint = 12111
const ID_2nd as longint = 3 ' node IDs
main:
GPIO_Digital_Output(@GPIO_PORTJ, _GPIO_PINMASK_ALL)
GPIO_PORTJ_DATA = 0
Can_Init_Flags = _CAN_CONFIG_AUTO_RETRY_ENABLED ' CAN init flags
Can_Send_Flags = _CAN_TX_XTD_FRAME and _CAN_TX_NO_RTR_FRAME' form value to be used with CAN0Write
Can_Rcv_Flags = 0
CAN0Initialize(1,3,3,3,1,Can_Init_Flags) ' initialize CAN
CAN0SetOperationMode(_CAN_MODE_CONFIG,0xFF) ' set CONFIGURATION mode
CAN0ConfigureMessage(1, _CAN_CONFIG_XTD_MSG and _CAN_CONFIG_TYPE_TX) ' configure message object for transmitting
CAN0ConfigureMessage(2, _CAN_CONFIG_XTD_MSG and _CAN_CONFIG_TYPE_RX) ' congigure message object for receiving
CAN0SetMask(2, 0xFFFFFFFF, _CAN_CONFIG_XTD_MSG) ' set all mask bits to ones
CAN0SetFilter(2, ID_1st, _CAN_CONFIG_XTD_MSG) ' set filter
CAN0SetOperationMode(_CAN_MODE_NORMAL,0xFF) ' set NORMAL mode
while TRUE
Msg_Rcvd = CAN0ReadMessage(2, Rx_ID , RxTx_Data , Rx_Data_Len, Can_Rcv_Flags)' receive message
if ((Rx_ID = ID_1st) and (Msg_Rcvd <> 0)) <> 0 then ' if message received check id
GPIO_PORTJ_DATA = RxTx_Data[0] ' id correct, output data at PORTJ
RxTx_Data[0] = RxTx_Data[0] + 1 ' increment received data
CAN0WriteMessage(1, ID_2nd, RxTx_Data, 1, Can_Send_Flags) ' send incremented data back
end if
wend
end.
STM32
program CAN_2nd
dim Can_Init_Flags as longword
Can_Send_Flags, Can_Rcv_Flags, Rx_Data_Len as byte
RxTx_Data as byte[8]
Rx_ID as longword
Msg_Rcvd as longword
const ID_1st as longint = 12111
const ID_2nd as longint = 3 ' node IDs
main:
GPIO_Digital_Output(@GPIOE_BASE, 0xFF00)
GPIOE_ODR = 0
Can_Init_Flags = 0 '
Can_Send_Flags = 0 ' clear flags
Can_Rcv_Flags = 0 '
Can_Send_Flags = _CAN_TX_XTD_FRAME and ' with CANWrite
_CAN_TX_NO_RTR_FRAME
Can_Init_Flags = _CAN_CONFIG_AUTOMATIC_RETRANSMISSION and ' form value to be used
_CAN_CONFIG_RX_FIFO_NOT_LOCKED_ON_OVERRUN and ' with CANInit
_CAN_CONFIG_TIME_TRIGGERED_MODE_DISABLED and
_CAN_CONFIG_TX_FIFO_PRIORITY_BY_IDINTIFIER and
_CAN_CONFIG_WAKE_UP
CAN1InitializeAdvanced(1,5,4,4,1,Can_Init_Flags, @_GPIO_MODULE_CAN1_PD01) ' Initialize CAN module
CAN1SetOperationMode(_CAN_OperatingMode_Initialization) ' set CONFIGURATION mode
CANSetFilter(0, ID_1st,_CAN_FILTER_ENABLED and _CAN_FILTER_ID_MASK_MODE and _CAN_FILTER_XTD_MSG)
CANSetMask(0, 0xFFFFFFFF,_CAN_FILTER_ENABLED and _CAN_FILTER_ID_MASK_MODE and _CAN_FILTER_XTD_MSG)
CAN1SetOperationMode(_CAN_OperatingMode_Normal) ' set NORMAL mode
while TRUE
Msg_Rcvd = CAN1Read(0, Rx_ID , RxTx_Data , Rx_Data_Len, Can_Rcv_Flags) ' receive message
if ((Rx_ID = ID_1st) and (Msg_Rcvd <> 0)) then
GPIOE_ODR = word(RxTx_Data[0]) << 8 ' id correct, output data at PORTE
inc(RxTx_Data[0]) ' increment received data
CAN1Write(ID_2nd, RxTx_Data, 1, Can_Send_Flags) ' send incremented data back
end if
wend
end.
What do you think about this topic ? Send us feedback!





