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

📄 candsp.c

📁 处理器采用TI公司的TMS320LF2407
💻 C
字号:
////////////////////////////////////////////////////////////////////
//File: CanDSP.c
//Designed by: Xiaofei Qin
//Device type: TMS320LF2407
//Date: 2008-09-17
/////////////////////////////////////////////////////////////////////

#include "2407c.h"
#include "CanDSP.h"
#include "mydatatype.h"

/***************Variables Definition*******************/
UINT DSPCanRX0Buf[9];
UINT DSPCanRX3Buf[9];
UINT DSPCanTXBuf[8];
UINT DSPCanRX0FIFO[DSPRXFIFODEPTH][9];	//RX0的接收fifo
										//每帧的第9字节用来存放此帧的字节个数
UINT DSPCanRX0FIFONEFlag=0;				//RX0接收fifo非空标志
UINT DSPCanRX0FIFOHead=0;				//RX0fifo的头
UINT DSPCanRX0FIFOTail=0;				//RX0fifo的尾
UINT DSPCanRX3FIFO[DSPRXFIFODEPTH][9];	//RX3的接收fifo
										//每帧的第9字节用来存放此帧的字节个数
UINT DSPCanRX3FIFONEFlag=0;				//RX3接收fifo非空标志
UINT DSPCanRX3FIFOHead=0;				//RX3fifo的头
UINT DSPCanRX3FIFOTail=0;				//RX3fifo的尾
UINT DSPCanFramBuf[9];					//帧弹出时的临时缓冲器

/*****************Functions Definition*********************/
//DSP的CAN模块初始化函数
//此函数只支持标准ID(11bits),不支持扩展ID
//该函数将RB0与RB3用来接收,将RB4,RB5用来发送,RB1,2未用
//波特率设置为125k
//参数1:接收邮箱RB0的SID屏蔽器
//参数2:接收邮箱RB0的SID
//参数3:接收邮箱RB3的SID屏蔽器
//参数4:接收邮箱RB3的SID
//参数5:波特率(50-50k,100-100k,250-250k,500-500k,1000-1M,others-100k)
//!!注意!!DSPCAN的mask与mcp2515的mask逻辑上是反的
UINT DSPCan_Init(UINT SIDmask0,UINT SIDRb0,UINT SIDmask1,UINT SIDRb3,UINT bitrate)
{
	UINT mytimer=0;
	UINT tmout=3000;
	UINT temp;
	
	(*MCRB)|=0x00c0;		//设置IOPC6、IOPC7为CANRX,CANTX 
    (*CANIFR)|=0x007f;		//清所有CAN中断标志
    (*CANTCR)|=0xff00;
    (*CANRCR)|=0xf0f0;
  
    temp=(SIDmask0<<2);
    temp|=0x0003;
    (*CANLAM0H)=temp;		//设置接收邮箱0(1)的屏蔽ID寄存器
	(*CANLAM0L)=0xffff;
	temp=(SIDmask1<<2);
    temp|=0x0003;
    (*CANLAM1H)=temp;		//设置接收邮箱2(3)的屏蔽ID寄存器
	(*CANLAM1L)=0xffff;
	    	
	mytimer=tmout;
	*CANMCR=0x1000;			//CCR=1改变配置请求
	while(((*CANGSR)&0x0010)==0)//只有当CCE=1时可配置BCR2、BCR1寄存器
	{
		mytimer--;
		if(mytimer==0)
			return 1;	//超时

	}
	switch(bitrate)
	{
	case 50:
		//波特率50kb/s
		*CANBCR2=0x0027;//波特率预分频寄存器 (RBP+1)=39+1=40
		*CANBCR1=0x005e;//波特率设置为50K=40M/40/20 bittime=(11+1)+(6+1)+1=20	
		break;
	case 100:
		//波特率100kb/s
		*CANBCR2=0x0013;//波特率预分频寄存器 (RBP+1)=19+1=20
		*CANBCR1=0x005e;//波特率设置为100K=40M/20/20 bittime=(11+1)+(6+1)+1=20	
		break;
	case 250:
		//波特率250kb/s
		*CANBCR2=0x0007;//波特率预分频寄存器 (RBP+1)=7+1=8
		*CANBCR1=0x005e;//波特率设置为250K=40M/8/20 bittime=(11+1)+(6+1)+1=20	
		break;
	case 500:
		//波特率500kb/s
		*CANBCR2=0x0003;//波特率预分频寄存器 (RBP+1)=3+1=4
		*CANBCR1=0x005e;//波特率设置为500K=40M/4/20 bittime=(11+1)+(6+1)+1=20	
		break;
	case 1000:
		//波特率1000kb/s
		*CANBCR2=0x0001;//波特率预分频寄存器 (RBP+1)=1+1=2
		*CANBCR1=0x005e;//波特率设置为1000K=40M/2/20 bittime=(11+1)+(6+1)+1=20	
		break;
	default:
		//波特率100kb/s
		*CANBCR2=0x0013;//波特率预分频寄存器 (RBP+1)=19+1=20
		*CANBCR1=0x005e;//波特率设置为100K=40M/20/20 bittime=(11+1)+(6+1)+1=20	
		break;		
	}
	(*CANMCR)&=0xefff;		//CCR=0改变配置结束请求
	mytimer=tmout;
	while(((*CANGSR)&0x0010)==1)//只有当CCE=0时BCR2、BCR1寄存器配置成功
	{
		mytimer--;
		if(mytimer==0)
			return 1;	//超时
	}
	
	/*接收邮箱0初始化*/
    *CANMDER=0x0000;		//不使能邮箱
	*CANMCR=0x0100;			//CDR=1,数据区改变请求 
	temp=(SIDRb0<<2)&0x1ffc;
	temp|=0x4000;			//设置邮箱0的控制字及ID
	*CANMSGID0H=temp;		//IDE=0(标准帧),AME=1(使能接收mask),AAM=0(不自动回复远程帧)
	*CANMSGID0L=0xffff;
/*	*CANMSGCTRL0=0x00;		//设置控制域,数据长度DCL=0 非远程帧
	*CANMBX0A = 0x0000;
	*CANMBX0B = 0x0000;   
	*CANMBX0C = 0x0000;
	*CANMBX0D = 0x0000;*/
	
	/*接收邮箱3初始化*/
    *CANMDER=0x0000;		//不使能邮箱
	*CANMCR=0x0100;			//CDR=1,数据区改变请求
	temp=(SIDRb3<<2)&0x1ffc;
	temp|=0x4000;			//设置邮箱3的控制字及ID
	*CANMSGID3H=temp;		//IDE=0(标准帧),AME=1(使能接收mask),AAM=0(不自动回复远程帧)
	*CANMSGID3L=0xffff;
/*	*CANMSGCTRL3 = 0x00;       		//设置控制域,数据长度DCL=4 非远程帧
	*CANMBX3A = 0x0000;   
	*CANMBX3B = 0x0000;   
	*CANMBX3C = 0x0000;
	*CANMBX3D = 0x0000;*/
			
	/*发送邮箱4初始化*/ 
	*CANMDER=0x0000;		//不使能邮箱
	*CANMCR=0x0100;			//CDR=1,数据区改变请求 
	*CANMSGID4H=0;       
	*CANMSGID4L=0;
	*CANMSGCTRL4=0;
	*CANMBX4A=0xff;
	*CANMBX4B=0xff;
	*CANMBX4C=0xff;
	*CANMBX4D=0xff;

	/*发送邮箱5初始化*/
	*CANMDER=0x0000;		//不使能邮箱
	*CANMCR=0x0100;			//CDR=1,数据区改变请求 
	*CANMSGID5H=0;       
	*CANMSGID5L=0;
	*CANMSGCTRL5=0;
	*CANMBX5A=0xff;
	*CANMBX5B=0xff;
	*CANMBX5C=0xff;
	*CANMBX5D=0xff;
	
    *CANMCR=0x0480;			//DBO=1,CDR=0,ABO=1,STM=0正常工作模式
	*CANMDER=0x00b9;		//ME0=ME3=ME4=ME5=1,邮箱3接收,邮箱2发送
    (*CANIFR)|=0x007f;		//清所有CAN中断标志
    (*CANTCR)|=0xff00;
    (*CANRCR)|=0xf0f0;
	*CANIMR=0x8984;			//邮箱3,0接收中断使能,总线关闭中断使能,低中断优先级
//	*CANIMR=0xbfff;
	(*IFR)|=0x10;			/*清INT5中断标志*/
	(*IMR)|=0x10;			/*开INT5中断*/
	
    return 0;
}

void interrupt dspcanisr()//CANdsp中断ISR
{
	int i;
	UINT piv;
	
	piv=*PIVR;
	
	switch(piv)
	{
	case 0x40:
		/*MB0 接收数据准备好*/
		if(((*CANIFR)&0x0100)==0x0100)			
		{
			/*数据放入缓冲区*/
			DSPCanRX0Buf[8]=(*CANMSGCTRL0)&0x000f;
			for(i=0;i<4;i++)
			{
				DSPCanRX0Buf[i*2]=(*(CANMBX0A+i))&0x00ff;
				DSPCanRX0Buf[i*2+1]=((*(CANMBX0A+i))>>8)&0x00ff;
			}
			/*向RMP0写1清除RMP0(中断标志位MIF0)*/
			(*CANRCR)|=0x0010;
			PushDSPCanRX0FIFO();
		} 
		/*MB3 接收数据准备好*/
		if(((*CANIFR)&0x0800)==0x0800)			
		{
			/*数据放入缓冲区*/
			DSPCanRX3Buf[8]=(*CANMSGCTRL3)&0x000f;
			for(i=0;i<4;i++)
			{
				DSPCanRX3Buf[i*2]=(*(CANMBX3A+i))&0x00ff;
				DSPCanRX3Buf[i*2+1]=((*(CANMBX3A+i))>>8)&0x00ff;
			} 
			/*向RMP3写1清除RMP3(中断标志位MIF3)*/
			(*CANRCR)|=0x0080;
			PushDSPCanRX3FIFO();
		}
		break;
	case 0x41:
		/*Can总线关闭*/  
		if(((*CANIFR)&0x0004)==0x0004)			
		{
			/*向CANIFR写1清除BOIF*/
			(*CANIFR)|=0x0004;   
		}
		break;
	default:
	    break;
	}
	asm("	CLRC	INTM");
}

