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

📄 12.2.c

📁 数字信号处理器 原理、结构及应用基础-TMS320F28x所附光盘源程序C-C++ 刘和平等编著
💻 C
字号:
/**************************************************************
**功能描述: 2812ECAN通信程序程序,用于两块实验开发板间的相互控制**
**************************************************************/
#include "DSP28_Device.h"
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 = 0x15100000;   //  配置发送邮箱0的ID:标识符11位
    ECanaMboxes.MBOX1.MID.all = 0x15100000;   //  配置发送邮箱1的ID:标识符11位
    ECanaMboxes.MBOX16.MID.all = 0x15200000;  //  确定接收邮箱16的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 = 0x55555555;
	ECanaMboxes.MBOX0.MDRH.all = 0x55555501;
	ECanaMboxes.MBOX1.MDRL.all = 0x55555555;
	ECanaMboxes.MBOX1.MDRH.all = 0x55555502;
	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;                //  改变配置请求位  
	ECanaShadow.CANMC.bit.SCM = 1;                //  eCAN模式,所有邮箱使能 
	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,请求正常模式
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;     //  把配置好的寄存器值回写    
    EDIS;
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );  //  等待 CCE 位被清零
    EALLOW;
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.STM = 0;         //  配置CAN 为正常模式
  							           // CANMC.bit.STM=0,正常模式
							           // CANMC.bit.STM=1,自测试模式
    ECanaShadow.CANMC.bit.SCM = 1;         // 选择HECC模式
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    EDIS;
  }
 //  该函数读出邮箱序号(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
} 
void IOinit(void)
{
    EALLOW;
//  将GPIOE0~GPIOE2配置为一般I/O端口输出,作138译码  
 	GpioMuxRegs.GPEMUX.all = GpioMuxRegs.GPEMUX.all&0xfff8; 
	GpioMuxRegs.GPEDIR.all = GpioMuxRegs.GPEDIR.all|0x0007;
//  将GPIOB8~GPIOB15配置为一般I/O端口,D0~D7
	GpioMuxRegs.GPBMUX.all = GpioMuxRegs.GPBMUX.all&0x00ff; 
	EDIS;
}
int KeyIn(void)
{
 	unsigned long int i = 0;
 	EALLOW;  
//  将GPIOB8~GPIOB15配置为输入,D0~D7
	GpioMuxRegs.GPBDIR.all = GpioMuxRegs.GPBDIR.all&0x00ff;
    EDIS;   
    GpioDataRegs.GPEDAT.all = 0xfff8;                          //  选通键盘低8位
    for (i=0; i<100; i++){}                                     //  延时
//  判S1是否按下
    if ((GpioDataRegs.GPBDAT.all|0x00ff)==0xfeff)
    {
    	for (i=0; i<100000; i++){}                                  //  延时消抖动
        if ((GpioDataRegs.GPBDAT.all|0x00ff)==0xfeff)
        {
    			while ((GpioDataRegs.GPBDAT.all|0x00ff)==0xfeff)  //  判S1是否断开
    			{
    			GpioDataRegs.GPDDAT.bit.GPIOD1 = !GpioDataRegs.GPDDAT.bit.GPIOD1;
    			for (i=0; i<1000; i++){}     
    			}
    		return (1);			      
}
}
//  判S2是否按下
    if ((GpioDataRegs.GPBDAT.all|0x00ff)==0xfdff)
    {
    	for (i=0; i<100000; i++){}                                   //  延时消抖动
        if ((GpioDataRegs.GPBDAT.all|0x00ff)==0xfdff)
        {
    			while ((GpioDataRegs.GPBDAT.all|0x00ff)==0xfdff)   // 判S2是否断开
    			{
    			GpioDataRegs.GPDDAT.bit.GPIOD1 = !GpioDataRegs.GPDDAT.bit.GPIOD1;
    			for (i=0; i<1000; i++){}     
    			}
    		return (2);			      
    		}
    }
    return (0);
}
void LedOut(Uint16 led)
{
 	unsigned long int i = 0;
 	EALLOW;  
//  将GPIOB8~GPIOB15配置为输出,D0~D7
	GpioMuxRegs.GPBDIR.all = GpioMuxRegs.GPBDIR.all|0xff00;
	EDIS;
	GpioDataRegs.GPEDAT.all = 0xfffb;    //  LEDB清零
	GpioDataRegs.GPBDAT.all =-led;
	for (i=0; i<100; i++){}               //  延时
    GpioDataRegs.GPEDAT.all = 0xffff;     //  锁存高8位
	GpioDataRegs.GPEDAT.all = 0xfffa;    //  LEDA清零
	GpioDataRegs.GPBDAT.all =-(led<<8);
	for (i=0; i<100; i++){}
    GpioDataRegs.GPEDAT.all = 0xffff;     //  锁存低8位			
}
void main(void)
{   
	Uint16 dis = 0x0000;
	InitSysCtrl();           // 系统初始化程序,该子程序在DSP28_sysctrl.c中
 	DINT;                // 关闭总中断
	IER = 0x0000;         // 关闭外设中断
	IFR = 0x0000;         // 请中断标志	
	CAN_INIT();
	IOinit();
	LedOut(dis);
    while(1)                                
    {
       if (KeyIn() = =  1) 
       {
       		ECanaRegs.CANTRS.all = 0x00000001;          
       		//  while(ECanaRegs.CANTA.all != 0x00000001) {};
       		ECanaRegs.CANTA.all = 0x0000FFFF;	
       }  
       if (KeyIn() = =  2)  
       {
       		ECanaRegs.CANTRS.all = 0x00000002;          
       		//  while(ECanaRegs.CANTA.all != 0x00000002) {};
       		ECanaRegs.CANTA.all = 0x0000FFFF; 
       }      
       if(ECanaRegs.CANRMP.all = = 0x00010000)
       {
       		ECanaRegs.CANRMP.all = 0xFFFF0000;  
       		mailbox_read(16);
       		if (TestMbox2 = = 0x55555501)
       		{
       			dis = dis+1;
       			LedOut(dis);
       		}
       		if (TestMbox2 = =  0x55555502)
       		{
       			dis = dis-1;
       			LedOut(dis);
       		}
        }
    }
}

⌨️ 快捷键说明

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