cubemx
生成代码后。写了一个测试程序;
调用这个函数,
一直提示can发送error;
原因分析:
cubemx生成代码如下:
void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 21;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_2TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
/* USER CODE END CAN1_Init 2 */
}
MX_CAN1_Init函数不完全;
想要实现发送,需要在MX_CAN1_Init添加
HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) ;
HAL_CAN_Start(&hcan1);
HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
想要接收,需要做2个操作:
1)需要在MX_CAN1_Init添加
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
2)实现can回调函数
uint8_t User_CAN_RxData[8]=0;
uint8_t Can_Rx_Data_for_calculate[8] = 0;
CAN_RxHeaderTypeDef RxHeader;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//can接收中断回调函数
{
uint8_t can_rx_string[30] = {0};
memset(User_CAN_RxData,0,sizeof(User_CAN_RxData));
if(hcan->Instance==CAN1)
{
HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,&RxHeader,User_CAN_RxData);
if(RxHeader.StdId == 0x01)//接收ID为00 00 00 01的can包
{
sprintf(can_rx_string,"can_data:[0x]%d,%d,%d,%d,%d,%d,%d,%d\r\n",User_CAN_RxData[0],\
User_CAN_RxData[1],User_CAN_RxData[2],User_CAN_RxData[3],User_CAN_RxData[4],\
User_CAN_RxData[5],User_CAN_RxData[6],User_CAN_RxData[7]);
HAL_UART_Transmit(&huart3, can_rx_string, strlen(can_rx_string), 100);
}
}
}
因此完整的can配置代码如下:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file can.c
* @brief This file provides code for the configuration
* of the CAN instances.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"
/* USER CODE BEGIN 0 */
CAN_TxHeaderTypeDef TxHeader= {
.RTR = CAN_RTR_DATA,
.IDE = CAN_ID_STD,
.StdId = 1,
.TransmitGlobalTime = DISABLE,
.DLC = 8,
};
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
extern UART_HandleTypeDef huart3;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
CAN_FilterTypeDef sFilterConfig;//--------------------------------------------
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 21;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;/
hcan1.Init.TimeSeg1 = CAN_BS1_2TQ;/
hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;///
hcan1.Init.AutoWakeUp = DISABLE;/
hcan1.Init.AutoRetransmission = DISABLE;//
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;///
if (HAL_CAN_Init(&hcan1) != HAL_OK)/
{
Error_Handler();
HAL_UART_Transmit(&huart3, "HAL_CAN_Init failed\r\n", strlen("HAL_CAN_Init failed\r\n"), 100);
}
/* USER CODE BEGIN CAN1_Init 2 */
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) ;
HAL_CAN_Start(&hcan1);
HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
/* USER CODE END CAN1_Init 2 */
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* CAN1 clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
uint8_t User_CAN_RxData[8]=0;
uint8_t Can_Rx_Data_for_calculate[8] = 0;
CAN_RxHeaderTypeDef RxHeader;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//can接收中断回调函数
{
uint8_t can_rx_string[30] = {0};
memset(User_CAN_RxData,0,sizeof(User_CAN_RxData));
if(hcan->Instance==CAN1)
{
HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,&RxHeader,User_CAN_RxData);
if(RxHeader.StdId == 0x01)//接收ID为00 00 00 01的can包
{
sprintf(can_rx_string,"can_data:[0x]%d,%d,%d,%d,%d,%d,%d,%d\r\n",User_CAN_RxData[0],\
User_CAN_RxData[1],User_CAN_RxData[2],User_CAN_RxData[3],User_CAN_RxData[4],\
User_CAN_RxData[5],User_CAN_RxData[6],User_CAN_RxData[7]);
HAL_UART_Transmit(&huart3, can_rx_string, strlen(can_rx_string), 100);
}
}
}
/* USER CODE END 1 */
验证:
1)测试can发送
2)测试can接收