⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 12.1.c

📁 数字信号处理器 原理、结构及应用基础-TMS320F28x所附光盘源程序C-C++ 刘和平等编著
💻 C
字号:
/**************************************************************************
**功能描述: ECAN自测试程序,CAN模块工作在自测试模式。MBX0发送到MBX16***
**MBX1发送到MBX17。该程序不停地高速背靠背传输数据,检查接数据的正确性**
**************************************************************************/
#include "DSP28_Device.h"
// Prototype statements for functions found within this file.
void mailbox_check(int32 T1, int32 T2, int32 T3);
void mailbox_read(int16 i); 
// Global variable for this example
Uint32  ErrorCount = 0; 
Uint32  MessageReceivedCount = 0;
Uint32  TestMbox1 = 0;
Uint32  TestMbox2 = 0;
Uint32  TestMbox3 = 0;

void  CAN_INIT()
{
	struct ECAN_REGS ECanaShadow;  
	EALLOW;
  	GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1; //  设置GPIOF6为CANTX 
  	GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1; //  设置GPIOF7为CANRX    	
	EDIS;
/*eCAN 控制寄存器需要32位访问。如果想向一个单独位进行写操作,编译器可能会使其进入16位访问。这儿引用了一种解决方法,就是用影子寄存器迫使进行32位访问。 把整个寄存器读入一个影子寄存器。 这个访问将是32位的。用32位写操作改变需要改的位,然后把该值拷贝回eCAN寄存器*/
    EALLOW; 
   	ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all; //  把CANTIOC读入影子寄存器
   	ECanaShadow.CANTIOC.bit.TXFUNC = 1;              //  外部引脚I/O使能标志位。
//  TXFUNC=1  CANTX引脚被用于CAN发送功能。
//  TXFUNC=0  CANTX引脚被作为通用I/O引脚被使用 
	ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all; //  把配置好的寄存器值回写
    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;  //  把CANRIOC读影子寄存器
	ECanaShadow.CANRIOC.bit.RXFUNC = 1;              //  外部引脚I/O使能标志位。
//  RXFUNC=1  CANRX引脚被用于CAN接收功能。
//  RXFUNC=0  CANRX引脚被作为通用I/O引脚被使用。
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;  //  把配置好的寄存器值回写
    EDIS;
//  在配置邮箱ID值之前,CANME对应的位必须复位,
//  如果CANME寄存器中对应的位被置位,则ID写入操作无效。
ECanaRegs.CANME.all = 0;                 //  复位所有的邮箱
    ECanaMboxes.MBOX0.MID.all = 0x9555AAA0;  //  配置发送邮箱0的ID:扩展标识符29位
    ECanaMboxes.MBOX1.MID.all = 0x9555AAA1;  //  配置发送邮箱1的ID:扩展标识符29位
    ECanaMboxes.MBOX16.MID.all = 0x9555AAA0; //  确定接收邮箱16的ID
    ECanaMboxes.MBOX17.MID.all = 0x9555AAA1; //  确定接收邮箱17的ID
    //  把邮箱0~15 配置为发送邮箱 , 把邮箱16~31 配置为接收邮箱
    ECanaRegs.CANMD.all = 0xFFFF0000; 
    ECanaRegs.CANME.all = 0xFFFFFFFF;         //  CAN模块使能对应的邮箱,
        
    ECanaMboxes.MBOX0.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX1.MCF.bit.DLC = 8;       //  把发送,接收数据的长度定义为8位
    ECanaMboxes.MBOX0.MCF.bit.RTR = 0;       //  无远程帧请求  
//  因为RTR位在复位后状态不定,因此在程序进行初始化的时候必须对该位赋值。
    ECanaMboxes.MBOX1.MCF.bit.RTR = 0;
//  把待发送的数据写入发送邮箱 
 	ECanaMboxes.MBOX0.MDRL.all = 0x00112233;
	ECanaMboxes.MBOX0.MDRH.all = 0x44556677;
	ECanaMboxes.MBOX1.MDRL.all = 0x8899AABB;
	ECanaMboxes.MBOX1.MDRH.all = 0xCCDDEEFF;	 
	EALLOW;
//  邮箱中断屏蔽寄存器。上电后所有的中断屏蔽位都清零且停止中断使能。
//  这些位允许独立屏蔽任何邮箱中断。
	ECanaRegs.CANMIM.all = 0xFFFFFFFF;  
//  CANMIM .BIT.X=1  邮箱中断被使能(X=1~31)
//  CANMIM .BIT.X=0  邮箱中断被禁止(X=1~31)
	ECanaShadow.CANMC.all = ECanaRegs.CANMC.all; //  把CANMC读入影子寄存器
	ECanaShadow.CANMC.bit.CCR = 1;               //  改变配置请求位  
	ECanaRegs.CANMC.all = ECanaShadow.CANMC.all; //  把配置好的寄存器值回写
  	EDIS;
/*CPU要求对配置寄存器CANBTC和SCC的接收屏蔽寄存器(CANGAM,LAM[0]和LAM[3])进行写操作。对该位置位后,CPU必须等待,直到CANES寄存器的CCE标志位在送入CANBTC寄存器之前为1 */
do 
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );  //  当CCE=1时可以对CANBTC进行操作。
    //  配置波特率
    EALLOW;
    ECanaShadow.CANBTC.all = ECanaRegs.CANBTC.all; //  把CANBTC读入影子寄存器
    ECanaShadow.CANBTC.bit.BRP = 149;   //  (BRP+1)=150, 最小时间单位TQ=1us
    ECanaShadow.CANBTC.bit.TSEG2 = 2;   //  位定时bit-time=(TSEG1+1)+(TSEG1+1)+1
    ECanaShadow.CANBTC.bit.TSEG1 = 3;   //  bit-time=8us, 所以波特率为125Kpbs       
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;  //  把配置好的寄存器值回写
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;   //  把CANMC读入影子寄存器
    ECanaShadow.CANMC.bit.CCR = 0 ;       //  设置CCR=0, CPU请求正常模式
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;   //  把配置好的寄存器值回写
    EDIS;
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );  //  等待 CCE 位被清零
//  配置eCAN为自测试模式,使能eCAN的增强特性
    EALLOW;
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.STM = 1;        //  配置CAN 为自测试模式
  	// CANMC.bit.STM=0,正常模式,CANMC.bit.STM=1,自测试模式
    ECanaShadow.CANMC.bit.SCM = 1;        // 选择HECC工作模式
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    EDIS;
}
void main(void)
{   
	Uint16  j;
	InitSysCtrl();     //  系统初始化程序,该子程序在DSP28_sysctrl.c中
 	DINT;              //  关闭总中断
	IER = 0x0000;      //  关闭外设中断
	IFR = 0x0000;      //  请中断标志	
	CAN_INIT();
//  开始循环发送数据
    while(1)                                
    {
       ECanaRegs.CANTRS.all = 0x00000003;          
       while(ECanaRegs.CANTA.all != 0x00000003 ) {};
       ECanaRegs.CANTA.all = 0x0000FFFF;               
       MessageReceivedCount++;
       for(j = 0; j<32;)                          
	   	{
          mailbox_read(j);                      //  把邮箱j(j=0~31)的数据读出来
          j++;
          //  mailbox_check(TestMbox1,TestMbox2,TestMbox3); // 测试程序是否正确
       }	 
    }
}
//  该函数读出邮箱序号(MBXnbr)指示的邮箱内容.
void mailbox_read(int16 MBXnbr)
{
  	volatile struct MBOX *Mailbox;
	Mailbox = &ECanaMboxes.MBOX0 + MBXnbr;
	TestMbox1 = Mailbox->MDRL.all;    	// 读出当前邮箱数据低4字节
	TestMbox2 = Mailbox->MDRH.all;        //  读出当前邮箱数据高4字节
	TestMbox3 = Mailbox->MID.all;         //  读出当前邮箱ID
} 
//  接收邮箱MBX的 MID作为MDRL 数据传输data
void mailbox_check(int32 T1,int32 T2,int32 T3)
{
	if((T1 != T3) || ( T2 != 0x89ABCDEF))
 		ErrorCount++;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -