Difference between revisions of "STM32 CAN"
Jump to navigation
Jump to search
Line 31: | Line 31: | ||
| valign=top | [[File:Can loopback example can nvic.png]] | | valign=top | [[File:Can loopback example can nvic.png]] | ||
|} | |} | ||
+ | |||
+ | === Code === | ||
+ | |||
+ | First let's drop a few global variables to handle the CAN messages: | ||
+ | |||
+ | <pre> | ||
+ | /* USER CODE BEGIN PV */ | ||
+ | |||
+ | CAN_TxHeaderTypeDef TxHeader; | ||
+ | CAN_RxHeaderTypeDef RxHeader; | ||
+ | |||
+ | uint32_t TxMailbox; | ||
+ | |||
+ | uint8_t TxData[8]; | ||
+ | uint8_t RxData[8]; | ||
+ | |||
+ | uint32_t msg_count = 0; | ||
+ | |||
+ | /* USER CODE END PV */ | ||
+ | </pre> | ||
+ | |||
+ | Second, we create a callback to receive messages: | ||
+ | |||
+ | <pre> | ||
+ | void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) | ||
+ | { | ||
+ | DBG("HAL_CAN_RxFifo0MsgPendingCallback"); | ||
+ | if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) { | ||
+ | DBG("Got message %lu - id = 0x%04lx len = 0x%lx, data=%02x%02x%02x%02x%02x%02x%02x%02x", msg_count + 1, RxHeader.StdId, RxHeader.DLC, RxData[0], RxData[1], RxData[2], RxData[3], RxData[4], RxData[5], RxData[6], RxData[7]); | ||
+ | } | ||
+ | msg_count++; | ||
+ | } | ||
+ | </pre> | ||
== Real CAN bus example == | == Real CAN bus example == |
Revision as of 13:12, 23 December 2023
Introduction
Most STM32 MCUs are equipped with one or more CAN peripherals.
Loopback Example
The CAN peripheral on STM32 MCU's can be configured to run in loopback mode. This makes it possible to test CAN programming without actually hooking the device up to a physical CAN bus.
The source for this example is here: https://github.com/STM32World/firmware/tree/master/mcustm32f405_can_loopback
CubeMX Config
The clock is configured to maximum speed using the external crystal:
Notice the APB1 bus is running at 42 MHz. The CAN peripherals are connected to this bus.
We can now configure the CAN1 periopheral:
Code
First let's drop a few global variables to handle the CAN messages:
/* USER CODE BEGIN PV */ CAN_TxHeaderTypeDef TxHeader; CAN_RxHeaderTypeDef RxHeader; uint32_t TxMailbox; uint8_t TxData[8]; uint8_t RxData[8]; uint32_t msg_count = 0; /* USER CODE END PV */
Second, we create a callback to receive messages:
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { DBG("HAL_CAN_RxFifo0MsgPendingCallback"); if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) { DBG("Got message %lu - id = 0x%04lx len = 0x%lx, data=%02x%02x%02x%02x%02x%02x%02x%02x", msg_count + 1, RxHeader.StdId, RxHeader.DLC, RxData[0], RxData[1], RxData[2], RxData[3], RxData[4], RxData[5], RxData[6], RxData[7]); } msg_count++; }
Real CAN bus example
To be added
Miscellaneous Links
To be added