DSP28335 CAN通讯实验

《DSP从零开始学习历程》@EnzoReventon

DSP 28335 CAN通讯实验

1. 实验目的:

实现开发板上同一个CAN口的数据收发,mail0发送数据,mail1接收数据。

2. 硬件设备

“研旭 三兄弟”DSP28335开发板
在这里插入图片描述

研旭YXDSP-XDS100V3 仿真器
在这里插入图片描述

周立功ZLG USBCANFD200U,USB-CAN转换器,用于电脑与设备间的CAN数据收发
在这里插入图片描述

3. 软件准备

  1. Code Composer Studio 6.1.3,用于编写,调试DSP程序。
    在这里插入图片描述

  2. ZCANPRO,用于调试CAN通讯。
    在这里插入图片描述

4. CAN通讯的原理

CAN通讯的原理其实都是大同小异的,可以参考STM32的CAN通讯原理讲解。
《STM32从零开始学习历程》——CAN通讯协议物理层
STM32从零开始学习历程》——CAN通讯协议协议层

5. 硬件设计

查阅开发板手册,查询CAN相关外设的引脚信息,方便后续程序中配置GPIO。
本实验中我们使用CANA,也就是GPIO18,19。
在这里插入图片描述
我们将开发板的CANL,CANH与USBCANFD的CANH,CANL相连接,如下图所示。在这里插入图片描述

6. 软件设计

  1. CAN初始化子函数
#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 bits


    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;//can的发送IO口的配置寄存器读出来,赋值给阴影寄存器
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;				//将负责发送功能的阴影寄存器置一
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;//将置一的阴影寄存器给can io寄存器赋值

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

	ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
	ECanaShadow.CANMC.bit.SCB = 1;					//CANMC主控制器 SCB=1为选择eCAN模式,=0 在SCC模式下只有0-15号邮箱可以使用
	ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
	//清空邮箱的发送寄存器初始化
    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;
//==============================================================================

//清除所有的发送标志,发送标志
	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;
//=================================================================================
    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..
    //CANES CCE=1 CPU已经对配置寄存器写访问 =0位拒绝
//=================================================================================
//波特率设置
    ECanaShadow.CANBTC.all = 0;

    #if (CPU_FRQ_150MHZ)                       // 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 = 4;
			//BRPREG为波特率预调节
			ECanaShadow.CANBTC.bit.TSEG2REG = 2;
			//时间段2位
			ECanaShadow.CANBTC.bit.TSEG1REG = 10;
			//时间段1位
    #endif
	#if (CPU_FRQ_100MHZ)                       // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h
	/* The following block is only for 100 MHz SYSCLKOUT (50 MHz CAN clock). Bit rate = 1 Mbps
	   See Note at End of File */
	    ECanaShadow.CANBTC.bit.BRPREG = 4;
		ECanaShadow.CANBTC.bit.TSEG2REG = 1;
		ECanaShadow.CANBTC.bit.TSEG1REG = 6;
	#endif

    ECanaShadow.CANBTC.bit.SAM = 1;//设置CAN模块使用的采样数已决定CAN总线的实际水平。
    								//=1 CAN模块采样三次,并以多数为准,三次采样只会在位速率预定值大于4时被选取。
    								//=0 CAN模块只会在采样点采样一次
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;
//========================================================================================
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
	ECanaShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
												//=0 CPU请求正常操作。这只能在配置寄存器CANBTC置位位允许的值时完成。
    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..
    //CANES CCE=1 CPU已经对配置寄存器写访问 =0位拒绝

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

    EDIS;
}

//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;
    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 - (reqd 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
    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;

    #if (CPU_FRQ_150MHZ)                       // 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 = 4;
		ECanbShadow.CANBTC.bit.TSEG2REG = 2;
		ECanbShadow.CANBTC.bit.TSEG1REG = 10;
	#endif
	#if (CPU_FRQ_100MHZ)                       // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h
	/* The following block is only for 100 MHz SYSCLKOUT (50 MHz CAN clock). Bit rate = 1 Mbps
	   See Note at end of file */
	    ECanbShadow.CANBTC.bit.BRPREG = 4;
		ECanbShadow.CANBTC.bit.TSEG2REG = 1;
		ECanbShadow.CANBTC.bit.TSEG1REG = 6;
	#endif

    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

    EDIS;
}
#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;
}

#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;
}
#endif // if DSP28_ECANB

  1. 主程序函数页面

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

#define TXCOUNT  1000  // Transmission will take place (TXCOUNT) times..

