最近在使用STM32F767VIH6调试CAN的时候遇到点问题,在此记录一下调试记录。
硬件:STM32F767VIH6 CAN3
引脚:CAN3_RX -> PB3
CAN3_TX -> PA15
CubeMX配置


在CubeMX生成的工程中,MX_CAN3_Init函数中添加过滤器相关代码,并调用HAL_CAN_Start函数。
static void MX_CAN3_Init(void)
{
/* USER CODE BEGIN CAN3_Init 0 */
/* USER CODE END CAN3_Init 0 */
/* USER CODE BEGIN CAN3_Init 1 */
/* USER CODE END CAN3_Init 1 */
hcan3.Instance = CAN3;
hcan3.Init.Prescaler = 3;
hcan3.Init.Mode = CAN_MODE_NORMAL;
hcan3.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan3.Init.TimeSeg1 = CAN_BS1_16TQ;
hcan3.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan3.Init.TimeTriggeredMode = DISABLE;
hcan3.Init.AutoBusOff = ENABLE;
hcan3.Init.AutoWakeUp = ENABLE;
hcan3.Init.AutoRetransmission = DISABLE;
hcan3.Init.ReceiveFifoLocked = DISABLE;
hcan3.Init.TransmitFifoPriority = ENABLE;
if (HAL_CAN_Init(&hcan3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN3_Init 2 */
CAN_FilterTypeDef CAN1_FilerConf;
CAN1_FilerConf.FilterBank = 0; //过滤器0
CAN1_FilerConf.FilterMode = CAN_FILTERMODE_IDMASK;
CAN1_FilerConf.FilterScale = CAN_FILTERSCALE_32BIT;
CAN1_FilerConf.FilterIdHigh = 0X0000; //32位ID
CAN1_FilerConf.FilterIdLow = 0X0000;
CAN1_FilerConf.FilterMaskIdHigh = 0X0000; //32位MASK
CAN1_FilerConf.FilterMaskIdLow = 0X0000;
CAN1_FilerConf.FilterFIFOAssignment = CAN_FILTER_FIFO0;//过滤器0关联到FIFO0
CAN1_FilerConf.FilterActivation = ENABLE; //激活滤波器0
CAN1_FilerConf.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan3,&CAN1_FilerConf)!=HAL_OK)
{
printf("filter config failed.\r\n");
Error_Handler();//滤波器初始化
}
if(HAL_CAN_Start(&hcan3)!=HAL_OK)
{
printf("CAN3 start failed.\r\n");
Error_Handler();//CAN打开
}
/* USER CODE END CAN3_Init 2 */
}
调试的结果就是HAL_CAN_Start函数返回值为HAL_ERROR。经调试发现,程序运行到以下程序段返回

程序运行到这里的时候寄存器状态如下

试了很多方法都不行。但是将CubeMX生成的相关函数复制到其他旧版本调通过CAN3通信的工程中,程序可以正常初始化CAN3,运行到HAL_CAN_Start函数的时候,寄存器状态如下

一次偶然情况下,在配置CubeMX的时候,错将CAN3_TX配置到PB4引脚时,CAN3可以顺利初始化!于是在该工程基础上做了以下修改
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan->Instance==CAN3)
{
/* USER CODE BEGIN CAN3_MspInit 0 */
/* USER CODE END CAN3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN3_CLK_ENABLE();
__HAL_RCC_CAN2_CLK_ENABLE();
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN3 GPIO Configuration
PB3 ------> CAN3_RX
PA15 ------> CAN3_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_CAN3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_CAN3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN CAN3_MspInit 1 */
//添加以下两行代码
GPIO_InitStruct.Pin = GPIO_PIN_15;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE END CAN3_MspInit 1 */
}
}
先将PB4复用为CAN3_TX,再将PA15复用为CAN3_TX,此时程序可以正常初始化CAN3,并正常接收到数据。
此处仅记录调试过程,具体CAN3无法正常初始化的原因不明,反正目前程序可以用,先用着。希望有知道原因的大佬指点一下!
3435

被折叠的 条评论
为什么被折叠?