//DSPCAN发送函数
//参数1:发送缓冲器编号
//参数2:目标ID
//参数3:是否远程帧
//参数4:发送字节数
//参数5:指向待发送的数据
void DSPCan_TxFun(UINT TxBNO,UINT SID,UINT RemoteF,UINT DLC,UINT *pbuf)
{
	int i,j;
	UINT IDtemp,Ctltemp,TCRtemp;
	UINT mytimer=0;
	UINT tmout=30000;
	
	if(DLC>8)
		DLC=8;
	IDtemp=(SID<<2)&0x1ffc;
	RemoteF=(RemoteF<<4)&0x0010;
	if(RemoteF!=0)
		DLC=0;
	Ctltemp=RemoteF|DLC;
	
	switch(TxBNO)
	{
	case 4:
		TCRtemp=(*CANTCR);
		while(TCRtemp&0x0040)
		{
			mytimer++;
			if(mytimer>tmout)
			{
				i++;
				return;
			}
			TCRtemp=(*CANTCR);
		}
		(*CANMDER)&=0xffef;		//不使能邮箱4
		(*CANMCR)|=0x0100;		//CDR=1,数据改变请求
		(*CANMSGID4H)=IDtemp;
		(*CANMSGID4L)=0;
		(*CANMSGCTRL4)=Ctltemp;
		for(i=0;i<DLC;i++)		//邮箱4中数据更新
		{
			j=(i>>1)&0x000f;
			if(i&0x0001)
			{
				(*(CANMBX4A+j))&=0x00ff;
				(*(CANMBX4A+j))|=(((pbuf[i])<<8)&0xff00);
			}
			else
			{
				(*(CANMBX4A+j))&=0xff00;
				(*(CANMBX4A+j))|=((pbuf[i])&0x00ff);
			}
		}
		(*CANMDER)|=0x0010;		//使能邮箱4
		(*CANMCR)&=0xfeff;		//CDR=0
		(*CANTCR)|=0x0040;		//请求发送
		break;
	case 5:
		TCRtemp=(*CANTCR);
		while(TCRtemp&0x0080)
		{
			mytimer++;
			if(mytimer>tmout)
			{
				i++;
				return;
			}
			TCRtemp=(*CANTCR);
		}
		(*CANMDER)&=0xffdf;		//不使能邮箱5
		(*CANMCR)|=0x0100;		//CDR=1,数据改变请求
		(*CANMSGID5H)=IDtemp;
		(*CANMSGID5L)=0;
		(*CANMSGCTRL5)=Ctltemp;    	
		for(i=0;i<DLC;i++)		//邮箱4中数据更新
		{
			j=(i>>1)&0x000f;
			if(i&0x0001)
			{
				(*(CANMBX5A+j))&=0x00ff;
				(*(CANMBX5A+j))|=(((pbuf[i])<<8)&0xff00);
			}
			else
			{
				(*(CANMBX5A+j))&=0xff00;
				(*(CANMBX5A+j))|=((pbuf[i])&0x00ff);
			}
		}
		(*CANMDER)|=0x0020;		//使能邮箱5
		(*CANMCR)&=0xfeff;		//CDR=0
		(*CANTCR)|=0x0080;		//请求发送
		break;
	default:
		break;
	}
}
//向RX0fifo压入一帧
void PushDSPCanRX0FIFO()
{
	int i;
	
	DSPCanRX0FIFOHead++;
	if(DSPCanRX0FIFOHead>=DSPRXFIFODEPTH)
		DSPCanRX0FIFOHead=0;
	if(DSPCanRX0FIFOHead==DSPCanRX0FIFOTail)//缓冲区满,覆盖最早的帧
	{
		DSPCanRX0FIFOTail++;
		if(DSPCanRX0FIFOTail>=DSPRXFIFODEPTH)
			DSPCanRX0FIFOTail=0;
	}
	DSPCanRX0FIFO[DSPCanRX0FIFOHead][8]=DSPCanRX0Buf[8];
	for(i=0;i<DSPCanRX0FIFO[DSPCanRX0FIFOHead][8];i++)
	{
		DSPCanRX0FIFO[DSPCanRX0FIFOHead][i]=DSPCanRX0Buf[i];
	}
	DSPCanRX0FIFONEFlag=1;
}
//向RX3fifo压入一帧
void PushDSPCanRX3FIFO()
{
	int i;
	
	DSPCanRX3FIFOHead++;
	if(DSPCanRX3FIFOHead>=DSPRXFIFODEPTH)
		DSPCanRX3FIFOHead=0;
	if(DSPCanRX3FIFOHead==DSPCanRX3FIFOTail)//缓冲区满,覆盖最早的帧
	{
		DSPCanRX3FIFOTail++;
		if(DSPCanRX3FIFOTail>=DSPRXFIFODEPTH)
			DSPCanRX3FIFOTail=0;
	}
	DSPCanRX3FIFO[DSPCanRX3FIFOHead][8]=DSPCanRX3Buf[8];
	for(i=0;i<DSPCanRX3FIFO[DSPCanRX3FIFOHead][8];i++)
	{
		DSPCanRX3FIFO[DSPCanRX3FIFOHead][i]=DSPCanRX3Buf[i];
	}
	DSPCanRX3FIFONEFlag=1;
}
//从RX0fifo弹出一帧到指定位置
//参数1:指向弹出帧的存储位置
void PopDSPCanRX0FIFO(UINT *pbuf)
{
	int i;

	if(DSPCanRX0FIFOTail==DSPCanRX0FIFOHead)	//缓冲区空
	{
		DSPCanRX0FIFONEFlag=0;
		return;
	}
	DSPCanRX0FIFOTail++;
	if(DSPCanRX0FIFOTail>=DSPRXFIFODEPTH)
		DSPCanRX0FIFOTail=0;
	pbuf[8]=DSPCanRX0FIFO[DSPCanRX0FIFOTail][8];
	for(i=0;i<pbuf[8];i++)
	{
		pbuf[i]=DSPCanRX0FIFO[DSPCanRX0FIFOTail][i];
	}
	if(DSPCanRX0FIFOTail==DSPCanRX0FIFOHead)	//缓冲区空
	{
		DSPCanRX0FIFONEFlag=0;
	}
}
//从RX3fifo弹出一帧到指定位置
//参数1:指向弹出帧的存储位置
void PopDSPCanRX3FIFO(UINT *pbuf)
{
	int i;

	if(DSPCanRX3FIFOTail==DSPCanRX3FIFOHead)	//缓冲区空
	{
		DSPCanRX3FIFONEFlag=0;
		return;
	}
	DSPCanRX3FIFOTail++;
	if(DSPCanRX3FIFOTail>=DSPRXFIFODEPTH)
		DSPCanRX3FIFOTail=0;
	pbuf[8]=DSPCanRX3FIFO[DSPCanRX3FIFOTail][8];
	for(i=0;i<pbuf[8];i++)
	{
		pbuf[i]=DSPCanRX3FIFO[DSPCanRX3FIFOTail][i];
	}
	if(DSPCanRX3FIFOTail==DSPCanRX3FIFOHead)	//缓冲区空
	{
		DSPCanRX3FIFONEFlag=0;
	}
}

⌨️ 快捷键说明

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