STM32 HAL库 CAN双机通信接收无法进入中断、中断没有反应的解决方法

文章讲述了在调试HAL库下CAN双机通信时,通过调整CAN_ConfigFilter、CAN_Start和CAN_ActivateNotification函数的顺序和配置,解决了中断接收无响应的问题,强调了这三个函数应保持捆绑执行的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在调试HAL库下的CAN双机(双F103ZET6)通信时,阻塞轮询接收完全正常,但是中断接收没有反应。翻看了GL的烧脑之路总结(一):Cubemx创建CAN通信工程,无法进入CAN中断的原因这篇文章以后,核实自己的硬件电路没有问题,于是对自己的工程文件进行整理,把
①HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)//配置can
②HAL_CAN_Start(CAN_HandleTypeDef *hcan)//开始can
③HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)//使能can
三个函数放在一起后,成功实现了CAN中断接收,下面是我在工程中的配置源码:

void can_filterconfig_and_init(void)
{
	CAN_FilterTypeDef filter;
	filter.FilterIdHigh = 0x0000;
	filter.FilterIdLow = 0x0000;
	filter.FilterMaskIdHigh = 0x0000;
	filter.FilterMaskIdLow = 0x0000;
	//不过滤
	filter.FilterFIFOAssignment = CAN_FILTER_FIFO1;
	filter.FilterActivation = ENABLE;
	filter.FilterMode = CAN_FILTERMODE_IDMASK;
	filter.FilterScale = CAN_FILTERSCALE_32BIT;
	filter.FilterBank = 0;
	//filter.SlaveStartFilterBank =14;
	
	if(HAL_CAN_ConfigFilter(&hcan,&filter) != HAL_OK)
	{
		Error_Handler();
		Usart_SendString("can配置失败\r\n");
	}	
	else
		Usart_SendString("can配置成功\r\n");
	
	if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)
	{
		Error_Handler();
		Usart_SendString("开启挂起中断允许失败\r\n");
	}	
	else
		Usart_SendString("开启挂起中断允许成功\r\n");
	if(HAL_CAN_Start(&hcan) != HAL_OK)
	{
		Error_Handler();
		Usart_SendString("can开启失败\r\n");
	}	
	else
		Usart_SendString("can开启成功\r\n");
}

以上三个函数的位置和顺序建议参考我的代码,下图是以上代码在工程中的位置。
在这里插入图片描述
最终在main函数中调用:
(中断回调函数我就不写了,教程很多)

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	can_filterconfig_and_init();//*这儿!不要忘记声明哦。* 

  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

最终代码运行结果(串口助手中):
在这里插入图片描述
花了很长时间踩了这个坑,之前的原因应该是把这三个函数分开了,建议这三个函数一辈子捆绑在一起!谢谢大家能看到这里!

源码自取,开源万岁!
链接:https://pan.baidu.com/s/1jQTEc2XtnRRcrEVfafYuWg?pwd=ivml
提取码:ivml

<think>嗯,用户现在想找关于HALCAN中断回调函数的相关资料和实现方法。首先,我需要回忆一下STM32HAL结构。HAL通常会为每个外设提供中断处理函数,而用户需要重写特定的回调函数来实现自己的逻辑。 用户提到了CAN中断,可能涉及接收中断、发送中断或者错误中断HAL中,中断处理流程一般是这样的:当发生中断时,HAL中断服务程序(ISR)会被调用,然后HAL内部处理一些状态,之后调用用户定义的弱函数回调函数。所以用户需要自己实现这些回调函数。 接下来,我应该考虑如何组织示例代码。首先,用户需要初始化CAN外设,配置中断,然后实现回调函数。例如,HAL_CAN_RxFifo0MsgPendingCallback会在接收FIFO有消息时触发。我需要确保示例代码正确使用HAL_CAN_ActivateNotification来启用特定中断的通知。 另外,参考文档方面,用户可能需要查阅AN5348应用笔记,以及HAL的源代码。在HAL的头文件,比如stm32h7xx_hal_can.h中,应该能找到所有回调函数的定义和说明。同时,ST的官方文档和CubeH7软件包中的示例工程也是重要资源,用户可能需要指导他们去查找这些资料。 还要注意用户提到的轮询方式和中断方式的区别,确保示例代码使用正确的中断配置步骤,比如启用NVIC中断,激活通知等。可能还需要提醒用户关于中断优先级的设置,避免潜在的问题。 最后,用户可能需要知道如何处理接收到的数据,比如解析CAN消息的ID、数据长度和数据内容,并在回调函数中进行处理。同时,错误处理也是重要的一环,实现HAL_CAN_ErrorCallback可以帮助调试。 总结一下,回答应该包括初始化步骤、回调函数实现、示例代码片段、参考文档和常见问题。确保各部分结构清晰,引用正确的文档,比如AN5348和CubeH7的示例工程,帮助用户找到更多资料。</think>### STM32 HALCAN中断回调函数实现方法 #### 一、中断回调机制原理 在STM32 HAL中,CAN中断回调函数通过弱定义(weak)函数实现,用户需在工程中重写这些函数。HAL通过`HAL_CAN_IRQHandler()`处理中断事件后,会自动调用对应的回调函数[^1]。 #### 二、关键配置步骤 1. **CAN外设初始化** ```c CAN_HandleTypeDef hcan; hcan.Instance = CANx; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.AutoBusOff = ENABLE; hcan.Init.AutoRetransmission = ENABLE; HAL_CAN_Init(&hcan); ``` 2. **中断配置** ```c // 启用接收中断 HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // 启用错误中断 HAL_CAN_ActivateNotification(&hcan, CAN_IT_ERROR); // 配置NVIC中断 HAL_NVIC_SetPriority(CANx_RX0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(CANx_RX0_IRQn); ``` #### 三、回调函数实现示例 1. **接收完成回调** ```c void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { CAN_RxHeaderTypeDef rx_header; uint8_t rx_data[8]; HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data); // 解析CAN数据 if(rx_header.StdId == 0x123) { // 处理特定ID的数据 } } ``` 2. **错误回调函数** ```c void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { uint32_t error = HAL_CAN_GetError(hcan); // 处理错误代码 if(error & HAL_CAN_ERROR_ACK) { // 处理应答错误 } } ``` #### 四、关键参考文档 1. 《STM32H7 HAL驱动手册》(文件路径:`Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_can.c`) 2. 官方应用笔记《AN5348》第4.3节关于中断配置的说明 3. STM32CubeH7软件包中的CAN示例工程(路径:`Projects/STM32H743I-EVAL/Examples/CAN/CAN_Networking`)[^2] #### 五、常见问题处理 1. **中断未触发**:检查`HAL_CAN_ActivateNotification()`调用顺序,必须在启动CAN(`HAL_CAN_Start()`)之后调用 2. **数据接收不完整**:确认FIFO锁定机制,使用`__HAL_CAN_FIFO_RELEASE()`释放FIFO 3. **优先级冲突**:通过`HAL_NVIC_SetPriority()`设置合适的中断优先级
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值