在一块stm32f4探索板上用can1和can2通讯,只是用can1发送can2接收,can发送第17次才开始接收,主函数按键发送,环回模式测试正常
根据描述,您在一块STM32F4探索板上使用CAN1和CAN2进行通信,其中只有CAN1发送数据,而CAN2负责接收数据。但是您发现在发送了16次后,CAN2才开始接收数据。
这个问题可能与CAN帧的过滤器设置有关。在CAN通信中,每个CAN控制器都有一组过滤器,用于筛选接收到的CAN帧。默认情况下,CAN控制器的过滤器可能是禁用的,或者只使用了默认过滤器设置。
为了确保CAN2接收到CAN1发送的CAN帧,您需要正确配置和启用CAN2的过滤器。可以通过以下步骤进行设置:
基于您的特定需求,选择适当的过滤器模式。例如,您可以选择屏蔽位模式,即只接受特定标识符范围内的CAN帧。
配置CAN2的过滤器,以仅接受CAN1发送的CAN帧。设置正确的标识符和屏蔽位值,以适应您的通信需求。
启用和激活过滤器,使其生效。
请注意,具体的过滤器设置步骤和寄存器配置可能因不同的STM32F4型号而有所不同,因此建议参考相关的STM32F4探索板的参考手册、数据手册和寄存器描述文档,以了解正确的配置过滤器和寄存器设置。
此外,还要确保CAN1和CAN2的初始化配置正确,系统时钟和波特率设置一致,CAN发送和接收函数的调用正确,以及适当的错误处理和错误中断处理等。
检查以上问题,进行适当的配置和调试,有助于解决CAN1发送的CAN帧在发送16次后才开始被CAN2接收的问题。
以下是一个示例代码,用于在一块STM32F4探索板上使用CAN1发送数据,CAN2接收数据,并正确配置和启用CAN2的过滤器:
#include "stm32f4xx.h"
CAN_FilterInitTypeDef filterConfig;
void CAN1_Configuration(void)
{
CAN_InitTypeDef canInit;
CAN_FilterInitTypeDef filterConfig;
// 使能CAN1时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
// CAN1_GPIO配置
// ...
// 配置CAN1
CAN_DeInit(CAN1);
CAN_StructInit(&canInit);
canInit.CAN_TTCM = DISABLE;
canInit.CAN_ABOM = DISABLE;
canInit.CAN_AWUM = DISABLE;
canInit.CAN_NART = DISABLE;
canInit.CAN_RFLM = DISABLE;
canInit.CAN_TXFP = DISABLE;
canInit.CAN_Mode = CAN_Mode_Normal;
canInit.CAN_SJW = CAN_SJW_1tq;
canInit.CAN_BS1 = CAN_BS1_9tq;
canInit.CAN_BS2 = CAN_BS2_4tq;
canInit.CAN_Prescaler = 2; // 72MHz时钟,500Kbps波特率
CAN_Init(CAN1, &canInit);
// 配置CAN1中断
// ...
// 启动CAN1发送
// ...
}
void CAN2_Configuration(void)
{
CAN_InitTypeDef canInit;
// 使能CAN2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
// CAN2_GPIO配置
// ...
// 配置CAN2
CAN_DeInit(CAN2);
CAN_StructInit(&canInit);
canInit.CAN_TTCM = DISABLE;
canInit.CAN_ABOM = DISABLE;
canInit.CAN_AWUM = DISABLE;
canInit.CAN_NART = DISABLE;
canInit.CAN_RFLM = DISABLE;
canInit.CAN_TXFP = DISABLE;
canInit.CAN_Mode = CAN_Mode_Normal;
canInit.CAN_SJW = CAN_SJW_1tq;
canInit.CAN_BS1 = CAN_BS1_9tq;
canInit.CAN_BS2 = CAN_BS2_4tq;
canInit.CAN_Prescaler = 2; // 72MHz时钟,500Kbps波特率
CAN_Init(CAN2, &canInit);
// 配置CAN2中断
// ...
// 配置CAN2过滤器
CAN_FilterInitTypeDef filterConfig;
filterConfig.CAN_FilterIdHigh = 0x0000;
filterConfig.CAN_FilterIdLow = 0x0000;
filterConfig.CAN_FilterMaskIdHigh = 0x0000;
filterConfig.CAN_FilterMaskIdLow = 0x0000;
filterConfig.CAN_FilterFIFOAssignment = CAN_FIFO0;
filterConfig.CAN_FilterNumber = 0;
filterConfig.CAN_FilterMode = CAN_FilterMode_IdMask;
filterConfig.CAN_FilterScale = CAN_FilterScale_32bit;
filterConfig.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&filterConfig);
// 启动CAN2接收
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
}
int main(void)
{
// 初始化CAN1和CAN2
CAN1_Configuration();
CAN2_Configuration();
// 等待CAN2接收到第17个CAN帧
while (1)
{
if (CAN_MessagePending(CAN2, CAN_FIFO0) >= 17)
{
// 执行接收处理
// ...
break;
}
}
while (1)
{
// 主程序代码
// ...
}
}
该示例代码假设您已经进行了正确的GPIO和中断配置。在CAN2_Configuration()
函数中,我们添加了配置CAN2过滤器的代码,确保只接收与过滤器设置匹配的CAN帧。注意要根据实际的过滤要求来配置filterConfig
结构体的相关参数。
在主函数的第一个while
循环中,我们等待CAN2接收到第17个CAN帧,以保证CAN1发送的数据被正确接收。一旦接收到足够的CAN
最近一个项目用到CAN总线通信,由于在硬件画板是没有考虑到STM32F407芯片CAN1和CAN2的区别,在电路板上只使用了CAN2接口,在调试时,CAN2总线通信失败,通过网上查找资料,及查看官方代码例程,解决了CAN2通信问题。CAN2可以
CAN_Mode_Normal模式下通信,发送使用查询,接收使用中断。