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

6. 软件设计
- CAN初始化子函数
- CAN总线学习https://blog.csdn.net/qq_33693310/article/details/118492687
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的一些寄存器无法进行直接操作,需要一个阴影寄存器进行间接操作
EALLOW; // EALLOW enables access to protected bitsECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;//can的发送IO口的配置寄存器读出来,赋值给阴影寄存器<br /> ECanaShadow.CANTIOC.bit.TXFUNC = 1; //将负责发送功能的阴影寄存器置一<br /> ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;//将置一的阴影寄存器给can io寄存器赋值ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;<br /> ECanaShadow.CANRIOC.bit.RXFUNC = 1;<br /> ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;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 请求对位时序进行配置
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;#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 /> #endifECanaShadow.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;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
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/
ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all;<br /> ECanbShadow.CANTIOC.bit.TXFUNC = 1;<br /> ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all;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) /
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
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.
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 */<br /> ECanbRegs.CANGIF1.all = 0xFFFFFFFF;
/ Configure bit timing parameters for eCANB/
ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;<br /> ECanbShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1<br /> ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;ECanbShadow.CANES.all = ECanbRegs.CANES.all;do<br /> {<br /> ECanbShadow.CANES.all = ECanbRegs.CANES.all;<br /> } while(ECanbShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be cleared..ECanbShadow.CANBTC.all = 0;#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 /> #endifECanbShadow.CANBTC.bit.SAM = 1;<br /> ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all;ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;<br /> ECanbShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0<br /> ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;ECanbShadow.CANES.all = ECanbRegs.CANES.all;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
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.
GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up for GPIO18 (CANRXA)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
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
EDIS;<br />}<br />#endif // if DSP28_ECANB
