基于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

基于S32K144 CAN总线功能开发详解_第1张图片

基于S32K144 CAN总线功能开发详解_第2张图片

–>Clock Configuration

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

–>Configure Flexcan

基于S32K144 CAN总线功能开发详解_第3张图片
基于S32K144 CAN总线功能开发详解_第4张图片
基于S32K144 CAN总线功能开发详解_第5张图片
基于S32K144 CAN总线功能开发详解_第6张图片
基于S32K144 CAN总线功能开发详解_第7张图片

代码部分我主要说初始化、发送、接收,其他的部分(例如时钟、主任务、收发器设置等等)的就不细叙了;
首先是初始化部分:
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那种,有时间再补充吧。。

你可能感兴趣的:(基于S32K144 CAN总线功能开发详解)