STM32芯片CAN2只能发送不能接收问题解决。

STM32F107在使用过程中,调整了一下任务优先级后,发现CAN2相关的任务的优先级被提高后,CAN2只能发送,不能接收,后来通过把CAN2的任务延时一段时间再初始化启动,发现可以正常收发了,通过排除的办法,发现只要CAN1的任务只要滞后与CAN2任务的启动,就会发生这种现象。后来听同事讲STM32的CAN2是通过CAN1扩展出来的,必须先初始化CAN1,再初始化CAN2才可以正常运行。后来把这两个CAN的初始化做了个先后顺序初始化后,恢复正常。怎么调整任务优先级都可以正常收发。

在网上搜了一下,发现有其它朋友也碰到过此种情况:

调试STM32F107的CAN2竟然无法接收。通过与另一个代码对比,终于发现想用CAN2,则必须把CAN1的RCC也配置上,就可以接收了。

上网查了下,21IC给解释http://bbs.21ic.com/icview-542674-1-1.html。手册也懒得看了,总之,CAN2和CAN1是有关联的。对于STM32F407可能也是如此。

如果设置两遍也不行。也是CAN2不能接收。

比如这样设置两遍:

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

那么不行,只有在整个工程中设置一遍才可以,如下:

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

只有先使能CAN1  然后才使能CAN2  否则有的不好用。

上面这些都是试出来的,没看文档,没理论依据。

关于FIFO 的配置  可以看这个文章http://blog.csdn.net/varding/article/details/39179125

而我目前只是采用一个FIFO0.

好用就得。实时性对我来说是次要的。
 

