之前项目中,一直用的MB(message buffer)结构和中断方式来接收总线CAN 报文。总线负载率和MCU负载不高的情况下,能够正常接收报文。
总线报文复杂的时候,可以利用CAN-FIFO和硬件过滤来提高MCU接收报文能力和性能。
先理解三个概念:
1)筛选ID;2)掩码;3)FIFO接收
筛选ID:用大白话来讲:就是总线上当前节点接收其他节点ID的范围;
掩码:利用掩码从硬件上过滤当前节点不需要的报文。此处还可以继续分为私有掩码和全局掩码,私有掩码针对单个MB结构来设置滤波,全局掩码可以针对所有MB结构来设置滤波。掩码设置1表示当前bit保持一致,设置0表示当前bit无需保持一致。相比于筛选ID,掩码设置更重要。
FIFO接收:当前CAN处理器在同一时间能够接收多帧报文存放在MB的结构中,存放和读取的顺序按照fifo规则。
此处示例代码:扩展帧,筛选ID=0x12345678,掩码=0x1fffffff,此时只能接收0x12345678的报文。
//can初始化 FLEXCAN_DRV_Init(INST_CANCOM1, &canCom1_State, &canCom1_InitConfig0); flexcan_id_table_t canidtable[8]; for(uint8_t i=0;i<8;i++) { canidtable[i].isExtendedFrame = true; canidtable[i].isRemoteFrame = false; canidtable[i].id = 0x12345678; } FLEXCAN_DRV_ConfigRxFifo(INST_CANCOM1,FLEXCAN_RX_FIFO_ID_FORMAT_A,canidtable); /*私有掩码设置*/ /* FLEXCAN_DRV_SetRxMaskType(INST_CANCOM1,FLEXCAN_RX_MASK_INDIVIDUAL); for(uint8_t id_index=0;id_index<8;id_index++) { FLEXCAN_DRV_SetRxIndividualMask(INST_CANCOM1,FLEXCAN_MSG_ID_STD,id_index,0xc0000000|0x7ff); }*/ /*全局掩码设置*/ FLEXCAN_DRV_SetRxMaskType(INST_CANCOM1,FLEXCAN_RX_MASK_GLOBAL); FLEXCAN_DRV_SetRxFifoGlobalMask(INST_CANCOM1,FLEXCAN_MSG_ID_EXT,0x1fffffff); //注册中断事件 FLEXCAN_DRV_InstallEventCallback(INST_CANCOM1,canRxCallback,NULL); FLEXCAN_DRV_RxFifo(INST_CANCOM1,&can_recmsg); // CAN发送时要使用到的 标准帧 8byte 数据帧 flexcan_data_info_t can1_data_std_info = { .msg_id_type = FLEXCAN_MSG_ID_EXT, .data_length = 8U, .is_remote = false }; FLEXCAN_DRV_ConfigTxMb(INST_CANCOM1,10,&can1_data_std_info,0x111); uint8_t Tx[8] = {0,0x1,0x2,0x3,0x4,0x5,0x6,0x7}; // 通过 CAN0 邮箱10 以默认配置 发送 ID是0x111 数据为0,0x1,0x2,0x3,0x4,0x5,0x6,0x7的报文 FLEXCAN_DRV_Send(INST_CANCOM1, 10, &can1_data_std_info, 0x111, Tx);
测试结果,0x12345678报文可以接收,但是其他ID都接收不了。