S32K144-12.flexcan fifo

本文详细介绍了FlexCAN模块的工作原理,涉及字模块的结构、消息缓冲区、私有掩码配置、ID筛选机制,以及中断处理和DMA的使用。重点讲解了如何设置私有掩码以实现精确的消息接收,并展示了接收和发送数据帧的示例代码。
摘要由CSDN通过智能技术生成

S32K146 FLEXCAN SDK解读:

FlexCAN 模块是一个通信控制器,该模块实现了 CAN 协议即CAN2.0B 协议规范。 FlexCAN 模块的字模块,包括了用来存储消息缓冲的相关联的内存区域,Rx 全局掩码寄存器、Rx 私有掩码寄存器、Rx 先进先出队列以及 Rx 队列标识过滤器。消息缓冲区存储在一个专用于 FlexCAN 模块的 RAM 区,请求存取 RAM 接收和传输消息帧,验证接收到的消息以及进行错误处理。控制器主机接口子模块用来选择接收和传输的消息缓冲区,使用仲裁与 ID 匹配算法,以建立同 CPU 或者其他模块的连接。

私有掩码则有64个,RXIMR0 - RXIMR63,对应MB0 – MB63,是一一对应的关系,所以私有掩码和对应的MB可以放到一起配置。

掩码不影响筛选表,而是与对应的ID位是否需要去和MB里面设定的预期ID对比。eg:flexcan_msgbuff_t recmsg;

当设置私有掩码时

#define CAN_ID_STD_MASK       0x1FFC0000u

0xC0000000|0x7FF ID为标准帧

 (stdMask << CAN_ID_STD_SHIFT) & CAN_ID_STD_MASK;

0xC0000000|0x7FF左移18与上0x1FFC0000还是为 0x1FFC0000

即(base->RXIMR[msgBuffIdx])为0x1FFC0000    二进制00011111111111000000000000000000

标准帧看29-19位 11111111111 也就是全关心

所以筛选id设置啥只接收啥

中断

uint8_t canrxdata[8];

flexcan_msgbuff_t recmsg;

flexcan_id_table_t canidtable[8];

void canrxcallback(uint8_t instance, flexcan_event_type_t eventType,

                                   uint32_t buffIdx, flexcan_state_t *flexcanState)

{

    // RxFIFO接收完成

          if(eventType == FLEXCAN_EVENT_RXFIFO_COMPLETE) {

        // CAN0接收

                  if(instance == INST_CANCOM1)

                  {
                          memcpy(&canrxdata, &recmsg.data, 8);

   //此函数使用 Rx FIFO 接收 CAN 帧。该函数立即返回。如果安装了回调,则在接收到帧并读入指定的缓冲区后,将调用该回调。
                          FLEXCAN_DRV_RxFifo(INST_CANCOM1, &recmsg);

                  }

          }

}





void can_fifo_init(void){

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 = 0;

        canidtable[i].isRemoteFrame = 0;

        canidtable[i].id = 0x11;

    }



    //配置RX FIFO ID过滤器表元素,并启用RX中断

    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_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);

    */

    //将RX掩码类型设置为RX全局掩码或RX单个掩码

    FLEXCAN_DRV_SetRxMaskType(INST_CANCOM1,FLEXCAN_RX_MASK_GLOBAL);

//将Rx FIFO全局掩码设置为11位标准掩码或29位扩展掩码

FLEXCAN_DRV_SetRxFifoGlobalMask(INST_CANCOM1,FLEXCAN_MSG_ID_STD,0);

FLEXCAN_DRV_InstallEventCallback(INST_CANCOM1,canrxcallback,NULL);

//此函数使用 Rx FIFO 接收 CAN 帧。该函数立即返回。如果安装了回调,则在接收到帧并读入指定的缓冲区后,将调用该回调。

FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recmsg);

}






void can_fifosend(void){

flexcan_data_info_t can_tx_data_config;

can_tx_data_config.msg_id_type = FLEXCAN_MSG_ID_STD;

//8字节数据帧

can_tx_data_config.data_length = 8;

can_tx_data_config.is_remote = 0;

//不使能自动波特率

can_tx_data_config.enable_brs = 0;

//                  CAN      邮箱       配置           发送ID  数据

FLEXCAN_DRV_Send(INST_CANCOM1,2,&can_tx_data_config,0x1,canrxdata);

}

DMA的代码和中断一样

只要配置DMA通道和初始化

代码中会自动调用

  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
以下是S32K144-EVB开发板CAN实例代码,供参考: ```c #include "S32K144.h" #define CAN0_TX_PIN 16U /* PTC16 */ #define CAN0_RX_PIN 17U /* PTC17 */ void CAN0_Init(void) { /* Enable the clock to the module */ PCC->PCCn[PCC_PORTC_INDEX] |= PCC_PCCn_CGC_MASK; PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK; /* Configure the pins for CAN0 */ PORTC->PCR[CAN0_TX_PIN] &= ~PORT_PCR_MUX_MASK; PORTC->PCR[CAN0_TX_PIN] |= PORT_PCR_MUX(2); PORTC->PCR[CAN0_RX_PIN] &= ~PORT_PCR_MUX_MASK; PORTC->PCR[CAN0_RX_PIN] |= PORT_PCR_MUX(2); /* Reset the module */ FLEXCAN0->MCR |= FLEXCAN_MCR_SOFTRST_MASK; while (FLEXCAN0->MCR & FLEXCAN_MCR_SOFTRST_MASK); /* Configure the module */ FLEXCAN0->MCR |= FLEXCAN_MCR_FRZ_MASK; FLEXCAN0->MCR |= FLEXCAN_MCR_MDIS_MASK; FLEXCAN0->CTRL1 |= FLEXCAN_CTRL1_CLKSRC_MASK; FLEXCAN0->CTRL1 |= FLEXCAN_CTRL1_PRESDIV(0x01); FLEXCAN0->CTRL1 &= ~FLEXCAN_CTRL1_LBUF_MASK; FLEXCAN0->MCR &= ~FLEXCAN_MCR_MDIS_MASK; while (FLEXCAN0->MCR & FLEXCAN_MCR_LPMACK_MASK); while (!(FLEXCAN0->MCR & FLEXCAN_MCR_FRZACK_MASK)); FLEXCAN0->MCR &= ~FLEXCAN_MCR_FRZ_MASK; /* Configure the mailbox */ FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_IDE_MASK; FLEXCAN0->MB[0].ID |= FLEXCAN_MB_ID_IDSTD(0x123); FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_RTR_MASK; FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_DLC(8); FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); } void CAN0_Send(uint8_t *data) { uint32_t i; /* Copy data to mailbox */ for (i = 0; i < 8; i++) { FLEXCAN0->MB[0].DATA[i] = data[i]; } /* Send the message */ FLEXCAN0->MB[0].CS &= ~FLEXCAN_MB_CS_CODE_MASK; FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE); } int main(void) { uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; CAN0_Init(); CAN0_Send(data); return 0; } ``` 注意,以上代码仅供参考,具体实现需要根据实际情况进行修改。例如,需要根据实际需求设置CAN的波特率、ID等参数。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YELL.DOLL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值