// 定义一些常用的变量以及一些函数的声明
long      i;
long 	  loopcount = 0;

#define	  BEEP	GpioDataRegs.GPADAT.bit.GPIO53
#define	  LED1	GpioDataRegs.GPADAT.bit.GPIO0
#define	  LED2	GpioDataRegs.GPADAT.bit.GPIO7

Uint16 j;
Uint16 m;

struct ECAN_REGS ECanbShadow;

struct ECAN_REGS ECanaShadow;

void mailbox_read(int MBXnbr);

void mailID_Config(void);

void mail_length(void);

void mail_Data(void);

void CANMIM_interrupt(void);//禁止邮箱中断子函数

void CAN_SelfTestMode(void);//can自我检测模式

void configtestled(void);

void CANMIMI_interrupt_OPEN(void);

Uint32 TESTMbox1 = 0;

Uint32 TESTMbox2 = 0;

Uint32 TESTMbox3 = 0;


void main()
{

unsigned long k = 0;

   InitSysCtrl();
   InitXintf16Gpio();
   InitECanGpio();
   DINT;	//禁止CPU中断
   InitPieCtrl();	
   IER = 0x0000;	//清除中断使能位
   IFR = 0x0000;
   InitPieVectTable();


//==================================================================================
/*
   1. CANME 使能邮箱 =1使能邮箱 =0禁止邮箱
   2. CANMD 配置邮箱接受还是发送
   3. CANTRS =1 启动邮箱的数据发送
   4. CANTRR =1 取消邮箱的数据发送,置位了CANTRS,数据还没发送出去,可以置位TRR取消数据的发送
   5. CANRMP 如果有新的信息进入了邮箱,那么RMP将置位为1

*/
   	   	 InitECan();//CAN初始化 已经包含CANME.all =0
   	     mailID_Config();
   	     //设置数据的长度编码
		 mail_length();
		 //设置邮箱内容
//		 mail_Data();(根据自己需要可以选择调用,本实验中没有使用)

		 CANMIM_interrupt();//CAN禁止中断模式
		 CAN_SelfTestMode();//CAN自检模式
		 
		 CANMIMI_interrupt_OPEN();
		 
	while(1)
	{

		 //CANa TX
		 for(i=0;i <TXCOUNT;i++)
		 {
		 //配置邮箱的接受还是发送模式
		 ECanaRegs.CANMD.all = 0x00000000;//配置cana mail0为发送邮箱

		 //邮箱使能 激活
		 ECanaRegs.CANME.all = 0x00000003;//邮箱激活

		 ECanaMboxes.MBOX0.MDL.all = k;

		 ECanaMboxes.MBOX0.MDH.all = k+1;

		 ECanaRegs.CANTRS.all = 0x00000001;  // Set TRS for all transmit mailboxes

		 //发送请求置位寄存器 启动邮箱数据发送

		 while(ECanaRegs.CANTA.all != 0x00000001 ) {}  // Wait for all TAn bits to be set..

		 ECanaRegs.CANTA.all = 0x00000001;   // Clear all TAn

		 loopcount++;//计数成功的发射次数

		 k++;

		 mailbox_read(0);

		 }
//=======================================================
 		 //CANb RX

		 for(i=TXCOUNT;i <TXCOUNT*2;i++)

	  	{

		 //配置邮箱的接受还是发送模式

		 ECanaRegs.CANMD.bit.MD1 = 1;;//cana配置位接受邮箱 mail1为接收邮箱

		 ECanaRegs.CANME.bit.ME1 =1;;

	 	}
//=========================================================
		 k = 0;
		 loopcount = 0;
		 configtestled();
	}

//       asm(" ESTOP0");  // Stop here
}
//==========================================================
//GPIO复用LED灯闪烁子函数
void configtestled(void)
{

   EALLOW;
   GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0复用为GPIO功能
   GpioCtrlRegs.GPADIR.bit.GPIO0 = ~GpioCtrlRegs.GPADIR.bit.GPIO0;  // GPIO0设置为输出
   EDIS;
}
//==========================================================
//读取指定邮箱的数据子函数
void mailbox_read(int16 MBXnbr)
{
	volatile struct MBOX *Mailbox;
	Mailbox = &ECanaMboxes.MBOX0 + MBXnbr;
	TESTMbox1 = Mailbox->MDL.all;
	TESTMbox2 = Mailbox->MDH.all;
	TESTMbox3 = Mailbox->MSGID.all;
}
//==========================================================
//CAN邮箱的ID配置子函数,本实验中使用了mail0作为发送邮箱,并且不设置过滤器,也就是说数据可以直接发送至总线不需要考虑ID,mail1是接收数据,过滤ID为0x00000001.
void mailID_Config(void)
{
	ECanaMboxes.MBOX0.MSGID.bit.IDE=0;
//	ECanaMboxes.MBOX1.MSGID.bit.IDE=0;
	//CANA ID
	//配置收发的ID
//	 ECanaMboxes.MBOX0.MSGID.all = 0x00000000;
	 ECanaMboxes.MBOX1.MSGID.all = 0x00000001;
//	 ECanaMboxes.MBOX2.MSGID.all = 0x9555AAA2;
//	 ECanaMboxes.MBOX3.MSGID.all = 0x9555AAA3;
//	 ECanaMboxes.MBOX4.MSGID.all = 0x9555AAA4;
//	 ECanaMboxes.MBOX5.MSGID.all = 0x9555AAA5;
//	 ECanaMboxes.MBOX6.MSGID.all = 0x9555AAA6;
//	 ECanaMboxes.MBOX7.MSGID.all = 0x9555AAA7;
//	 ECanaMboxes.MBOX8.MSGID.all = 0x9555AAA8;
//	 ECanaMboxes.MBOX9.MSGID.all = 0x9555AAA9;
//	 ECanaMboxes.MBOX10.MSGID.all = 0x9555AAAA;
//	 ECanaMboxes.MBOX11.MSGID.all = 0x9555AAAB;
//	 ECanaMboxes.MBOX12.MSGID.all = 0x9555AAAC;
//	 ECanaMboxes.MBOX13.MSGID.all = 0x9555AAAD;
//	 ECanaMboxes.MBOX14.MSGID.all = 0x9555AAAE;
//	 ECanaMboxes.MBOX15.MSGID.all = 0x9555AAAF;

	 // Write to the MSGID field of RECEIVE mailboxes MBOX16 - 31
//	 ECanaMboxes.MBOX16.MSGID.all = 0x9555AA10;
//	 ECanaMboxes.MBOX17.MSGID.all = 0x9555AA11;
//	 ECanaMboxes.MBOX18.MSGID.all = 0x9555AA12;
//	 ECanaMboxes.MBOX19.MSGID.all = 0x9555AA13;
//	 ECanaMboxes.MBOX20.MSGID.all = 0x9555AA14;
//	 ECanaMboxes.MBOX21.MSGID.all = 0x9555AA15;
//	 ECanaMboxes.MBOX22.MSGID.all = 0x9555AA16;
//	 ECanaMboxes.MBOX23.MSGID.all = 0x9555AA17;
//	 ECanaMboxes.MBOX24.MSGID.all = 0x9555AA18;
//	 ECanaMboxes.MBOX25.MSGID.all = 0x9555AA19;
//	 ECanaMboxes.MBOX26.MSGID.all = 0x9555AA1A;
//	 ECanaMboxes.MBOX27.MSGID.all = 0x9555AA1B;
//	 ECanaMboxes.MBOX28.MSGID.all = 0x9555AA1C;
//	 ECanaMboxes.MBOX29.MSGID.all = 0x9555AA1D;
//	 ECanaMboxes.MBOX30.MSGID.all = 0x9555AA1E;
//	 ECanaMboxes.MBOX31.MSGID.all = 0x9555AA1F;

//CANB ID
/* Configure Mailbox under test as a Transmit mailbox */
	 ECanbMboxes.MBOX0.MSGID.bit.IDE=0;
//	 ECanbMboxes.MBOX0.MSGID.all = 0x00000000;
//	 ECanbMboxes.MBOX1.MSGID.all = 0x9555AAA1;
//	 ECanbMboxes.MBOX2.MSGID.all = 0x9555AAA2;
//	 ECanbMboxes.MBOX3.MSGID.all = 0x9555AAA3;
//	 ECanbMboxes.MBOX4.MSGID.all = 0x9555AAA4;
//	 ECanbMboxes.MBOX5.MSGID.all = 0x9555AAA5;
//	 ECanbMboxes.MBOX6.MSGID.all = 0x9555AAA6;
//	 ECanbMboxes.MBOX7.MSGID.all = 0x9555AAA7;
//	 ECanbMboxes.MBOX8.MSGID.all = 0x9555AAA8;
//	 ECanbMboxes.MBOX9.MSGID.all = 0x9555AAA9;
//	 ECanbMboxes.MBOX10.MSGID.all = 0x9555AAAA;
//	 ECanbMboxes.MBOX11.MSGID.all = 0x9555AAAB;
//	 ECanbMboxes.MBOX12.MSGID.all = 0x9555AAAC;
//	 ECanbMboxes.MBOX13.MSGID.all = 0x9555AAAD;
//	 ECanbMboxes.MBOX14.MSGID.all = 0x9555AAAE;
//	 ECanbMboxes.MBOX15.MSGID.all = 0x9555AAAF;

	 // Write to the MSGID field of RECEIVE mailboxes MBOX16 - 31
//	 ECanbMboxes.MBOX16.MSGID.all = 0x9555AA10;
//	 ECanbMboxes.MBOX17.MSGID.all = 0x9555AA11;
//	 ECanbMboxes.MBOX18.MSGID.all = 0x9555AA12;
//	 ECanbMboxes.MBOX19.MSGID.all = 0x9555AA13;
//	 ECanbMboxes.MBOX20.MSGID.all = 0x9555AA14;
//	 ECanbMboxes.MBOX21.MSGID.all = 0x9555AA15;
//	 ECanbMboxes.MBOX22.MSGID.all = 0x9555AA16;
//	 ECanbMboxes.MBOX23.MSGID.all = 0x9555AA17;
//	 ECanbMboxes.MBOX24.MSGID.all = 0x9555AA18;
//	 ECanbMboxes.MBOX25.MSGID.all = 0x9555AA19;
//	 ECanbMboxes.MBOX26.MSGID.all = 0x9555AA1A;
//	 ECanbMboxes.MBOX27.MSGID.all = 0x9555AA1B;
//	 ECanbMboxes.MBOX28.MSGID.all = 0x9555AA1C;
//	 ECanbMboxes.MBOX29.MSGID.all = 0x9555AA1D;
//	 ECanbMboxes.MBOX30.MSGID.all = 0x9555AA1E;
//	 ECanbMboxes.MBOX31.MSGID.all = 0x9555AA1F;
}
//==========================================================
//CAN邮箱的收发字节设置
void mail_length(void)
{

	 ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8;
	 ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX2.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX3.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX4.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX5.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX6.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX7.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX8.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX9.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX10.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX11.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX12.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX13.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX14.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;
//
//	 ECanaMboxes.MBOX16.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX17.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX18.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX19.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX20.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX21.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX22.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX23.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX24.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX25.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX26.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX27.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX28.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX29.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX30.MSGCTRL.bit.DLC = 8;
//	 ECanaMboxes.MBOX31.MSGCTRL.bit.DLC = 8;

}
//==========================================================
//配置邮箱的数据
void mail_Data(void)
{
	//高低8位数据
//	ECanaMboxes.MBOX0.MDL.all = 0x00001123;
//	ECanaMboxes.MBOX0.MDH.all = 0x00001321;

//	ECanaMboxes.MBOX1.MDL.all = 0x22222222;
//	ECanaMboxes.MBOX1.MDH.all = 0x22222222;
//
//	ECanaMboxes.MBOX2.MDL.all = 0x33333333;
//	ECanaMboxes.MBOX2.MDH.all = 0x33333333;
//
//	ECanaMboxes.MBOX3.MDL.all = 0x44444444;
//	ECanaMboxes.MBOX3.MDH.all = 0x44444444;
//
//	ECanaMboxes.MBOX4.MDL.all = 0x55555555;
//	ECanaMboxes.MBOX4.MDH.all = 0x55555555;
//
//	ECanaMboxes.MBOX5.MDL.all = 0x66666666;
//	ECanaMboxes.MBOX5.MDH.all = 0x66666666;
//
//	ECanaMboxes.MBOX6.MDL.all = 0x77777777;
//	ECanaMboxes.MBOX6.MDH.all = 0x77777777;
//
//	ECanaMboxes.MBOX7.MDL.all = 0x88888888;
//	ECanaMboxes.MBOX7.MDH.all = 0x88888888;
//
//	ECanaMboxes.MBOX8.MDL.all = 0x99999999;
//	ECanaMboxes.MBOX8.MDH.all = 0x99999999;
//
//	ECanaMboxes.MBOX9.MDL.all = 0xaaaaaaaa;
//	ECanaMboxes.MBOX9.MDH.all = 0xaaaaaaaa;
//
//	ECanaMboxes.MBOX10.MDL.all = 0xbbbbbbbb;
//	ECanaMboxes.MBOX10.MDH.all = 0xbbbbbbbb;
//
//	ECanaMboxes.MBOX11.MDL.all = 0xcccccccc;
//	ECanaMboxes.MBOX11.MDH.all = 0xcccccccc;
//
//	ECanaMboxes.MBOX12.MDL.all = 0xdddddddd;
//	ECanaMboxes.MBOX12.MDH.all = 0xdddddddd;
//
//	ECanaMboxes.MBOX13.MDL.all = 0xeeeeeeee;
//	ECanaMboxes.MBOX13.MDH.all = 0xeeeeeeee;
//
//	ECanaMboxes.MBOX14.MDL.all = 0xffffffff;
//	ECanaMboxes.MBOX14.MDH.all = 0xffffffff;
//
//	ECanaMboxes.MBOX15.MDL.all = 0x00001233;
//	ECanaMboxes.MBOX15.MDH.all = 0x00003211;

	// 低8位数据

//	ECanaMboxes.MBOX16.MDL.all = 0x00005444;
//	ECanaMboxes.MBOX16.MDH.all = 0x00005544;
//
//	ECanaMboxes.MBOX17.MDL.all = 0x11111111;
//	ECanaMboxes.MBOX17.MDH.all = 0x11111111;
//
//	ECanaMboxes.MBOX18.MDL.all = 0x22222222;
//	ECanaMboxes.MBOX18.MDH.all = 0x22222222;
//
//	ECanaMboxes.MBOX19.MDL.all = 0x33333333;
//	ECanaMboxes.MBOX19.MDH.all = 0x33333333;
//
//	ECanaMboxes.MBOX20.MDL.all = 0x44444444;
//	ECanaMboxes.MBOX20.MDH.all = 0x44444444;
//
//	ECanaMboxes.MBOX21.MDL.all = 0x55555555;
//	ECanaMboxes.MBOX21.MDH.all = 0x55555555;
//
//	ECanaMboxes.MBOX22.MDL.all = 0x66666666;
//	ECanaMboxes.MBOX22.MDH.all = 0x66666666;
//
//	ECanaMboxes.MBOX23.MDL.all = 0x77777777;
//	ECanaMboxes.MBOX23.MDH.all = 0x77777777;
//
//	ECanaMboxes.MBOX24.MDL.all = 0x88888888;
//	ECanaMboxes.MBOX24.MDH.all = 0x88888888;
//
//	ECanaMboxes.MBOX25.MDL.all = 0x99999999;
//	ECanaMboxes.MBOX25.MDH.all = 0x99999999;
//
//	ECanaMboxes.MBOX26.MDL.all = 0xaaaaaaaa;
//	ECanaMboxes.MBOX26.MDH.all = 0xaaaaaaaa;
//
//	ECanaMboxes.MBOX27.MDL.all = 0xbbbbbbbb;
//	ECanaMboxes.MBOX27.MDH.all = 0xbbbbbbbb;
//
//	ECanaMboxes.MBOX28.MDL.all = 0xcccccccc;
//	ECanaMboxes.MBOX28.MDH.all = 0xcccccccc;
//
//	ECanaMboxes.MBOX29.MDL.all = 0xdddddddd;
//	ECanaMboxes.MBOX29.MDH.all = 0xdddddddd;
//
//	ECanaMboxes.MBOX30.MDL.all = 0xeeeeeeee;
//	ECanaMboxes.MBOX30.MDH.all = 0xeeeeeeee;
//
//	ECanaMboxes.MBOX31.MDL.all = 0xffffffff;
//	ECanaMboxes.MBOX31.MDH.all = 0xffffffff;


	//CANB
	//高低8位数据
//	ECanbMboxes.MBOX0.MDL.all = 0xaaaaaaaa;
//	ECanbMboxes.MBOX0.MDH.all = 0xdddddddd;
//
//	ECanbMboxes.MBOX1.MDL.all = 0x22222222;
//	ECanbMboxes.MBOX1.MDH.all = 0x22222222;
//
//	ECanbMboxes.MBOX2.MDL.all = 0x33333333;
//	ECanbMboxes.MBOX2.MDH.all = 0x33333333;
//
//	ECanbMboxes.MBOX3.MDL.all = 0x44444444;
//	ECanbMboxes.MBOX3.MDH.all = 0x44444444;
//
//	ECanbMboxes.MBOX4.MDL.all = 0x55555555;
//	ECanbMboxes.MBOX4.MDH.all = 0x55555555;
//
//	ECanbMboxes.MBOX5.MDL.all = 0x66666666;
//	ECanbMboxes.MBOX5.MDH.all = 0x66666666;
//
//	ECanbMboxes.MBOX6.MDL.all = 0x77777777;
//	ECanbMboxes.MBOX6.MDH.all = 0x77777777;
//
//	ECanbMboxes.MBOX7.MDL.all = 0x88888888;
//	ECanbMboxes.MBOX7.MDH.all = 0x88888888;
//
//	ECanbMboxes.MBOX8.MDL.all = 0x99999999;
//	ECanbMboxes.MBOX8.MDH.all = 0x99999999;
//
//	ECanbMboxes.MBOX9.MDL.all = 0xaaaaaaaa;
//	ECanbMboxes.MBOX9.MDH.all = 0xaaaaaaaa;
//
//	ECanbMboxes.MBOX10.MDL.all = 0xbbbbbbbb;
//	ECanbMboxes.MBOX10.MDH.all = 0xbbbbbbbb;
//
//	ECanbMboxes.MBOX11.MDL.all = 0xcccccccc;
//	ECanbMboxes.MBOX11.MDH.all = 0xcccccccc;
//
//	ECanbMboxes.MBOX12.MDL.all = 0xdddddddd;
//	ECanbMboxes.MBOX12.MDH.all = 0xdddddddd;
//
//	ECanbMboxes.MBOX13.MDL.all = 0xeeeeeeee;
//	ECanbMboxes.MBOX13.MDH.all = 0xeeeeeeee;
//
//	ECanbMboxes.MBOX14.MDL.all = 0xffffffff;
//	ECanbMboxes.MBOX14.MDH.all = 0xffffffff;
//
//	ECanbMboxes.MBOX15.MDL.all = 0x00001233;
//	ECanbMboxes.MBOX15.MDH.all = 0x00003211;
//
//	 //低8位数据
//
//	 ECanbMboxes.MBOX16.MDL.all = 0x00005444;
//	 ECanbMboxes.MBOX16.MDH.all = 0x00005544;
//
//	 ECanbMboxes.MBOX17.MDL.all = 0x11111111;
//	 ECanbMboxes.MBOX17.MDH.all = 0x11111111;
//
//	 ECanbMboxes.MBOX18.MDL.all = 0x22222222;
//	 ECanbMboxes.MBOX18.MDH.all = 0x22222222;
//
//	 ECanbMboxes.MBOX19.MDL.all = 0x33333333;
//	 ECanbMboxes.MBOX19.MDH.all = 0x33333333;
//
//	 ECanbMboxes.MBOX20.MDL.all = 0x44444444;
//	 ECanbMboxes.MBOX20.MDH.all = 0x44444444;
//
//	 ECanbMboxes.MBOX21.MDL.all = 0x55555555;
//	 ECanbMboxes.MBOX21.MDH.all = 0x55555555;
//
//	 ECanbMboxes.MBOX22.MDL.all = 0x66666666;
//	 ECanbMboxes.MBOX22.MDH.all = 0x66666666;
//
//	 ECanbMboxes.MBOX23.MDL.all = 0x77777777;
//	 ECanbMboxes.MBOX23.MDH.all = 0x77777777;
//
//	 ECanbMboxes.MBOX24.MDL.all = 0x88888888;
//	 ECanbMboxes.MBOX24.MDH.all = 0x88888888;
//
//	 ECanbMboxes.MBOX25.MDL.all = 0x99999999;
//	 ECanbMboxes.MBOX25.MDH.all = 0x99999999;
//
//	 ECanbMboxes.MBOX26.MDL.all = 0xaaaaaaaa;
//	 ECanbMboxes.MBOX26.MDH.all = 0xaaaaaaaa;
//
//	 ECanbMboxes.MBOX27.MDL.all = 0xbbbbbbbb;
//	 ECanbMboxes.MBOX27.MDH.all = 0xbbbbbbbb;
//
//	 ECanbMboxes.MBOX28.MDL.all = 0xcccccccc;
//	 ECanbMboxes.MBOX28.MDH.all = 0xcccccccc;
//
//	 ECanbMboxes.MBOX29.MDL.all = 0xdddddddd;
//	 ECanbMboxes.MBOX29.MDH.all = 0xdddddddd;
//
//	 ECanbMboxes.MBOX30.MDL.all = 0xeeeeeeee;
//	 ECanbMboxes.MBOX30.MDH.all = 0xeeeeeeee;
//
//	 ECanbMboxes.MBOX31.MDL.all = 0xffffffff;
//	 ECanaMboxes.MBOX31.MDH.all = 0xffffffff;
}
//==========================================================
//禁止邮箱中断子函数 不需要修改
void CANMIM_interrupt(void)
{
  		/* Write to the mailbox RAM field */
  		EALLOW;
  		ECanaRegs.CANMIM.all = 0xFFFFFFFF; //enable interrupt of mailbox//邮箱中断屏蔽寄存器 使能
}
//==========================================================
//中断打开子函数
void CANMIMI_interrupt_OPEN(void)
{
	 EALLOW;

		    ECanaShadow.CANMIM.all=ECanaRegs.CANMIM.all;
		    ECanaShadow.CANMIM.bit.MIM16=1;
		    ECanaRegs.CANMIM.all=ECanaShadow.CANMIM.all;

		    ECanaShadow.CANMIL.all = ECanaRegs.CANMIL.all;
		    ECanaShadow.CANMIL.all = 0;              // 1-32号邮箱中断在中断线0上产生
		    ECanaRegs.CANMIL.all = ECanaShadow.CANMIL.all;

		    ECanaShadow.CANGIM.all = ECanaRegs.CANGIM.all;
		    ECanaShadow.CANGIM.bit.I0EN = 1 ;              //  中断线0使能
		    ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all;

		    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
		    ECanaShadow.CANMC.bit.STM = 0;    // 0-Normal
		    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

	EDIS;

		    EALLOW;  // This is needed to write to EALLOW protected registers
		    PieVectTable.ECAN0INTA = &ECAN0INTA_ISR;//R-CAN1  接收后中断函数
		    EDIS;   // This is needed to disable write to EALLOW protected registers

		    IER |=M_INT9;// 开CPU中断1~9(必须开放对应的CPU级中断口)

		    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
		    PieCtrlRegs.PIEIER9.bit.INTx5=1;     //R-CAN0  接收邮箱

		    EINT;//开总中断
		    ERTM;//使能实时中断(CPU级的)
}
//==========================================================
//CAN自我检测功能,仅需要的时候才进行修改
void CAN_SelfTestMode(void)
{

		EALLOW;
		ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
		ECanaShadow.CANMC.bit.STM = 0;    // Configure CAN for self-test mode//自动测试模式位
		ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
		EDIS;

		EALLOW;
		ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
		ECanbShadow.CANMC.bit.STM = 0;    // Configure CAN for self-test mode
		ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
		EDIS;

}

  1. 中断服务函数,在DSP2833x_DefaultIsr.c中找到ECAN0INTA_ISR。
// INT9.5
interrupt void ECAN0INTA_ISR(void)  // eCAN-A
{
    if(ECanaRegs.CANRMP.all==0x00000002)//RX get after flag and int   BOX1
    {
        ECanaRegs.CANRMP.all = 0x00000002;//clear GMIF1
        TestMbox1 = ECanaMboxes.MBOX1.MDL.all;
        TestMbox2 = ECanaMboxes.MBOX1.MDH.all;
        TestMbox3 = ECanaMboxes.MBOX1.MSGID.all;//从外部接收邮箱1的ID,1为接收邮箱(CANMD)
    }
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}

7. 程序调试

  1. 编译
  2. debug
  3. 在变量观测表中添加观察变量在这里插入图片描述
  4. 全速运行程序

在这里插入图片描述
可以看到黄色的数据一直在变换。
程序中,loopcount’为发送成功计数,会一直在递增。
TESTMbox1-2为mail0邮箱0发送的数据,0-1000循环发送。低位TESTMbox1永远比高位TESTMbox2小1。
TESTMbox3为ID号。

  1. 打开ZCANPRO,配置参数,波特率为1mbps,并根据实际串口选择连接。可以看到数据在源源不断的更新。
    在这里插入图片描述

  2. 通过ZCANPRO发送数据,DSP接收数据。

![在这里插入图片描述](https://img-blog.csdnimg.cn/2021070516595242.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNjkzMzEw,size_16,color_FFFFFF,t_70
#pic_center)
根据压力测试,对于一个数据发送10次并且每次发送100帧,可以有较高成功率的接收到。根据自己的需求发送数据,配置帧ID等。
点击立即发送。可以在CCS的变量表中看到数据的变化。如下图所示。
200789对应的就是数据中的低八位:00031055
4181对应的就是数据中的高八位:00001055
在这里插入图片描述
在这里插入图片描述

  • 32
    点赞
  • 243
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
### 回答1: dsp28335是德州仪器公司推出的一款数字信号处理器芯片,具有高性能和可靠性。CAN通讯是一种常用的数据通信协议,可实现多个设备之间的数据传输和交互。 编写dsp28335的CAN通信数据收发程序主要包括以下几个步骤: 首先,需要初始化CAN控制器寄存器,包括配置波特率、接收和发送缓冲区、屏蔽和接收代码等。可以通过读写寄存器的方式来完成初始化。 其次,需要设置CAN控制器的接收模式。可以选择监听模式或自发自收模式,监听模式用于接收其他设备发送的数据,自发自收模式用于向其他设备发送数据并接收回应。 然后,在主程序中编写数据发送和接收的相关代码。对于数据发送,通过设置发送缓冲区、设置发送标识符和发送数据来实现。对于数据接收,通过轮询接收缓冲区和接收标识符来接收其他设备发送的数据。 最后,需要处理接收到的数据。根据接收到的数据类型进行相应的处理,例如进行数据解析、控制其他外设的操作等。 为了确保数据的可靠性和稳定性,还需要进行错误处理和异常情况的处理。例如,当发送或接收错误时,需要进行相应的处理,比如重新发送数据或记录错误信息。 综上所述,编写dsp28335的CAN通信数据收发程序需要进行初始化设置、编写发送和接收代码、处理接收到的数据以及进行错误处理。通过合理的编程和调试,可以实现稳定可靠的CAN通信。 ### 回答2: DSP28335是德州仪器公司推出的一款数字信号处理器,它具有多个外设接口,包括CAN(Controller Area Network)通信接口。下面是一个简单的DSP28335 CAN通信数据收发程序的示例: 1. 配置CAN控制器: 首先,需要设置CAN寄存器的控制位和波特率,例如,设置波特率为500 kbps,可以使用下面的代码: CAN_CTL = 0x0410; CAN_BRPE = 0; CAN_BTR = 0x3804; 2. 发送数据: 要发送数据,需要将数据写入到CAN的发送邮箱中,并设置相应的标识符。例如,将数据0x55发送到标识符为0x100的邮箱中,可以使用下面的代码: CAN_TX_R0_ID = 0x100; CAN_TX_R0_DLC = 1; CAN_TX_R0_DATA[0] = 0x55; CAN_TXR0_CMD = 0x0600; 3. 接收数据: 要接收数据,需要检测CAN的接收邮箱是否有数据到达,并从接收寄存器中读取数据和标识符。例如,可以使用下面的代码接收数据: if (CAN_RX_SR & 0x1) { int id = CAN_RX_MSGID; int data = CAN_RX_DATA[0]; // 处理接收到的数据和标识符 } 以上是一个简单的DSP28335 CAN通信数据收发程序的示例,可以根据实际需求进行相应的修改和扩展。 ### 回答3: DSP28335是一种数字信号处理器,它具有CAN通信功能。CAN(Controller Area Network)是一种常用于实时应用的串行通信协议。 DSP28335的CAN通信数据收发程序涉及以下步骤: 1. 初始化CAN控制器:首先,我们需要对CAN控制器进行初始化设置。这包括设置波特率、配置CAN控制寄存器、使能接收中断等。 2. 配置发送消息对象:接下来,我们需要配置发送消息对象。发送消息对象包含了要发送的数据和相关的控制信息。我们需要设置发送消息对象的标识符、数据长度和数据内容。 3. 发送数据:一旦发送消息对象被配置好,我们可以通过向CAN控制器的发送邮箱写入发送消息对象来触发数据的发送。 4. 接收数据:为了接收CAN数据帧,我们需要配置接收邮箱和接收过滤器。然后,可以通过检查接收邮箱是否非空来判断是否有新数据到达。如果接收邮箱非空,我们可以从中读取接收到的数据。 5. 处理数据:接收到数据后,我们可以根据数据的标识符和内容进行相应的处理。可以根据应用需求,使用数据进行控制操作、传输数据等。 需要注意的是,CAN通信是一种广播式的通信方式,即一条总线上的所有节点都可以收到发送的数据。因此,在设计CAN通信程序时,需要考虑如何区分和处理不同的数据帧。 综上所述,DSP28335的CAN通信数据收发程序主要涉及初始化CAN控制器、配置发送消息对象、发送数据、配置接收邮箱、接收数据和处理数据等步骤。这样的程序能够实现DSP28335与其他CAN设备之间的数据通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EnzoReventon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值