一种带缓存DSP28335 CAN程序

一、概述

在嵌入式系统中,CAN(控制器局域网络)是一种常用的通信协议。然而,为了保证数据的稳定传输和处理效率,我们需要设计一种高效的CAN驱动程序。本文将介绍一种基于DSP28335的带缓存CAN驱动程序设计,该设计主要分为三层:CHAL层、BSP层和应用层。

  1. CHAL层:

CHAL层是CAN驱动的底层实现,主要负责CAN的读写操作。这一层直接与硬件交互,实现对CAN控制器的配置和数据的发送接收。通过精细的硬件控制,确保数据的准确传输。

  1. BSP层:

BSP层位于CHAL层之上,主要负责CAN数据的发送和接收处理。在这一层,我们设计了两个CAN数据帧缓存,分别用于存储待发送和已接收的数据。

BSP层包含一个周期调用函数,每隔200us调用一次。这个函数的主要任务是将发送缓存中的数据装入CAN控制器进行发送,并从CAN控制器读取接收到的数据放入接收缓存。值得注意的是,我们的设计中,CAN本身并不产生中断,而是通过周期调用函数来处理数据的发送和接收。

为了提高数据的发送和接收效率,我们在BSP层采用了2到3个缓冲箱来进行数据的发送和接收。这样可以在一定程度上并行处理数据,提高系统的吞吐量。

  1. 应用层:

应用层是最高层,主要负责处理接收缓存中的数据和将待发送的数据加入发送缓存。只要缓存大小设置得当,且数据的处理及时,就可以保证CAN数据不会丢帧,同时也不需要频繁进入中断,从而保持CPU运行的节拍稳定。

二、关键代码

以下是一个简易的canopen master 帧过滤的程序 ,工程采用面向对象思想,模仿C++的类编写程序,关键初始化程序,应用程序通过回调调用 gCanFunc.TxData, gCanFunc.RxData这两个收发接口处理数据,原工程是一个控制伺服驱动的demo程序,伺服驱动器是标准的canopen协议。后续可将工程绑定在资源。

    gBSP.Create();
    gBSP.cpu->Init(150000000);
    gCanFunc.Init(500);

200us 中断及时处理can数据,应用层可以1ms或者几ms调用一次,根据实际工程情况和需求。

interrupt void cpu_timer2_isr(void)
{
       gCanFunc.Period();
     PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}

CHAL层驱动代码:

#include "CHAL.h"                          // DSP2833x Examples Include File
#include "TMS320F28335/DSP2833x_Device.h"  // DSP2833x Headerfile Include File

