Summary of Connect CAN Protocol with PIC
The mikroC PRO for PIC CAN library provides drivers to configure and use the microcontroller CAN module, offering initialization, baud-rate setup, masks/filters, read/write, operation mode control, and TX idle-level settings. It supports standard (11-bit) and extended (29-bit) identifiers, requires a CAN transceiver (e.g., MCP2551) and proper bus termination, and exposes numerous configuration constants and flags for flexible timing and message handling.
Parts used in the CAN Project:
- Microcontroller with CAN module (PIC MCU)
- CAN transceiver (MCP2551 or similar)
- Shielded twisted pair cable for CAN bus
- Termination resistors for CAN bus (per CAN standard)
- Standard format, with 11 identifier bits, and
- Extended format, with 29 identifier bits
- Consult the CAN standard about CAN bus termination resistance.
Library Routines
- CANSetOperationMode
- CANGetOperationMode
- CANInitialize
- CANSetBaudRate
- CANSetMask
- CANSetFilter
- CANRead
- CANWrite
- CANSetTxIdleLevel
CANSetOperationMode
| Prototype | void CANSetOperationMode(unsigned short mode, unsigned short wait_flag); |
|---|---|
| Returns | Nothing. |
| Description | Sets CAN to requested mode, i.e. copies mode to CANSTAT. Parameter mode needs to be one of CAN_OP_MODE constants .Parameter wait_flag needs to be either 0 or 0xFF:
|
| Requires | Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
CANSetOperationMode(_CAN_MODE_CONFIG, 0xFF); |
CANGetOperationMode
| Prototype | unsigned short CANGetOperationMode(); |
|---|---|
| Returns | Current opmode. |
| Description | Function returns current operational mode of CAN module. |
| Requires | Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
if (CANGetOperationMode() == _CAN_MODE_NORMAL) { ... };
|
CANInitialize
| Prototype | void CANInitialize(char SJW, char BRP, char PHSEG1, char PHSEG2, char PROPSEG, char CAN_CONFIG_FLAGS); |
|---|---|
| Returns | Nothing. |
| Description | Initializes CAN. All pending transmissions are aborted. Sets all mask registers to 0 to allow all messages. Filter registers are set according to flag value: if (CAN_CONFIG_FLAGS & _CAN_CONFIG_VALID_XTD_MSG != 0) // Set all filters to XTD_MSG else if (config & _CAN_CONFIG_VALID_STD_MSG != 0) // Set all filters to STD_MSG else // Set half of the filters to STD, and the rest to XTD_MSG. Parameters:
|
| Requires | CAN must be in Config mode; otherwise the function will be ignored. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
init = _CAN_CONFIG_SAMPLE_THRICE &
_CAN_CONFIG_PHSEG2_PRG_ON &
_CAN_CONFIG_STD_MSG &
_CAN_CONFIG_DBL_BUFFER_ON &
_CAN_CONFIG_VALID_XTD_MSG &
_CAN_CONFIG_LINE_FILTER_OFF;
...
CANInitialize(1, 1, 3, 3, 1, init); // initialize CAN
|
CANSetBaudRate
| Prototype | void CANSetBaudRate(char SJW, char BRP, char PHSEG1, char PHSEG2, char PROPSEG, char CAN_CONFIG_FLAGS); |
|---|---|
| Returns | Nothing. |
| Description | Sets CAN baud rate. Due to complexity of CAN protocol, you cannot simply force a bps value. Instead, use this function when CAN is in Config mode. Refer to datasheet for details. Parameters:
|
| Requires | CAN must be in Config mode; otherwise the function will be ignored. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
init = _CAN_CONFIG_SAMPLE_THRICE &
_CAN_CONFIG_PHSEG2_PRG_ON &
_CAN_CONFIG_STD_MSG &
_CAN_CONFIG_DBL_BUFFER_ON &
_CAN_CONFIG_VALID_XTD_MSG &
_CAN_CONFIG_LINE_FILTER_OFF;
...
CANSetBaudRate(1, 1, 3, 3, 1, init);
|
CANSetMask
| Prototype | void CANSetMask(char CAN_MASK, long value, char CAN_CONFIG_FLAGS); |
|---|---|
| Returns | Nothing. |
| Description | Function sets mask for advanced filtering of messages. Given value is bit adjusted to appropriate buffer mask registers.Parameters:
|
| Requires | CAN must be in Config mode; otherwise the function will be ignored. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
// Set all mask bits to 1, i.e. all filtered bits are relevant: CANSetMask(_CAN_MASK_B1, -1, _CAN_CONFIG_XTD_MSG); // Note that -1 is just a cheaper way to write 0xFFFFFFFF. Complement will do the trick and fill it up with ones. |
CANSetFilter
| Prototype | void CANSetFilter(char CAN_FILTER, long value, char CAN_CONFIG_FLAGS); |
|---|---|
| Returns | Nothing. |
| Description | Function sets message filter. Given value is bit adjusted to appropriate buffer mask registers.Parameters:
|
| Requires | CAN must be in Config mode; otherwise the function will be ignored. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
// Set id of filter B1_F1 to 3: CANSetFilter(_CAN_FILTER_B1_F1, 3, _CAN_CONFIG_XTD_MSG); |
CANRead
| Prototype | char CANRead(long *id, char *data, char *datalen, char *CAN_RX_MSG_FLAGS); |
|---|---|
| Returns | Message from receive buffer or zero if no message found. |
| Description | Function reads message from receive buffer. If at least one full receive buffer is found, it is extracted and returned. If none found, function returns zero. Parameters:
|
| Requires | CAN must be in mode in which receiving is possible. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
char rcv, rx, len, data[8]; long id; // ... rx = 0; // ... rcv = CANRead(id, data, len, rx); |
CANWrite
| Prototype | unsigned short CANWrite(long id, char *data, char datalen, char CAN_TX_MSG_FLAGS); |
|---|---|
| Returns | Returns zero if message cannot be queued (buffer full). |
| Description | If at least one empty transmit buffer is found, function sends message on queue for transmission. If buffer is full, function returns 0. Parameters:
|
| Requires | CAN must be in Normal mode. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. |
| Example |
char tx, data;
long id;
// ...
tx = _CAN_TX_PRIORITY_0 &
_CAN_TX_XTD_FRAME;
// ...
CANWrite(id, data, 2, tx);
|
CANSetTxIdleLevel
| Prototype | void CANSetTxIdleLevel(char driveHighState); | ||||||
|---|---|---|---|---|---|---|---|
| Returns | Nothing. | ||||||
| Description | This function sets the state of CANTX pin when recessive. Parameters:
|
||||||
| Requires | Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus. | ||||||
| Example |
CANSetTxIdleLevel(_CAN_DRIVE_HIGH_STATE_ENABLE); |
CAN Constants
CAN_OP_MODE
CAN_OP_MODE constants define CAN operation mode. Function CANSetOperationMode expects one of these as its argument:_CAN_MODE_SLEEP = 0x20,
_CAN_MODE_LOOP = 0x40,
CAN_CONFIG_FLAGS constants define flags related to CAN module configuration. Functions CANInitialize and CANSetBaudRate expect one of these (or a bitwise combination) as their argument:&) to form config byte out of these values. For example:_CAN_CONFIG_PHSEG2_PRG_ON &
_CAN_CONFIG_STD_MSG &
_CAN_CONFIG_VALID_XTD_MSG &
For more detail: Connect CAN Protocol with PIC
- What message formats does CAN support?
CAN supports standard format with 11 identifier bits and extended format with 29 identifier bits. - How do I set the CAN operation mode?
Use CANSetOperationMode(mode, wait_flag) with a CAN_OP_MODE constant and wait_flag 0 or 0xFF. - Can I check the current CAN operation mode?
Yes, call CANGetOperationMode which returns the current opmode. - How do I initialize the CAN module?
Call CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS) while CAN is in Config mode. - How is CAN baud rate configured?
Use CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS) when CAN is in Config mode. - How do I set masks and filters for message selection?
Use CANSetMask(CAN_MASK, value, CAN_CONFIG_FLAGS) for masks and CANSetFilter(CAN_FILTER, value, CAN_CONFIG_FLAGS) for filters while in Config mode. - How can I read a received CAN message?
Use CANRead(id, data, datalen, CAN_RX_MSG_FLAGS); it returns the message or zero if none found. - How do I send a CAN message?
Use CANWrite(id, data, datalen, CAN_TX_MSG_FLAGS) while CAN is in Normal mode; it returns zero if transmit buffers are full. - How do I set the CANTX idle level?
Use CANSetTxIdleLevel(_CAN_DRIVE_HIGH_STATE_ENABLE or _CAN_DRIVE_HIGH_STATE_DISABLE) to set CANTX recessive state. - What hardware is required for using the CAN library?
The microcontroller must be connected to a CAN transceiver such as MCP2551 which is connected to the CAN bus.

