1 Introduction
Use STM32F407IGHX single-chip microcomputer (C board) CAN1, CAN2 to short circuit for data self-transmission.
2. CubeMax initialization configuration
Introduction to CAN communication: CAN bus and microcontroller .
1. rcc configuration
2.sys configuration
3. Clock tree configuration
4. CAN configuration
It should be noted that the sixth point, according to the C-board manual, CAN1 output interface is PD0, PD1, as shown in the following figure:
CAN2 configuration is consistent with CAN1, no need to configure pins separately, C board CAN2 output pins are consistent with the default configuration.
5. Trigger button configuration
6. File export
3 Keil terminal program writing
3.1. Initial configuration
1. Filter configuration
To use the CAN bus, you first need to configure the filter.
/* USER CODE BEGIN 4 */
//CAN初始化
void CAN_ConfigFilter()
{
//过滤器配置
CAN_FilterTypeDef sFilterConfig;//建立过滤器结构体
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterFIFOAssignment = CAN_FilterFIFO0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;//32 位 ID 不使用过滤器
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;//32 位 MASK
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
sFilterConfig.FilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE END 4 */
2. CAN startup configuration
After the filter configuration, carry out the CAN startup configuration, first start CAN1 and then start CAN2, the code is as follows:
if(HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
//启动CAN
if(HAL_CAN_Start(&hcan1)!= HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan2)!= HAL_OK)
{
Error_Handler();
}
3. Turn on interrupt
After CAN starts, perform CAN interrupt configuration, the code is as follows:
//打开接收中断
if(HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING|CAN_IT_RX_FIFO1_MSG_PENDING)!= HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO0_MSG_PENDING|CAN_IT_RX_FIFO1_MSG_PENDING)!= HAL_OK)
{
Error_Handler();
}
The entire initialization function code is as follows:
//CAN初始化
void CAN_ConfigFilter()
{
//过滤器配置
CAN_FilterTypeDef sFilterConfig;//建立过滤器结构体
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterFIFOAssignment = CAN_FilterFIFO0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;//32 位 ID 不使用过滤器
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;//32 位 MASK
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
sFilterConfig.FilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
//启动CAN
if(HAL_CAN_Start(&hcan1)!= HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan2)!= HAL_OK)
{
Error_Handler();
}
//打开接收中断
if(HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING|CAN_IT_RX_FIFO1_MSG_PENDING)!= HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO0_MSG_PENDING|CAN_IT_RX_FIFO1_MSG_PENDING)!= HAL_OK)
{
Error_Handler();
}
}
/* USER CODE END 4 */
4. Function declaration and main function call
Declare the appeal function in main.h, as follows:
/* USER CODE BEGIN Includes */
void CAN_ConfigFilter();
/* USER CODE END Includes */
After the declaration, initialize it in the main function, as follows:
/* USER CODE BEGIN 2 */
CAN_ConfigFilter();
/* USER CODE END 2 */
5. Define arrays, send and receive structures
/* USER CODE BEGIN PV */
uint8_t txData[8],rxData0[8],rxData1[8];
CAN_TxHeaderTypeDef txHeader;
CAN_RxHeaderTypeDef rxHeader0,rxHeader1;
bool Pa0Pressed = false;
uint16_t txID = 0x200;
uint32_t txMailbox;
/* USER CODE END PV */
6. Button trigger
reference header file
/* USER CODE BEGIN Includes */
#include "stdbool.h"
/* USER CODE END Includes */
7. CAN configuration
while (1)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == 0 && !Pa0Pressed){
Pa0Pressed = true;
txHeader.StdId = txID;
txHeader.IDE = CAN_ID_STD;
txHeader.RTR = CAN_RTR_DATA;
txHeader.DLC = 8;
*((uint32_t*)(txData)) = HAL_GetTick();
if(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 0){
HAL_CAN_AddTxMessage(&hcan1,&txHeader,txData,&txMailbox);
}
}
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == 1 && !Pa0Pressed){
Pa0Pressed = false;
}
HAL_Delay(100);
8 Interrupt callback function
/* USER CODE BEGIN 4 */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance==CAN2)
{
HAL_CAN_GetRxMessage(&hcan2,CAN_FILTER_FIFO0,&rxHeader0,rxData0);//获取数据
}
}
void HAL_CAN_RxFifo10MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance==CAN2)
{
HAL_CAN_GetRxMessage(&hcan1,CAN_FILTER_FIFO1,&rxHeader1,rxData1);//获取数据
}
}