S32K146-CAN fifo接收

发布时间 2023-12-21 15:14:53作者: 涛哥nihao

之前项目中,一直用的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都接收不了。