一种带缓存DSP28335 CAN程序

      一、概述

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

1. CHAL层:

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

2. BSP层:

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

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

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

3. 应用层:

应用层是最高层,主要负责处理接收缓存中的数据和将待发送的数据加入发送缓存。只要缓存大小设置得当,且数据的处理及时,就可以保证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 Filevoid 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 bitsSysCtrlRegs.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 bitsECanaRegs.CANRMP.all = 0xFFFFFFFF;  // Clear all RMPn bitsECanaRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bitsECanaRegs.CANGIF1.all = 0xFFFFFFFF;//// Configure bit timing parameters for eCANA//ECanaShadow.CANMC.all     = ECanaRegs.CANMC.all;ECanaShadow.CANMC.bit.CCR = 1;  // Set CCR = 1ECanaShadow.CANMC.bit.DBO = 1;  // DATA orderECanaRegs.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 setECanaShadow.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 = 0ECanaRegs.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 IDECanaMboxes.MBOX0.MSGID.bit.AME   = 1;          // Set IDECanaShadow.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 IDECanaMboxes.MBOX1.MSGID.bit.AME   = 1;          // Set IDECanaShadow.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 IDECanaMboxes.MBOX2.MSGID.bit.AME   = 1;          // Set IDECanaShadow.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 bitsSysCtrlRegs.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 bitsECanbRegs.CANRMP.all = 0xFFFFFFFF;  // Clear all RMPn bitsECanbRegs.CANGIF0.all = 0xFFFFFFFF;  // Clear all interrupt flag bitsECanbRegs.CANGIF1.all = 0xFFFFFFFF;//// Configure bit timing parameters for eCANB//ECanbShadow.CANMC.all     = ECanbRegs.CANMC.all;ECanbShadow.CANMC.bit.CCR = 1;  // Set CCR = 1ECanbShadow.CANMC.bit.DBO = 1;  // DATA orderECanbRegs.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  clearedECanbShadow.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 = 0ECanbRegs.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 IDECanbMboxes.MBOX0.MSGID.bit.AME   = 1;          // Set IDECanbShadow.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 IDECanbMboxes.MBOX1.MSGID.bit.AME   = 1;          // Set IDECanbShadow.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 IDECanbMboxes.MBOX2.MSGID.bit.AME   = 1;          // Set IDECanbShadow.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 IDECanbShadow.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 IDECanbShadow.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 = 0ECanaRegs.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 flagret                         = 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 flagret                         = 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 flagret                         = 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 testECanaShadow.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 testECanaShadow.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 = 0ECanbRegs.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 flagret                         = 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 flagret                         = 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 flagret                         = 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 testECanbShadow.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 testECanbShadow.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 operationGpioCtrlRegs.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 operationEDIS;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 operationGpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;  // Configure GPIO31 for CANTXA operationEDIS;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)
{//   //Rxstc_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能够更专注于其他任务的执行,提升了整体系统的性能。在未来的设计和优化中,我们可以进一步细化各层的功能,以适应更复杂的应用场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/239007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flutter + firebase 云消息通知教程 (android-安卓、ios-苹果)

如果能看到这篇文章的 一定已经对手机端的 消息推送通知 有了一定了解。 国内安卓厂商这里不提都有自己的FCM 可自行查找。&#xff08;国内因无法科学原因 &#xff0c;不能使用谷歌服务&#xff09;只说海外的。 目前 adnroid 和 ios 推送消息分别叫 FCM 和 APNs。这里通过…

UG阵列面、阵列集合特征和阵列特征的区别

阵列面 对面进行阵列&#xff0c;当实体中被切除特征的时候可以使用阵列面&#xff0c;当这个命令去阵列一个实体的时候&#xff0c;阵列的是一个片体&#xff0c;优点是速度快&#xff0c;缺点是功能较简单&#xff1b; 阵列几何特征 对实体进行阵列&#xff0c;可以一次性选…

在el-tabs中echarts图表宽高设置style=“width: 100%; height: 100%“不起效变成100px的问题

bug场景 两种情况 一就是如标题一样&#xff0c;给div设置的100%高度&#xff0c;但是最后在elements里检查元素发现高度只有100px。二是&#xff0c;设置了高度为100%&#xff0c;但是检查元素里发现元素高宽为0。 问题解决方案 在使用 ECharts时&#xff0c;将图表嵌套在 …

【稳定检索|投稿优惠】2024年绿色能源与电网电力系统国际会议(ICGEGPS 2024)

2024年绿色能源与电网电力系统国际会议(ICGEGPS 2024) 2024 International Conference on Green Energy and Grid Power Systems(ICGEGPS) 一、【会议简介】 2024年绿色能源与电网电力系统国际会议(ICGEGPS 2024)将在宜宾盛大召开。本次会议将聚焦绿色能源与电网电力系统的最新…

QByteArray 是 Qt 框架中的一个类,用于存储和操作字节数组(byte array)

QByteArray 是 Qt 框架中的一个类&#xff0c;用于存储和操作字节数组&#xff08;byte array&#xff09;。 QByteArray 类提供了一系列方法来处理字节数据&#xff0c;包括&#xff1a; 存储字节数据&#xff1a;你可以使用 QByteArray 对象存储字节数据&#xff0c;例如图片…

教你在Linux上安装Node并用Electron打包deb和rpm包

Windows下无法打linux版本的包&#xff0c;如果你要打linux系统的amd64架构需要找一台linux amd64的系统打包&#xff0c;也可以在amd64下打arm架构的包&#xff0c;但是不能运行&#xff0c;需要放到arm架构的系统里才能运行。 下载linux的node环境 Index of /nodejs-releas…

WinRAR如何设置和清除密码?

WinRAR是一款功能强大的压缩管理器&#xff0c;除了能把文件打包变小&#xff0c;还能给压缩包设置密码保护&#xff0c;让文件不能随意打开&#xff0c;不需要时还可以把密码取消。下面来说说具体怎么操作吧。 WinRAR根据需要可以设置单次密码和永久密码&#xff0c;我们分别…

Spring Environment 注入引起NPE问题排查

文章目录 背景原因分析1&#xff09;Spring Aware Bean 是什么&#xff1f;2&#xff09;从 Spring Bean 的生命周期入手 解决方案 背景 写业务代码遇到使用 Spring Environment 注入为 null 的情况&#xff0c;示例代码有以下两种写法&#xff0c;Environment 实例都无法注入…

Megatron模型并行研究

Megatron模型并行研究 1. 技术调研 a. Megatron-LM Megatron-LM针对的是特别大的语言模型&#xff0c;使用的是模型并行的训练方式。但和普通的模型并行不同&#xff0c;他采用的其实是张量并行的形式&#xff0c;具体来说就是将一个层切开放到不同的GPU上&#xff0c;属于层…

Java中升级属性复制转换功能

前言 在java中,经常碰到bean之间的转换,诸如Entity转VO,Entity转DTO等等,这时,经常会碰到这样一种情况,VO和DTO里面有一个字段都是来源于Entity里面,但是属性名称和属性类型都不一样,虽然转换逻辑一致但是我们还是只能手动转换,这时如果我在代码中手动转换会出现很多多…

基于SSM的旅游网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

设计模式:循序渐进走入工厂模式

文章目录 前言一、引入二、简单工厂模式1.实现2.优缺点3.扩展 三、工厂方法模式1.实现2.优缺点 四、抽象工厂模式1.实现2.优缺点3.使用场景 五、模式扩展六、JDK源码解析总结 前言 软件设计模式之工厂模式。 一、引入 需求&#xff1a;设计一个咖啡店点餐系统。 设计一个咖啡类…

设计模式-门面模式

设计模式专栏 模式介绍模式特点应用场景门面模式和代理模式的区别代码示例Java实现门面模式Python实现门面模式 门面模式在spring中的应用 模式介绍 门面模式是一种常用的软件设计模式&#xff0c;也称为外观模式。它提供了一个高层次的接口&#xff0c;将一个子系统的外部与内…

卡通动漫AI绘画视频风格化AI智能PR插件StyleX免费下载

带有AI的视频风格化工具PR AI智能绘画插件。将视频转换为卡通、绘图、绘画、半色调和许多其他风格。 性能高度依赖GPU&#xff0c;一些旧的GPU卡&#xff08;2012年之前&#xff09;不受支持。 StyleX是一款先进的视频风格化工具&#xff0c;采用AI技术&#xff0c;它不仅可以将…

代码随想录第三十八天(一刷C语言)|零钱兑换II组合总数和 IV

创作目的&#xff1a;为了方便自己后续复习重点&#xff0c;以及养成写博客的习惯。 一、零钱兑换II 思路&#xff1a;参考carl文档 1、确定dp数组以及下标的含义&#xff1a;凑成总金额j的货币组合数为dp[j]。 2、确定递推公式&#xff1a;dp[j] 就是所有的dp[j - coins[i…

黑苹果安装经验总结2023-12

最近2个月安装了3台黑苹果 B85&#xff0c;I3-4330&#xff0c;HD7750&#xff0c;最容易安装&#xff0c;MacOS12一次成功山寨X99&#xff0c;E5-2650V4&#xff0c;RX470&#xff0c;难度高惠普Z840&#xff0c;X99平台&#xff0c;2颗E5-2630&#xff0c;128G内存&#xff…

仿悬赏猫任务平台源码 悬赏任务系统源码 带支付接口

源码介绍 最新仿悬赏猫任务平台源码 悬赏任务系统源码 带支付接口&#xff0c; 全新开发悬赏任务系统&#xff0c;功能齐全&#xff0c;包含接任务&#xff0c;发布任务&#xff0c; 店铺关注&#xff0c;置顶推荐&#xff0c;排行榜&#xff0c;红包大厅&#xff0c;红包抽奖…

深信服AF防火墙升级步骤(简单粗暴)

设备当前版本&#xff1a;AF8.0.75 升级升级后版本&#xff1a;AF8.0.85 官方发行&#xff1a;内容比较多&#xff0c;找设备当前版本在不在支持升级的列表即可 8.0.75是可以直接升到8.0.85的 升级前注意事项&#xff1a; 升级是需要重启设备的&#xff0c;会断网&#xff…

两种方法解决win10开机慢,经验分享

方法一&#xff1a; 1、按快捷键“winR”打开 运行窗口。 2、这时候输入“msconfig”后 &#xff0c;点击“确定”或者按“ENTER”键。 3、这时候会打开一个名为“系统配置”的窗口&#xff0c; 在“常规”选项框下 勾选“有选择的启动”下的“加载系统服务”和“加载启动项”。…

C语言的scanf输入函数的介绍分享

各位少年&#xff1a; 我来分享一个输入函数&#xff0c;scanf函数 是输入的函数&#xff0c;scanf&#xff08;“参数1”&#xff0c;参数2);好&#xff0c;我们接着看代码的例子 int main() { int score0; printf("请输入成绩:"); scanf("%d",&sco…