<think>好的,我现在需要帮助用户了解如何在STM32F407上配置CAN总线的接收部分。首先,我需要回忆一下STM32CAN模块相关知识,尤其是使用HAL库的情况。用户提到了STM32F407,所以应该参考该型号的HAL库文档和相关示例代码。 根据之前的引用内容,用户提供的参考中有提到在STM32CubeIDE中使用HAL库实现CAN从站,并且涉及到CanRxMsgTypeDef更改为CAN_RxHeaderTypeDef,这说明在较新的CubeIDE版本中,结构体名称可能有所变化。因此,在代码示例中需要注意使用正确的类型名称。 接下来,我需要整理CAN接收配置的步骤。通常,CAN接收配置包括初始化CAN外设、配置过滤器、启动接收以及处理接收中断等步骤。用户可能还需要了解如何编写中断服务函数或者使用轮询方式接收数据。 用户的问题是关于接收配置的,所以重点在接收部分的设置。首先,初始化CAN外设的代码可能已经在CubeMX生成,但需要确认参数是否正确,比如波特率、工作模式等。然后,过滤器配置是关键,因为它决定了哪些消息会被接收。过滤器可以配置为掩码模式或列表模式,用户可能需要根据应用需求设置。例如,如果希望接收所有消息,可以将过滤器配置为不屏蔽任何ID。 接下来是启动接收的部分。HAL库中通常使用HAL_CAN_Start函数来启动CAN模块,然后使用HAL_CAN_ActivateNotification来使能接收中断接收数据可以使用HAL_CAN_GetRxMessage函数,这个函数需要在中断回调中调用,或者在主循环中轮询检查接收标志位。 用户可能需要示例代码,所以需要提供一个基本的接收配置代码框架,包括初始化、过滤器设置、中断启用和接收处理。同时,需要注意引用的资料中提到的结构体名称变化,比如CanRxMsgTypeDef更改为CAN_RxHeaderTypeDef,所以在代码中应该使用新的结构体名称,避免编译错误。 另外,用户可能对过滤器配置不太熟悉,需要解释过滤器的作用和配置方法。例如,过滤器组编号、模式、尺度和ID的设置,以及如何计算FilterID和FilterMask。同时,需要提到HAL_CAN_ConfigFilter函数的使用。 中断处理部分也是关键,需要说明如何使能FIFO0中断,并在中断回调函数中处理接收到的数据。HAL库的中断处理流程通常是重写HAL_CAN_RxFifo0MsgPendingCallback函数,并在其中调用HAL_CAN_GetRxMessage来获取数据。 可能还需要提到错误处理,比如清除接收标志位,使用__HAL_CAN_CLEAR_FLAG宏,这在用户提供的引用[^1]中也有提到。 最后,要确保代码示例正确,并且符合用户使用的CubeIDE版本,特别是结构体名称和函数参数的变化。同时,提醒用户注意硬件连接,比如CAN收发器的配置和终端电阻的设置,这可能影响通信的稳定性。 总结步骤: 1. 使用CubeMX配置CAN外设参数,生成初始化代码。 2. 配置过滤器,设置合适的ID和掩码。 3. 启动CAN模块,使能接收中断。 4. 在中断回调函数中处理接收到的数据。 5. 清除接收标志位,避免重复处理。 需要检查是否有遗漏的步骤,比如GPIO的配置是否正确,时钟是否使能,以及是否启用了全局中断。另外,用户可能需要了解如何测试接收功能,例如使用CAN分析仪发送数据并观察接收情况。 可能遇到的问题包括过滤器配置错误导致无法接收消息,中断未正确使能,或者波特率不匹配。在回答中需要提示用户注意这些常见问题,并参考相关的文档或教程,如引用[^2]和[^3]提到的内容。</think>### STM32F407 CAN接收配置教程 #### 1. CAN初始化配置 首先通过STM32CubeMX生成基础配置: 1. 启用CAN外设(例如CAN1),选择工作模式为`Normal`或`Loopback`(测试用)。 2. 配置波特率:例如设置$Prescaler=4$,$BS1=13$,$BS2=2$,对应波特率计算公式: $$Baudrate = \frac{APB1\_CLK}{Prescaler \times (BS1 + BS2 + 1)}$$ 若APB1时钟为42MHz,则波特率为$42000000/(4 \times 16) = 656.25kbps$。 ```c // CubeMX生成的初始化代码(can.c) CAN_HandleTypeDef hcan1; void MX_CAN1_Init(void) { hcan1.Instance = CAN1; hcan1.Init.Prescaler = 4; hcan1.Init.Mode = CAN_MODE_NORMAL; hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan1.Init.TimeSeg1 = CAN_BS1_13TQ; hcan1.Init.TimeSeg2 = CAN_BS2_2TQ; hcan1.Init.TimeTriggeredMode = DISABLE; hcan1.Init.AutoBusOff = DISABLE; hcan1.Init.AutoWakeUp = DISABLE; hcan1.Init.AutoRetransmission = DISABLE; hcan1.Init.ReceiveFifoLocked = DISABLE; hcan1.Init.TransmitFifoPriority = DISABLE; HAL_CAN_Init(&hcan1); } ``` #### 2. 过滤器配置 配置过滤器接收所有标准帧: ```c void CAN_Filter_Config(void) { CAN_FilterTypeDef filterConfig; filterConfig.FilterBank = 0; // 使用过滤器组0 filterConfig.FilterMode = CAN_FILTERMODE_IDMASK; filterConfig.FilterScale = CAN_FILTERSCALE_32BIT; filterConfig.FilterIdHigh = 0x0000; // ID高16位 filterConfig.FilterIdLow = 0x0000; // ID低16位 filterConfig.FilterMaskIdHigh = 0x0000; // 掩码高16位 filterConfig.FilterMaskIdLow = 0x0000; // 掩码低16位 filterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; filterConfig.FilterActivation = ENABLE; filterConfig.SlaveStartFilterBank = 14; // 双CAN时分配 HAL_CAN_ConfigFilter(&hcan1, &filterConfig); } ``` #### 3. 中断配置与接收处理 ```c // 启用FIFO0接收中断 HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); // 中断回调函数 void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { CAN_RxHeaderTypeDef rxHeader; uint8_t rxData[8]; if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK) { // 处理接收数据 printf("Received ID:0x%03X, Data:", rxHeader.StdId); for(int i=0; i<rxHeader.DLC; i++) printf("%02X ", rxData[i]); } __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RX_FIFO0_FULL); // 清除标志 } ``` #### 4. 启动CAN总线 ```c HAL_CAN_Start(&hcan1); // 启动CAN HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); // 启用中断 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值