5. 硬件设计

查阅开发板手册,查询CAN相关外设的引脚信息,方便后续程序中配置GPIO。
本实验中我们使用CANA,也就是GPIO18,19。
image.png
image.png
image.png

6. 软件设计

  1. CAN初始化子函数
  2. CAN总线学习https://blog.csdn.net/qq_33693310/article/details/118492687
  3. include “DSP2833x_Device.h” // DSP2833x Headerfile Include File

include “DSP2833x_Examples.h” // DSP2833x Examples Include File

void InitECan(void)
{
//如果用到了CANA那么使能CANA,如果用到了CANB那么使能CANB
InitECana();
#if DSP28_ECANB
InitECanb();
#endif // if DSP28_ECANB
}

//CANA初始化函数
void InitECana(void)
{

struct ECAN_REGS ECanaShadow; //建立一个阴影寄存器,因为CAN的一些寄存器无法进行直接操作,需要一个阴影寄存器进行间接操作

  1. EALLOW; // EALLOW enables access to protected bits
  2. ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;//can的发送IO口的配置寄存器读出来,赋值给阴影寄存器<br /> ECanaShadow.CANTIOC.bit.TXFUNC = 1; //将负责发送功能的阴影寄存器置一<br /> ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;//将置一的阴影寄存器给can io寄存器赋值
  3. ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;<br /> ECanaShadow.CANRIOC.bit.RXFUNC = 1;<br /> ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;
  4. ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;<br /> ECanaShadow.CANMC.bit.SCB = 1; //CANMC主控制器 SCB=1为选择eCAN模式,=0 在SCC模式下只有0-15号邮箱可以使用<br /> ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;<br /> //清空邮箱的发送寄存器初始化<br /> ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;<br /> ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;<br />//==============================================================================

//清除所有的发送标志,发送标志
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//CPU请求向配置寄存器CANBTC和SCC
//的接收屏蔽寄存器(CANGAM,LAM[0],LAM[3])写配置
//在该位置位后,CPU必须等到CANES寄存器的CCE标志位为1时,
//才能对CANBTC寄存器进行操作。如果ABO位置没有置位,CCR
//位将会在总线离线状态下置位,BO状态能够通过清除这一位而退出
//=1 请求对位时序进行配置

  1. ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;<br />//=================================================================================<br /> ECanaShadow.CANES.all = ECanaRegs.CANES.all;<br /> do<br /> {<br /> ECanaShadow.CANES.all = ECanaRegs.CANES.all;<br /> } while(ECanaShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be set..<br /> //CANES CCE=1 CPU已经对配置寄存器写访问 =0位拒绝<br />//=================================================================================<br />//波特率设置<br /> ECanaShadow.CANBTC.all = 0;
  2. #if (CPU_FRQ_150MHZ) // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h<br /> /* The following block for all 150 MHz SYSCLKOUT (75 MHz CAN clock) - default. Bit rate = 1 Mbps<br /> See Note at End of File */<br /> ECanaShadow.CANBTC.bit.BRPREG = 4;<br /> //BRPREG为波特率预调节<br /> ECanaShadow.CANBTC.bit.TSEG2REG = 2;<br /> //时间段2位<br /> ECanaShadow.CANBTC.bit.TSEG1REG = 10;<br /> //时间段1位<br /> #endif<br /> #if (CPU_FRQ_100MHZ) // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h<br /> /* The following block is only for 100 MHz SYSCLKOUT (50 MHz CAN clock). Bit rate = 1 Mbps<br /> See Note at End of File */<br /> ECanaShadow.CANBTC.bit.BRPREG = 4;<br /> ECanaShadow.CANBTC.bit.TSEG2REG = 1;<br /> ECanaShadow.CANBTC.bit.TSEG1REG = 6;<br /> #endif
  3. ECanaShadow.CANBTC.bit.SAM = 1;//设置CAN模块使用的采样数已决定CAN总线的实际水平。<br /> //=1 CAN模块采样三次,并以多数为准,三次采样只会在位速率预定值大于4时被选取。<br /> //=0 CAN模块只会在采样点采样一次<br /> ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;<br />//========================================================================================<br /> ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;<br /> ECanaShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0<br /> //=0 CPU请求正常操作。这只能在配置寄存器CANBTC置位位允许的值时完成。<br /> ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;<br />//========================================================================================<br /> ECanaShadow.CANES.all = ECanaRegs.CANES.all;
  4. do<br /> {<br /> ECanaShadow.CANES.all = ECanaRegs.CANES.all;<br /> } while(ECanaShadow.CANES.bit.CCE != 0 ); // Wait for CCE bit to be cleared..<br /> //CANES CCE=1 CPU已经对配置寄存器写访问 =0位拒绝

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

  1. EDIS;<br />}

//CANB初始化函数 程序和初始化CANA是一样的。

//===========================================================================================
#if (DSP28_ECANB)
void InitECanb(void) // Initialize eCAN-B module
{
/ 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

/ Configure eCAN RX and TX pins for CAN operation using eCAN regs/

  1. ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all;<br /> ECanbShadow.CANTIOC.bit.TXFUNC = 1;<br /> ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all;
  2. ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all;<br /> ECanbShadow.CANRIOC.bit.RXFUNC = 1;<br /> ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all;

/ Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) /

  1. ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;<br /> ECanbShadow.CANMC.bit.SCB = 1;<br /> 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

  1. ECanbMboxes.MBOX0.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX1.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX2.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX3.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX4.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX5.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX6.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX7.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX8.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX9.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX10.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX11.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX12.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX13.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX14.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX15.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX16.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX17.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX18.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX19.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX20.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX21.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX22.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX23.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX24.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX25.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX26.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX27.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX28.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX29.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX30.MSGCTRL.all = 0x00000000;<br /> ECanbMboxes.MBOX31.MSGCTRL.all = 0x00000000;

// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
// as a matter of precaution.

  1. ECanbRegs.CANTA.all = 0xFFFFFFFF; /* Clear all TAn bits */
  2. ECanbRegs.CANRMP.all = 0xFFFFFFFF; /* Clear all RMPn bits */
  3. ECanbRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */<br /> ECanbRegs.CANGIF1.all = 0xFFFFFFFF;

/ Configure bit timing parameters for eCANB/

  1. ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;<br /> ECanbShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1<br /> ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
  2. ECanbShadow.CANES.all = ECanbRegs.CANES.all;
  3. do<br /> {<br /> ECanbShadow.CANES.all = ECanbRegs.CANES.all;<br /> } while(ECanbShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be cleared..
  4. ECanbShadow.CANBTC.all = 0;
  5. #if (CPU_FRQ_150MHZ) // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h<br /> /* The following block for all 150 MHz SYSCLKOUT (75 MHz CAN clock) - default. Bit rate = 1 Mbps<br /> See Note at end of file */<br /> ECanbShadow.CANBTC.bit.BRPREG = 4;<br /> ECanbShadow.CANBTC.bit.TSEG2REG = 2;<br /> ECanbShadow.CANBTC.bit.TSEG1REG = 10;<br /> #endif<br /> #if (CPU_FRQ_100MHZ) // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h<br /> /* The following block is only for 100 MHz SYSCLKOUT (50 MHz CAN clock). Bit rate = 1 Mbps<br /> See Note at end of file */<br /> ECanbShadow.CANBTC.bit.BRPREG = 4;<br /> ECanbShadow.CANBTC.bit.TSEG2REG = 1;<br /> ECanbShadow.CANBTC.bit.TSEG1REG = 6;<br /> #endif
  6. ECanbShadow.CANBTC.bit.SAM = 1;<br /> ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all;
  7. ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;<br /> ECanbShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0<br /> ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
  8. ECanbShadow.CANES.all = ECanbRegs.CANES.all;
  9. do<br /> {<br /> ECanbShadow.CANES.all = ECanbRegs.CANES.all;<br /> } 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

  1. EDIS;<br />}<br />#endif // if DSP28_ECANB

//===========================================================================================
//GPIO初始化程序 同样也是用到那个can初始化哪个
void InitECanGpio(void)
{
InitECanaGpio();
#if (DSP28_ECANB)
InitECanbGpio();
#endif // if DSP28_ECANB
}

//===========================================================================================
void InitECanaGpio(void)
{
EALLOW;

/ Enable internal pull-up for the selected CAN pins /
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

  1. GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up for GPIO18 (CANRXA)
  2. GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; // Enable pull-up for GPIO19 (CANTXA)

/ Set qualification for selected CAN pins to asynch only /
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.

GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch qual for GPIO18 (CANRXA)

/ Configure eCAN-A pins using GPIO regs/
// This specifies which of the possible GPIO pins will be eCAN functional pins.

GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // Configure GPIO18 for CANRXA operation

GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 3; // Configure GPIO19 for CANTXA operation

  1. EDIS;<br />}

if (DSP28_ECANB)
void InitECanbGpio(void)
{
EALLOW;

/ Enable internal pull-up for the selected CAN pins /
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pull-up for GPIO16 (CANTXB)

GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up for GPIO17 (CANRXB)

/ Set qualification for selected CAN pins to asynch only /
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch qual for GPIO17 (CANRXB)

/ Configure eCAN-B pins using GPIO regs/
// This specifies which of the possible GPIO pins will be eCAN functional pins.

GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; // Configure GPIO16 for CANTXB operation

GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; // Configure GPIO17 for CANRXB operation

  1. EDIS;<br />}<br />#endif // if DSP28_ECANB