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

在调试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

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32的CAN总线通信是一种非常常见的双机通讯方式,可以实现高速、可靠的数据传输。下面是一个简单的双机通讯的步骤: 1. 配置CAN通信参数:包括波特率、数据位、校验位等。 2. 初始化CAN模块:使能CAN模块、配置CAN接收中断等。 3. 发送数据:将待发送的数据填入CAN发送FIFO缓冲区中,并触发发送请求。 4. 接收数据:在CAN接收中断中,读取接收到的数据,根据数据标识符判断数据类型。 5. 处理数据:根据接收到的数据类型进行相应的处理,如更新状态、执行控制操作等。 下面是一个简单的CAN通信程序示例: ```c #include "stm32f10x.h" CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; CanTxMsg TxMessage; CanRxMsg RxMessage; void CAN_Config(void) { /* Enable CAN clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); /* CAN GPIOs configuration **************************************************/ /* GPIO clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE); /* Configure CAN RX and TX pins */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); /* CAN configuration ********************************************************/ /* CAN register init */ CAN_DeInit(CAN1); /* CAN cell init */ CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = ENABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; CAN_InitStructure.CAN_Prescaler = 4; CAN_Init(CAN1, &CAN_InitStructure); /* CAN filter init */ CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); /* Enable FIFO 0 message pending Interrupt */ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); } void CAN_SendMessage(void) { /* Transmit Structure preparation */ TxMessage.StdId = 0x321; TxMessage.ExtId = 0x01; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; TxMessage.DLC = 1; TxMessage.Data[0] = 0xAA; /* Transmit the message */ CAN_Transmit(CAN1, &TxMessage); } void CAN_ReceiveMessage(void) { /* Get the received message */ CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); /* Process received message */ if (RxMessage.StdId == 0x321) { // Do something with received data } } int main(void) { /* CAN configuration */ CAN_Config(); while (1) { /* Send message */ CAN_SendMessage(); /* Wait for message to be received */ while(!CAN_GetFlagStatus(CAN1, CAN_FLAG_FMP0)); /* Process received message */ CAN_ReceiveMessage(); } } ``` 这是一个基本的CAN双机通讯的示例,你可以根据自己的需要进行修改。需要注意的是,CAN通讯需要硬件支持,因此需要在硬件电路设计中预留好CAN总线接口。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值