基于S32K144 CAN总线功能开发详解

最近换了一份工作,初次接触NXP S32K144 MCU,刚好负责开发CAN协议栈及应用功能的开发,开发过程遇到过一些问题,网上资料也不是那么全,于是自己总结了一下自己的开发经验,希望对初次接触的小白有一些帮助,也希望大家多多提出问题。

关于S32K144

S32K144 MCU支持三路CAN,CAN0,CAN1,CAN2。CAN0有32个邮箱,CAN1和CAN2有16个邮箱,NXP系列开发有一个好处是底层的驱动接口都是可以在S32Design Studio中配置,我此次开发基于的是3.0版本的SDK。

S32K144 FLEXCAN Lab Configuration
–>CAN0 TX/RX pins

在这里插入图片描述

在这里插入图片描述

–>Clock Configuration

时钟部分根据实际情况来配置,一般具体到应用项目上用的都是外部晶振

–>Configure Flexcan

在这里插入图片描述
在这里插入图片描述
这里是CAN的属性配置
设置参数
在这里插入图片描述

代码部分我主要说初始化、发送、接收,其他的部分(例如时钟、主任务、收发器设置等等)的就不细叙了;
首先是初始化部分:
static flexcan_id_table_t Can0_ID_filter_table;
flexcan_msgbuff_t CanRxPduInfo;
uint32_t Can0_Rx_Id[kCanNumberOfRxObjects] =
{
    0x123,
    0x456,
    0x578
};
static void Can0Init(void)
{
  uint8 i;
  FLEXCAN_DRV_Init(INST_CANCOM0,&canCom0_State,canCom0_InitConfig0);
  FLEXCAN_DRV_InstallEventCallback(INST_CANCOM0,CanCallback,NULL);
  for(i = 0;i<kCanNumberOfRx;i++)
  {
    Can0_ID_filter_table[i].isExtendedFrame = false;
    Can0_ID_filter_table[i].isRemoteFrame = false;
    Can0_ID_filter_table[i].id = Can0_Rx_Id[i];
  }
  FLEXCAN_DRV_ConfigRxFifo(INST_CANCOM0,FLEXCAN_RX_FIFO_ID_FORMAT_A,&Can0_ID_filter_table);
  FLEXCAN_DRV_SetRxMaskType(INST_CANCOM0,FLEXCAN_RX_MASK_INDIVIDUAL);
  FLEXCAN_DRV_RxFifo(INST_CANCOM0,&CanRxPduInfo);
}

FLEXCAN_DRV_Init():初始化CAN配置,注意一定要放在最前面;
FLEXCAN_DRV_InstallEventCallback():加载CallBack函数,在中断ISR最后被调用;
FLEXCAN_DRV_InstallEventCallback():加载CallBack函数,在中断ISR最后被调用;
Can0_ID_filter_table:里面填的是需要过滤的ID;
FLEXCAN_DRV_SetRxMaskType:我这里是使能Individual Mask,我不要设置范围性的过滤;
FLEXCAN_DRV_RxFifo();此函数接收数据,还有一个很重要的处理是Enable MB 中断,后面在CallBack函数中每次都会调用这个来使能中断;

Callback函数
static void CanCallback(uint8 instance,flexcan_event_type_t event,uint32 buffIdx,flexcan_state_t *flexcanState)
{
  switch(eventType)
  {
    case FLEXCAN_EVENT_RX_COMPLETE:
        FLEXCAN_DRV_Receive(instance,buffIdx,&CanRxPduInfo);
        CanMsgReceived();
        break;
    case FLEXCAN_EVENT_TX_COMPLETE:
        FLEXCAN_DRV_RxFifo(instance,&CanRxPduInfo);
        CanInterruptTx(instance);
        break;
    case FLEXCAN_EVENT_RXFIFO_COMPLETE:
        FLEXCAN_DRV_RxFifo(instance,&CanRxPduInfo);
        CanMsgReceived(instance);
        break;
    default:
        break;
  }
}

CallBack函数是每次进中断会执行;
instance:CAN 通道类型
event: 中断事件类型,比如接收中断、队列接收中断、发送完成中断等等;
buffIdx:中断进入的邮箱号;

报文发送

发送报文需要先配置发送邮箱,然后调用发送接口
注意邮箱的选择,我使能了RXFIFO,所以MB0~MB7不能用

FLEXCAN_DRV_ConfigTxMb(channel,mailbox,&dataInfo,messageid);
FLEXCAN_DRV_Send(channel,mailbox,&dataInfo,messageid,);

暂时就写这么多,我觉得还有很多东西可以细写的,例如协议栈的整体框架,类似Autosar那种,有时间再补充吧。。

  • 16
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lseyer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值