void InitECana(uint32_t baudRate)
{
    //
    // Create a shadow register structure for the CAN control registers. This
    // is needed, since only 32-bit access is allowed to these registers.
    // 16-bit access to these registers could potentially corrupt the register
    // contents or return false data. This is especially true while writing
    // to/reading from a bit (or group of bits) among bits 16 - 31
    //
    struct ECAN_REGS ECanaShadow;

    EALLOW;                                  // EALLOW enables access to protected bits
    SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 1;  // eCAN-A
    //
    // Configure eCAN RX and TX pins for CAN operation using eCAN regs
    //
    ECanaShadow.CANTIOC.all        = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANOPC.all         = ECanaRegs.CANOPC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all          = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all        = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;
    ECanaRegs.CANRIOC.all          = ECanaShadow.CANRIOC.all;

    //
    // Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31)
    // HECC mode also enables time-stamping feature
    //
    ECanaShadow.CANMC.all     = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.SCB = 1;
    ECanaRegs.CANMC.all       = ECanaShadow.CANMC.all;

    //
    // Initialize all bits of 'Master Control Field' to zero
    // Some bits of MSGCTRL register come up in an unknown state. For proper
    // operation, all bits (including reserved bits) of MSGCTRL must be
    // initialized to zero
    //
    ECanaMboxes.MBOX0.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX1.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all  = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;

    //
    // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
    // as a matter of precaution.
    //
    ECanaRegs.CANTA.all = 0xFFFFFFFF;  // Clear all TAn bits

    ECanaRegs.CANRMP.all = 0xFFFFFFFF;  // Clear all RMPn bits

    ECanaRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bits
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

    //
    // Configure bit timing parameters for eCANA
    //
    ECanaShadow.CANMC.all     = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1;  // Set CCR = 1
    ECanaShadow.CANMC.bit.DBO = 1;  // DATA order
    ECanaRegs.CANMC.all       = ECanaShadow.CANMC.all;

    ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
    {
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while (ECanaShadow.CANES.bit.CCE != 1);  // Wait for CCE bit to be set

    ECanaShadow.CANBTC.all = 0;

    //
    // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h
    //
    //
    // The following block for all 150 MHz SYSCLKOUT
    // (75 MHz CAN clock) - default. Bit rate = 1 Mbps See Note at End of File
    //
    ECanaShadow.CANBTC.bit.BRPREG   = (SYS_MAIN_FREQ / (30 * baudRate)) - 1;
    ECanaShadow.CANBTC.bit.TSEG2REG = 2;
    ECanaShadow.CANBTC.bit.TSEG1REG = 10;

    ECanaShadow.CANBTC.bit.SAM = 1;
    ECanaRegs.CANBTC.all       = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all     = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0;  // Set CCR = 0
    ECanaRegs.CANMC.all       = ECanaShadow.CANMC.all;

    ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
    {
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while (ECanaShadow.CANES.bit.CCE != 0);  // Wait for CCE bit to be  cleared

    //
    // Disable all Mailboxes
    //
    ECanaRegs.CANME.all = 0;  // Required before writing the MSGIDs

    /* 设置接收寄存器  0,1,2 接收*/
    //   struct ECAN_REGS ECanaShadow;

    ECanaShadow.CANMD.all       = ECanaRegs.CANMD.all;
    ECanaShadow.CANME.all       = ECanaRegs.CANME.all;
    ECanaShadow.CANOPC.bit.OPC0 = 1;  // 读前原数据不可被覆盖 需要被读出后再接收新的数据
    ECanaShadow.CANOPC.bit.OPC1 = 1;  // 读前原数据不可被覆盖 需要被读出后再接收新的数据
    ECanaShadow.CANOPC.bit.OPC2 = 1;  // 读前原数据不可被覆盖 需要被读出后再接收新的数据

    ECanaShadow.CANME.bit.ME0 = 0; /* Enable Mailbox under test */
    ECanaMboxes.MBOX0.MSGID.all       = 0;          // Set ID
    ECanaMboxes.MBOX0.MSGID.bit.AME   = 1;          // Set ID
    ECanaShadow.CANMD.bit.MD0         = 1;          /* Configure Mailbox Rx */
    ECanaShadow.CANME.bit.ME0         = 1;          /* Enable Mailbox under test */
    ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanaMboxes.MBOX0.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanaMboxes.MBOX0.MDH.all         = 0x55555555;
    ECanaLAMRegs.LAM0.bit.LAMI        = 1;
    ECanaLAMRegs.LAM0.bit.LAM_H       = 0x1fff;  //屏蔽位 接收所有标准帧
    ECanaLAMRegs.LAM0.bit.LAM_L       = 0x0;

    ECanaShadow.CANME.bit.ME1 = 0; /* Enable Mailbox under test */
    ECanaMboxes.MBOX1.MSGID.all       = 0;          // Set ID
    ECanaMboxes.MBOX1.MSGID.bit.AME   = 1;          // Set ID
    ECanaShadow.CANMD.bit.MD1         = 1;          /* Configure Mailbox Rx */
    ECanaShadow.CANME.bit.ME1         = 1;          /* Enable Mailbox under test */
    ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanaMboxes.MBOX1.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanaMboxes.MBOX1.MDH.all         = 0x55555555;
    ECanaLAMRegs.LAM1.bit.LAMI        = 1;
    ECanaLAMRegs.LAM1.bit.LAM_H       = 0x1fff;  //屏蔽位 接收所有标准帧
    ECanaLAMRegs.LAM1.bit.LAM_L       = 0x0;

    ECanaShadow.CANME.bit.ME2 = 0; /* Enable Mailbox under test */
    ECanaMboxes.MBOX2.MSGID.all       = 0;          // Set ID
    ECanaMboxes.MBOX2.MSGID.bit.AME   = 1;          // Set ID
    ECanaShadow.CANMD.bit.MD2         = 1;          /* Configure Mailbox Rx */
    ECanaShadow.CANME.bit.ME2         = 1;          /* Enable Mailbox under test */
    ECanaMboxes.MBOX2.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanaMboxes.MBOX2.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanaMboxes.MBOX2.MDH.all         = 0x55555555;
    ECanaLAMRegs.LAM2.bit.LAMI        = 1;
    ECanaLAMRegs.LAM2.bit.LAM_H       = 0x1fff;  //屏蔽位 接收所有标准帧
    ECanaLAMRegs.LAM2.bit.LAM_L       = 0x0;

    ECanaRegs.CANMD.all  = ECanaShadow.CANMD.all;
    ECanaRegs.CANME.all  = ECanaShadow.CANME.all;
    ECanaRegs.CANOPC.all = ECanaShadow.CANOPC.all;

    EDIS;
}

void InitECanb(uint32_t baudRate)
{
    //
    // Create a shadow register structure for the CAN control registers. This
    // is needed, since only 32-bit access is allowed to these registers.
    // 16-bit access to these registers could potentially corrupt the register
    // contents or return false data. This is especially true while writing
    // to/reading from a bit (or group of bits) among bits 16 - 31
    //
    struct ECAN_REGS ECanbShadow;

    EALLOW;                                  // EALLOW enables access to protected bits
    SysCtrlRegs.PCLKCR0.bit.ECANBENCLK = 1;  // eCAN-B
    //
    // Configure eCAN RX and TX pins for CAN operation using eCAN regs
    //
    ECanbShadow.CANTIOC.all        = ECanbRegs.CANTIOC.all;
    ECanbShadow.CANTIOC.bit.TXFUNC = 1;
    ECanbRegs.CANTIOC.all          = ECanbShadow.CANTIOC.all;

    ECanbShadow.CANRIOC.all        = ECanbRegs.CANRIOC.all;
    ECanbShadow.CANRIOC.bit.RXFUNC = 1;
    ECanbRegs.CANRIOC.all          = ECanbShadow.CANRIOC.all;

    //
    // Configure eCAN for HECC mode - (read to access mailboxes 16 thru 31)
    //
    ECanbShadow.CANMC.all     = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.SCB = 1;
    ECanbRegs.CANMC.all       = ECanbShadow.CANMC.all;

    //
    // Initialize all bits of 'Master Control Field' to zero
    // Some bits of MSGCTRL register come up in an unknown state. For proper
    // operation, all bits (including reserved bits) of MSGCTRL must be
    // initialized to zero
    //
    ECanbMboxes.MBOX0.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX1.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX2.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX3.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX4.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX5.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX6.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX7.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX8.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX9.MSGCTRL.all  = 0x00000000;
    ECanbMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanbMboxes.MBOX31.MSGCTRL.all = 0x00000000;

    //
    // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
    // as a matter of precaution.
    //
    ECanbRegs.CANTA.all = 0xFFFFFFFF;  // Clear all TAn bits

    ECanbRegs.CANRMP.all = 0xFFFFFFFF;  // Clear all RMPn bits

    ECanbRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bits
    ECanbRegs.CANGIF1.all = 0xFFFFFFFF;

    //
    // Configure bit timing parameters for eCANB
    //
    ECanbShadow.CANMC.all     = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.CCR = 1;  // Set CCR = 1
    ECanbShadow.CANMC.bit.DBO = 1;  // DATA order
    ECanbRegs.CANMC.all       = ECanbShadow.CANMC.all;

    ECanbShadow.CANES.all = ECanbRegs.CANES.all;

    do
    {
        ECanbShadow.CANES.all = ECanbRegs.CANES.all;
    } while (ECanbShadow.CANES.bit.CCE != 1);  // Wait for CCE bit to be  cleared

    ECanbShadow.CANBTC.all = 0;

    //
    // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h
    //
    //
    // The following block for all 150 MHz SYSCLKOUT
    // (75 MHz CAN clock) - default. Bit rate = 1 Mbps See Note at end of file
    //
    ECanbShadow.CANBTC.bit.BRPREG   = (SYS_MAIN_FREQ / (30 * baudRate)) - 1;
    ECanbShadow.CANBTC.bit.TSEG2REG = 2;
    ECanbShadow.CANBTC.bit.TSEG1REG = 10;

    ECanbShadow.CANBTC.bit.SAM = 1;
    ECanbRegs.CANBTC.all       = ECanbShadow.CANBTC.all;

    ECanbShadow.CANMC.all     = ECanbRegs.CANMC.all;
    ECanbShadow.CANMC.bit.CCR = 0;  // Set CCR = 0
    ECanbRegs.CANMC.all       = ECanbShadow.CANMC.all;

    ECanbShadow.CANES.all = ECanbRegs.CANES.all;

    do
    {
        ECanbShadow.CANES.all = ECanbRegs.CANES.all;
    } while (ECanbShadow.CANES.bit.CCE != 0);  // Wait for CCE bit to be  cleared

    //
    // Disable all Mailboxes
    //
    ECanbRegs.CANME.all = 0;  // Required before writing the MSGIDs

    /* 设置接收寄存器  0,1,2 接收*/
    //   struct ECAN_REGS ECanbShadow;

    ECanbShadow.CANMD.all       = ECanbRegs.CANMD.all;
    ECanbShadow.CANME.all       = ECanbRegs.CANME.all;
    ECanbShadow.CANOPC.bit.OPC0 = 1;  // 读前原数据不可被覆盖 需要被读出后再接收新的数据
    ECanbShadow.CANOPC.bit.OPC1 = 1;  // 读前原数据不可被覆盖 需要被读出后再接收新的数据
    ECanbShadow.CANOPC.bit.OPC2 = 1;  // 读前原数据不可被覆盖 需要被读出后再接收新的数据

    ECanbShadow.CANME.bit.ME0 = 0; /* Enable Mailbox under test */
    ECanbMboxes.MBOX0.MSGID.all       = 0;          // Set ID
    ECanbMboxes.MBOX0.MSGID.bit.AME   = 1;          // Set ID
    ECanbShadow.CANMD.bit.MD0         = 1;          /* Configure Mailbox Rx */
    ECanbShadow.CANME.bit.ME0         = 1;          /* Enable Mailbox under test */
    ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanbMboxes.MBOX0.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanbMboxes.MBOX0.MDH.all         = 0x55555555;
    ECanbLAMRegs.LAM0.bit.LAMI        = 1;
    ECanbLAMRegs.LAM0.bit.LAM_H       = 0x1fff;  //屏蔽位 接收所有标准帧
    ECanbLAMRegs.LAM0.bit.LAM_L       = 0x0;

    ECanbShadow.CANME.bit.ME1 = 0; /* Enable Mailbox under test */
    ECanbMboxes.MBOX1.MSGID.all       = 0;          // Set ID
    ECanbMboxes.MBOX1.MSGID.bit.AME   = 1;          // Set ID
    ECanbShadow.CANMD.bit.MD1         = 1;          /* Configure Mailbox Rx */
    ECanbShadow.CANME.bit.ME1         = 1;          /* Enable Mailbox under test */
    ECanbMboxes.MBOX1.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanbMboxes.MBOX1.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanbMboxes.MBOX1.MDH.all         = 0x55555555;
    ECanbLAMRegs.LAM1.bit.LAMI        = 1;
    ECanbLAMRegs.LAM1.bit.LAM_H       = 0x1fff;  //屏蔽位 接收所有标准帧
    ECanbLAMRegs.LAM1.bit.LAM_L       = 0x0;

    ECanbShadow.CANME.bit.ME2 = 0; /* Enable Mailbox under test */
    ECanbMboxes.MBOX2.MSGID.all       = 0;          // Set ID
    ECanbMboxes.MBOX2.MSGID.bit.AME   = 1;          // Set ID
    ECanbShadow.CANMD.bit.MD2         = 1;          /* Configure Mailbox Rx */
    ECanbShadow.CANME.bit.ME2         = 1;          /* Enable Mailbox under test */
    ECanbMboxes.MBOX2.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanbMboxes.MBOX2.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanbMboxes.MBOX2.MDH.all         = 0x55555555;
    ECanbLAMRegs.LAM2.bit.LAMI        = 1;
    ECanbLAMRegs.LAM2.bit.LAM_H       = 0x1fff;  //屏蔽位 接收所有标准帧
    ECanbLAMRegs.LAM2.bit.LAM_L       = 0x0;

    ECanbShadow.CANME.bit.ME16 = 0; /* Enable Mailbox under test */
    ECanbMboxes.MBOX16.MSGID.all       = 0;  // Set ID
    ECanbShadow.CANMD.bit.MD16         = 0;  /* Configure Mailbox Rx */
    ECanbShadow.CANME.bit.ME16         = 1;
    ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanbMboxes.MBOX16.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanbMboxes.MBOX16.MDH.all         = 0x55555555;

    ECanbShadow.CANME.bit.ME17 = 0; /* Enable Mailbox under test */
    ECanbMboxes.MBOX17.MSGID.all       = 0;  // Set ID
    ECanbShadow.CANMD.bit.MD17         = 0;  /* Configure Mailbox Rx */
    ECanbShadow.CANME.bit.ME17         = 1;
    ECanbMboxes.MBOX17.MSGCTRL.bit.DLC = 8;          /* Write to DLC field in Master Control reg */
    ECanbMboxes.MBOX17.MDL.all         = 0x55555555; /* Write to the mailbox RAM field */
    ECanbMboxes.MBOX17.MDH.all         = 0x55555555;

    ECanbRegs.CANMD.all  = ECanbShadow.CANMD.all;
    ECanbRegs.CANME.all  = ECanbShadow.CANME.all;
    ECanbRegs.CANOPC.all = ECanbShadow.CANOPC.all;

    EDIS;
}

uint8_t CHAL_Can0Rx(stc_can_rx_frame_t *canMsg)
{
    uint8_t ret           = 0;
    static uint32_t times = 0;
    uint32_t redata[2];
    struct ECAN_REGS ECanaShadow;

    ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
    ECanaShadow.CANRML.all = ECanaRegs.CANRML.all;
    ECanaShadow.CANMC.all  = ECanaRegs.CANMC.all;

    if (ECanaShadow.CANMC.bit.CCR == 1)  //瑙e喅ecan busoff 闂
    {
        times++;
        if (times > 7000)  //  /7  绾�1s
        {
            times = 0;
            EALLOW;
            ECanaShadow.CANMC.all     = ECanaRegs.CANMC.all;
            ECanaShadow.CANMC.bit.CCR = 0;  // Set CCR = 0
            ECanaRegs.CANMC.all       = ECanaShadow.CANMC.all;
            EDIS;
        }
    }
    if (ECanaShadow.CANRMP.bit.RMP2)
    {
        canMsg->au32Data[0]         = ECanaMboxes.MBOX2.MDL.all;
        canMsg->au32Data[1]         = ECanaMboxes.MBOX2.MDH.all;
        canMsg->u32Ctrl             = ECanaMboxes.MBOX2.MSGCTRL.all;
        canMsg->u32ID               = (ECanaMboxes.MBOX2.MSGID.all >> 18) & 0x7ff;
        ECanaShadow.CANRMP.all      = 0;
        ECanaShadow.CANRMP.bit.RMP2 = 1;  // clear the flag
        ret                         = 1;
    }
    else if (ECanaShadow.CANRMP.bit.RMP1)
    {
        canMsg->au32Data[0]         = ECanaMboxes.MBOX1.MDL.all;
        canMsg->au32Data[1]         = ECanaMboxes.MBOX1.MDH.all;
        canMsg->u32Ctrl             = ECanaMboxes.MBOX1.MSGCTRL.all;
        canMsg->u32ID               = (ECanaMboxes.MBOX1.MSGID.all >> 18) & 0x7ff;
        ECanaShadow.CANRMP.all      = 0;
        ECanaShadow.CANRMP.bit.RMP1 = 1;  // clear the flag
        ret                         = 1;
    }
    else if (ECanaShadow.CANRMP.bit.RMP0)
    {
        canMsg->au32Data[0]         = ECanaMboxes.MBOX0.MDL.all;
        canMsg->au32Data[1]         = ECanaMboxes.MBOX0.MDH.all;
        canMsg->u32Ctrl             = ECanaMboxes.MBOX0.MSGCTRL.all;
        canMsg->u32ID               = (ECanaMboxes.MBOX0.MSGID.all >> 18) & 0x7ff;
        ECanaShadow.CANRMP.all      = 0;
        ECanaShadow.CANRMP.bit.RMP0 = 1;  // clear the flag
        ret                         = 1;
    }

    if (ret)
    {
        ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all;
    }

    return ret;
}

/* ret 0: 发送失败  1: 发送成功 */
uint8_t CHAL_Can0Tx(stc_can_tx_frame_t *canMsg)
{
    uint8_t ret = 0;

    struct ECAN_REGS ECanaShadow;
    ECanaShadow.CANTA.all  = ECanaRegs.CANTA.all;
    ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all;
    ECanaShadow.CANME.all  = ECanaRegs.CANME.all;
    ECanaShadow.CANTA.all  = 0;

    if (ECanaShadow.CANTRS.bit.TRS16 == 0)
    {
        ECanaShadow.CANME.bit.ME16         = 0; /* Enable Mailbox under test */
        ECanaRegs.CANME.all                = ECanaShadow.CANME.all;
        ECanaMboxes.MBOX16.MSGID.all       = canMsg->u32ID << 18;
        ECanaMboxes.MBOX16.MDL.all         = canMsg->au32Data[0];
        ECanaMboxes.MBOX16.MDH.all         = canMsg->au32Data[1];
        ECanaMboxes.MBOX16.MSGCTRL.bit.DLC = canMsg->DLC;
        ECanaShadow.CANTRS.bit.TRS16       = 1;  // Set TRS for mailbox under test
        ECanaShadow.CANTA.bit.TA16         = 1;
        ECanaShadow.CANME.bit.ME16         = 1; /* Enable Mailbox under test */

        ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
        ECanaRegs.CANTA.all  = ECanaShadow.CANTA.all;
        ECanaRegs.CANME.all  = ECanaShadow.CANME.all;
        ret                  = 1;
    }
    else if (ECanaShadow.CANTRS.bit.TRS17 == 0)
    {
        ECanaShadow.CANME.bit.ME17         = 0; /* Enable Mailbox under test */
        ECanaRegs.CANME.all                = ECanaShadow.CANME.all;
        ECanaMboxes.MBOX17.MSGID.all       = canMsg->u32ID << 18;
        ECanaMboxes.MBOX17.MDL.all         = canMsg->au32Data[0];
        ECanaMboxes.MBOX17.MDH.all         = canMsg->au32Data[1];
        ECanaMboxes.MBOX17.MSGCTRL.bit.DLC = canMsg->DLC;
        ECanaMboxes.MBOX17.MSGID.all       = canMsg->u32ID << 18;
        ECanaShadow.CANTRS.bit.TRS17       = 1;  // Set TRS for mailbox under test
        ECanaShadow.CANTA.bit.TA17         = 1;
        ECanaShadow.CANME.bit.ME17         = 1; /* Enable Mailbox under test */

        ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
        ECanaRegs.CANTA.all  = ECanaShadow.CANTA.all;
        ECanaRegs.CANME.all  = ECanaShadow.CANME.all;
        ret                  = 1;
    }
    return ret;
}

uint8_t CHAL_Can1Rx(stc_can_rx_frame_t *canMsg)
{
    uint8_t ret           = 0;
    static uint32_t times = 0;
    uint32_t redata[2];
    struct ECAN_REGS ECanbShadow;

    ECanbShadow.CANRMP.all = ECanbRegs.CANRMP.all;
    ECanbShadow.CANRML.all = ECanbRegs.CANRML.all;
    ECanbShadow.CANMC.all  = ECanbRegs.CANMC.all;

    if (ECanbShadow.CANMC.bit.CCR == 1)  //瑙e喅ecan busoff 闂
    {
        times++;
        if (times > 7000)  //  /7  绾�1s
        {
            times = 0;
            EALLOW;
            ECanbShadow.CANMC.all     = ECanbRegs.CANMC.all;
            ECanbShadow.CANMC.bit.CCR = 0;  // Set CCR = 0
            ECanbRegs.CANMC.all       = ECanbShadow.CANMC.all;
            EDIS;
        }
    }
    if (ECanbShadow.CANRMP.bit.RMP2)
    {
        canMsg->au32Data[0]         = ECanbMboxes.MBOX2.MDL.all;
        canMsg->au32Data[1]         = ECanbMboxes.MBOX2.MDH.all;
        canMsg->u32Ctrl             = ECanbMboxes.MBOX2.MSGCTRL.all;
        canMsg->u32ID               = (ECanbMboxes.MBOX2.MSGID.all >> 18) & 0x7ff;
        ECanbShadow.CANRMP.all      = 0;
        ECanbShadow.CANRMP.bit.RMP2 = 1;  // clear the flag
        ret                         = 1;
    }
    else if (ECanbShadow.CANRMP.bit.RMP1)
    {
        canMsg->au32Data[0]         = ECanbMboxes.MBOX1.MDL.all;
        canMsg->au32Data[1]         = ECanbMboxes.MBOX1.MDH.all;
        canMsg->u32Ctrl             = ECanbMboxes.MBOX1.MSGCTRL.all;
        canMsg->u32ID               = (ECanbMboxes.MBOX1.MSGID.all >> 18) & 0x7ff;
        ECanbShadow.CANRMP.all      = 0;
        ECanbShadow.CANRMP.bit.RMP1 = 1;  // clear the flag
        ret                         = 1;
    }
    else if (ECanbShadow.CANRMP.bit.RMP0)
    {
        canMsg->au32Data[0]         = ECanbMboxes.MBOX0.MDL.all;
        canMsg->au32Data[1]         = ECanbMboxes.MBOX0.MDH.all;
        canMsg->u32Ctrl             = ECanbMboxes.MBOX0.MSGCTRL.all;
        canMsg->u32ID               = (ECanbMboxes.MBOX0.MSGID.all >> 18) & 0x7ff;
        ECanbShadow.CANRMP.all      = 0;
        ECanbShadow.CANRMP.bit.RMP0 = 1;  // clear the flag
        ret                         = 1;
    }

    if (ret)
    {
        ECanbRegs.CANRMP.all = ECanbShadow.CANRMP.all;
    }

    return ret;
}

/* ret 0: 发送失败  1: 发送成功 */
uint8_t CHAL_Can1Tx(stc_can_tx_frame_t *canMsg)
{
    uint8_t ret = 0;

    struct ECAN_REGS ECanbShadow;
    ECanbShadow.CANTA.all  = ECanbRegs.CANTA.all;
    ECanbShadow.CANTRS.all = ECanbRegs.CANTRS.all;
    ECanbShadow.CANME.all  = ECanbRegs.CANME.all;
    ECanbShadow.CANTA.all  = 0;

    if (ECanbShadow.CANTRS.bit.TRS16 == 0)
    {
        ECanbShadow.CANME.bit.ME16         = 0; /* Enable Mailbox under test */
        ECanbRegs.CANME.all                = ECanbShadow.CANME.all;
        ECanbMboxes.MBOX16.MSGID.all       = canMsg->u32ID << 18;
        ECanbMboxes.MBOX16.MDL.all         = canMsg->au32Data[0];
        ECanbMboxes.MBOX16.MDH.all         = canMsg->au32Data[1];
        ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = canMsg->DLC;
        ECanbShadow.CANTRS.bit.TRS16       = 1;  // Set TRS for mailbox under test
        ECanbShadow.CANTA.bit.TA16         = 1;
        ECanbShadow.CANME.bit.ME16         = 1; /* Enable Mailbox under test */

        ECanbRegs.CANTRS.all = ECanbShadow.CANTRS.all;
        ECanbRegs.CANTA.all  = ECanbShadow.CANTA.all;
        ECanbRegs.CANME.all  = ECanbShadow.CANME.all;
        ret                  = 1;
    }
    else if (ECanbShadow.CANTRS.bit.TRS17 == 0)
    {
        ECanbShadow.CANME.bit.ME17         = 0; /* Enable Mailbox under test */
        ECanbRegs.CANME.all                = ECanbShadow.CANME.all;
        ECanbMboxes.MBOX17.MSGID.all       = canMsg->u32ID << 18;
        ECanbMboxes.MBOX17.MDL.all         = canMsg->au32Data[0];
        ECanbMboxes.MBOX17.MDH.all         = canMsg->au32Data[1];
        ECanbMboxes.MBOX17.MSGCTRL.bit.DLC = canMsg->DLC;
        ECanbMboxes.MBOX17.MSGID.all       = canMsg->u32ID << 18;
        ECanbShadow.CANTRS.bit.TRS17       = 1;  // Set TRS for mailbox under test
        ECanbShadow.CANTA.bit.TA17         = 1;
        ECanbShadow.CANME.bit.ME17         = 1; /* Enable Mailbox under test */

        ECanbRegs.CANTRS.all = ECanbShadow.CANTRS.all;
        ECanbRegs.CANTA.all  = ECanbShadow.CANTA.all;
        ECanbRegs.CANME.all  = ECanbShadow.CANME.all;
        ret                  = 1;
    }
    return ret;
}

uint8_t CHAL_Can1Init(char *HIVersion, uint32_t baudRate)
{
    uint8_t ret;

    InitECanb(baudRate);
    EALLOW;

    GpioCtrlRegs.GPAPUD.bit.GPIO17   = 0;  // Enable pull-up for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAPUD.bit.GPIO16   = 0;  // Enable pull-up for GPIO31 (CANTXA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3;  // Asynch qual for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAMUX2.bit.GPIO17  = 2;  // Configure GPIO30 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO16  = 2;  // Configure GPIO31 for CANTXA operation

    // GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0;  // Enable pull-up for GPIO30 (CANRXA)
    // GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0;  // Enable pull-up for GPIO31 (CANTXA)
    // GpioCtrlRegs.GPAQSEL1.bit.GPIO10 =3;  // Asynch qual for GPIO30 (CANRXA)
    // GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 2;  // Configure GPIO30 for CANRXA operation
    // GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 2;  // Configure GPIO31 for CANTXA operation

    //  GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;  // Enable pull-up for GPIO30 (CANRXA)
    // GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0;  // Enable pull-up for GPIO31 (CANTXA)
    // GpioCtrlRegs.GPAQSEL1.bit.GPIO10 =3;  // Asynch qual for GPIO30 (CANRXA)
    // GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 2;  // Configure GPIO30 for CANRXA operation
    // GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 2;  // Configure GPIO31 for CANTXA operation

    EDIS;

    ret = 1;

    return ret;
}


uint8_t CHAL_Can0Init(char *HIVersion, uint32_t baudRate)
{
    uint8_t ret;

    InitECana(baudRate);
    EALLOW;

        EALLOW;

        GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;  // Enable pull-up for GPIO30 (CANRXA)
        GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;  // Enable pull-up for GPIO31 (CANTXA)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;  // Asynch qual for GPIO30 (CANRXA)
        GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;  // Configure GPIO30 for CANRXA operation
        GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;  // Configure GPIO31 for CANTXA operation

        EDIS;

    EDIS;

    ret = 1;

    return ret;
}

BSP层代码:

#ifndef _MCAN0_H_
#define _MCAN0_H_


#include <MQueue.h>
#include "CHAL.h"   // 

//can数据缓存

#define  CAN_BUF_LEN  20

#define M1_NODEID  (0X01)
#define M2_NODEID  (0X02)
#define M3_NODEID  (0X03)
#define M4_NODEID  (0X04)




/*修改 以下两个枚举时,必须一一对应 */
/* 需要接收的CAN帧数据 */
typedef enum
{

    M1_TPDO1 = 0X180 + M1_NODEID,
    M1_TPDO2 = 0X280 + M1_NODEID,
    M1_TPDO3 = 0X380 + M1_NODEID,
    M1_TPDO4 = 0X480 + M1_NODEID,
    M1_TSDO  = 0X580 + M1_NODEID,
    M1_HEART = 0X700 + M1_NODEID,
    M2_TPDO1 = 0X180 + M2_NODEID,
    M2_TPDO2 = 0X280 + M2_NODEID,
    M2_TPDO3 = 0X380 + M2_NODEID,
    M2_TPDO4 = 0X480 + M2_NODEID,
    M2_TSDO  = 0X580 + M2_NODEID,
    M2_HEART = 0X700 + M2_NODEID,
} CAN_ID;

/* 与以上枚举对应的 ID 通道 */
typedef enum
{

    CH_M1_TPDO1 = 0,
    CH_M1_TPDO2,
    CH_M1_TPDO3,
    CH_M1_TPDO4,
    CH_M1_TSDO,
    CH_M1_HEART,
    CH_M2_TPDO1,
    CH_M2_TPDO2,
    CH_M2_TPDO3,
    CH_M2_TPDO4,
    CH_M2_TSDO,
    CH_M2_HEART,
} CAN_ID_CH;


/* 标准帧格式数据 */
typedef struct
{
   uint8_t dlc;  //帧数据长度	
   uint32_t dword[2];

} CanData;

typedef struct
{
    CanData rbuf[CAN_RX_CH_NUM][CAN_BUF_LEN];
    struct MQueue rq[CAN_RX_CH_NUM];

    stc_can_tx_frame_t txBuf[CAN_BUF_LEN];
    struct MQueue tq;

} MCan_Prop;

typedef struct
{
    void (*Init)(uint32_t baudRate_kHz);

    uint8_t (*RxData)(int8_t ch,uint8_t *dlc, uint32_t *data);
    uint8_t (*TxData)(uint32_t txId,uint8_t dlc, uint32_t *data);
    void (*Period)(void);

} MCan_Func;


extern const MCan_Func gCanFunc;

#endif

#include "MCan0.h"

MCan_Prop gCan0;




uint8_t CHAL_Can0Init(char *HIVersion, uint32_t baudRate);

extern uint8_t CHAL_Can0Rx(stc_can_rx_frame_t *canMsg);
extern  uint8_t CHAL_Can0Tx(stc_can_rx_frame_t *canMsg);

static void Init(uint32_t baudRate_kHz)
{


    int i = 0;

    // CHAL_Can0Init(baudRate_kHz * 1000, RxPeriod);

    // //    // CHAL_Can0RxIdSet(0 , 0 , 0 , 0x7FF);      //stadnrd fram
    // // CHAL_Can0RxIdSet(0, 1, 0, 0x10000000);  // extend fram
    // CHAL_Can0RxIdSetAll(0, 0x1FFFFFFF);
    // F460_GPIOInitForLed();
    CHAL_Can0Init("0",baudRate_kHz * 1000);
    for (i = 0; i < CAN_RX_CH_NUM; i++)
    {
        MQueue(&gCan0.rq[i], CAN_BUF_LEN);
    }
    MQueue(&gCan0.tq, CAN_BUF_LEN);
}

static void canRxData(stc_can_rx_frame_t *rxMsg)
{
    switch (rxMsg->u32ID)
    {
        case M1_TPDO1:
            if (gCan0.rq[CH_M1_TPDO1].deepMax - gCan0.rq[CH_M1_TPDO1].deep)
            {
                memcpy(gCan0.rbuf[CH_M1_TPDO1][gCan0.rq[CH_M1_TPDO1].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M1_TPDO1][gCan0.rq[CH_M1_TPDO1].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M1_TPDO1].Add(&gCan0.rq[CH_M1_TPDO1]);
            }
            break;
        case M1_TPDO2:
            if (gCan0.rq[CH_M1_TPDO2].deepMax - gCan0.rq[CH_M1_TPDO2].deep)
            {
                memcpy(gCan0.rbuf[CH_M1_TPDO2][gCan0.rq[CH_M1_TPDO2].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M1_TPDO2][gCan0.rq[CH_M1_TPDO2].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M1_TPDO2].Add(&gCan0.rq[CH_M1_TPDO2]);
            }
            break;
        case M1_TPDO3:
            if (gCan0.rq[CH_M1_TPDO3].deepMax - gCan0.rq[CH_M1_TPDO3].deep)
            {
                memcpy(gCan0.rbuf[CH_M1_TPDO3][gCan0.rq[CH_M1_TPDO3].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M1_TPDO3][gCan0.rq[CH_M1_TPDO3].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M1_TPDO3].Add(&gCan0.rq[CH_M1_TPDO3]);
            }
            break;
        case M1_TPDO4:
            if (gCan0.rq[CH_M1_TPDO4].deepMax - gCan0.rq[CH_M1_TPDO4].deep)
            {
                memcpy(gCan0.rbuf[CH_M1_TPDO4][gCan0.rq[CH_M1_TPDO4].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M1_TPDO4][gCan0.rq[CH_M1_TPDO4].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M1_TPDO4].Add(&gCan0.rq[CH_M1_TPDO4]);
            }
            break;
        case M1_TSDO:
            if (gCan0.rq[CH_M1_TSDO].deepMax - gCan0.rq[CH_M1_TSDO].deep)
            {
                memcpy(gCan0.rbuf[CH_M1_TSDO][gCan0.rq[CH_M1_TSDO].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M1_TSDO][gCan0.rq[CH_M1_TSDO].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M1_TSDO].Add(&gCan0.rq[CH_M1_TSDO]);
            }
            break;
        case M1_HEART:
            if (gCan0.rq[CH_M1_HEART].deepMax - gCan0.rq[CH_M1_HEART].deep)
            {
                memcpy(gCan0.rbuf[CH_M1_HEART][gCan0.rq[CH_M1_HEART].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M1_HEART][gCan0.rq[CH_M1_HEART].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M1_HEART].Add(&gCan0.rq[CH_M1_HEART]);
            }
            break;
        case M2_TPDO1:
            if (gCan0.rq[CH_M2_TPDO1].deepMax - gCan0.rq[CH_M2_TPDO1].deep)
            {
                memcpy(gCan0.rbuf[CH_M2_TPDO1][gCan0.rq[CH_M2_TPDO1].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M2_TPDO1][gCan0.rq[CH_M2_TPDO1].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M2_TPDO1].Add(&gCan0.rq[CH_M2_TPDO1]);
            }
            break;
        case M2_TPDO2:
            if (gCan0.rq[CH_M2_TPDO2].deepMax - gCan0.rq[CH_M2_TPDO2].deep)
            {
                memcpy(gCan0.rbuf[CH_M2_TPDO2][gCan0.rq[CH_M2_TPDO2].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M2_TPDO2][gCan0.rq[CH_M2_TPDO2].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M2_TPDO2].Add(&gCan0.rq[CH_M2_TPDO2]);
            }
            break;
        case M2_TPDO3:
            if (gCan0.rq[CH_M2_TPDO3].deepMax - gCan0.rq[CH_M2_TPDO3].deep)
            {
                memcpy(gCan0.rbuf[CH_M2_TPDO3][gCan0.rq[CH_M2_TPDO3].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M2_TPDO3][gCan0.rq[CH_M2_TPDO3].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M2_TPDO3].Add(&gCan0.rq[CH_M2_TPDO3]);
            }
            break;
        case M2_TPDO4:
            if (gCan0.rq[CH_M2_TPDO4].deepMax - gCan0.rq[CH_M2_TPDO4].deep)
            {
                memcpy(gCan0.rbuf[CH_M2_TPDO4][gCan0.rq[CH_M2_TPDO4].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M2_TPDO4][gCan0.rq[CH_M2_TPDO4].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M2_TPDO4].Add(&gCan0.rq[CH_M2_TPDO4]);
            }
            break;
        case M2_TSDO:
            if (gCan0.rq[CH_M2_TSDO].deepMax - gCan0.rq[CH_M2_TSDO].deep)
            {
                memcpy(gCan0.rbuf[CH_M2_TSDO][gCan0.rq[CH_M2_TSDO].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M2_TSDO][gCan0.rq[CH_M2_TSDO].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M2_TSDO].Add(&gCan0.rq[CH_M2_TSDO]);
            }
            break;
        case M2_HEART:
            if (gCan0.rq[CH_M2_HEART].deepMax - gCan0.rq[CH_M2_HEART].deep)
            {
                memcpy(gCan0.rbuf[CH_M2_HEART][gCan0.rq[CH_M2_HEART].head].dword, &rxMsg->au32Data[0], sizeof(uint32_t[2]));
                gCan0.rbuf[CH_M2_HEART][gCan0.rq[CH_M2_HEART].head].dlc = rxMsg->DLC;
                gCan0.rq[CH_M2_HEART].Add(&gCan0.rq[CH_M2_HEART]);
            }
            break;

        default: break;
    }
}

// static uint8_t QueryData(uint16_t ch,uint8_t *dlc, uint32_t *data)
static uint8_t RxData(int8_t ch, uint8_t *dlc, uint32_t *data)
{
    if ((ch > -1) && (gCan0.rq[ch].deep) > 0)
    {
        memcpy(data, gCan0.rbuf[ch][gCan0.rq[ch].tail].dword, sizeof(uint32_t[2]));
        *dlc = gCan0.rbuf[ch][gCan0.rq[ch].tail].dlc;
        gCan0.rq[ch].Del(&gCan0.rq[ch]);  //队列删除
        return 1;
    }
    else
    {
        return 0;
    }
}

static uint8_t TxData(uint32_t txId, uint8_t dlc, uint32_t *data)
{
    if (gCan0.tq.deepMax - gCan0.tq.deep)
    {
        // stc_can_tx_frame_t txMsg = {0};
        gCan0.txBuf[gCan0.tq.head].DLC                = dlc;
        gCan0.txBuf[gCan0.tq.head].u32ID              = txId;
        gCan0.txBuf[gCan0.tq.head].au32Data[0]        = data[0];
        gCan0.txBuf[gCan0.tq.head].au32Data[1]        = data[1];
        gCan0.tq.Add(&gCan0.tq);
    }
    return 0;
}



static void Period(void)
{
       //   //Rx
    stc_can_rx_frame_t rxMsg = {0};

    if (CHAL_Can0Rx(&rxMsg))
    {
        canRxData(&rxMsg);
    }

    /* TX */
    if (gCan0.tq.deep > 0)
    {
        CHAL_Can0Tx(&gCan0.txBuf[gCan0.tq.tail]);
        gCan0.tq.Del(&gCan0.tq);  //队列删除

    }
    //
}

//*


const MCan_Func gCanFunc=
{
  .Init=Init,
  .Period = Period,
  .RxData = RxData,
  .TxData = TxData,
};

三、总结

这种分层设计的带缓存DSP28335 CAN驱动程序,通过合理的缓存管理和周期性数据处理,能够在保证数据传输稳定性的同时,提高系统的运行效率。并且,由于避免了频繁的中断处理,使得CPU能够更专注于其他任务的执行,提升了整体系统的性能。在未来的设计和优化中,我们可以进一步细化各层的功能,以适应更复杂的应用场景。

相关推荐
劉小帅1 天前
CANoe的capl调用Qt制作的dll
qt·can
劉小帅7 天前
CAN和CANFD数据写入.asc文件的dll
qt·自动化·can
嵌入式小宁9 天前
ESP32 双线汽车接口 (TWAI)
汽车·can·twai
YRr YRr17 天前
CANable USB转CAN适配器固件的安装(ubuntu20.04)
linux·ubuntu·ros·can
码农小展25 天前
CAN协议简介
单片机·can·通讯协议·can协议
花园宝宝小点点1 个月前
车联网安全入门——ICSim模拟器使用
安全·汽车·can·车联网安全
花园宝宝小点点1 个月前
车联网安全入门——CAN总线逆向(ICSim)
安全·汽车·can·逆向·车联网安全
疯狂的机器人1 个月前
【Python搞定车载自动化测试】——Python实现CAN总线Bootloader刷写(含Python源码)
python·自动化·can·诊断·uds·bootloader·刷写
疯狂的机器人1 个月前
【Python搞定车载自动化测试】——Python基于Pytest框架实现UDS诊断自动化(含Python源码)
python·自动化·pytest·can·诊断·allure·uds
Nuttx_Fan_now2 个月前
Microchip 32位MCU CAN驱动图文教程-附源码
单片机·嵌入式硬件·can·教程·harmony·mcc·microchip