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

📄 canapp.c

📁 LPC2119 CAN中断及示范
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               广州周立功单片机发展有限公司
**                                     研    究    所
**                                        产品一部 
**                                 http://www.zlgmcu.com
**-----------------------------------------------------------文件信息--------------------------------------------------------------------------------
**	文   件  	名:	CANAPP.C
** 	版  		本:	v1.0
** 	日		期:	2004年2月23日
**	描		述:	CAN模块应用接口函数说明文件。该文件中的函数,如果用户有特别的需要,可以进行修改。
********************************************************************************************************/
#define		_CANAPP_GLOBAL_
#include "INCLUDES.H"

/*
***********************************************************************************************************
**函数原型	:  	void	CANIntPrg(void)
**参数说明	:  	无
**返回值		:	无	
**说	明		:	CAN控制器中断处理函数
************************************************************************************************************/
void		CANIntPrg(void)
{
	INT32U 	j;
	uCANICR k;
	if(CANLUTerr.Word != 0 )		//LUT Error Program
	{
		//add or modify code
		j=CANLUTerrAd.Word;	
	}
	for(j=0;j<CAN_MAX_NUM;j++)
	{
		k=CANICR(j);
		if(k.Bits.RI_BIT != 0)
		{
			//add code
			WriteCANRcvCyBuf(j);	//接收中断处理
		}
		if(k.Bits.TI1_BIT != 0)
		{
			//add code
		}
		if(k.Bits.TI2_BIT != 0)
		{
			//add code
		}
		if(k.Bits.TI3_BIT != 0)
		{
			//add code
		}
		if(k.Bits.BEI_BIT != 0)
		{
			//add code
			CanBufOffLinePrg(j);	//总线错误中断处理
		}
		if(k.Bits.ALI_BIT != 0)
		{
			//add code
		}
		if(k.Bits.EPI_BIT != 0)
		{
			//add code
		}
		if(k.Bits.WUI_BIT != 0)
		{
			//add code
		}
		if(k.Bits.DOI_BIT != 0)
		{
			//add code
			ClrCanDataOver(j);	//数据溢出中断处理
		}
	}
}
/*
***********************************************************************************************************
**函数原型	:  	void	InitCAN(eCANNUM CanNum)
**参数说明	:  	CanNum	-->>	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
**返回值		:	无	
**说	明		:	本函数用于初始化CAN控制器
************************************************************************************************************/
void	InitCAN(eCANNUM CanNum)
{	
//	INT32U	*p;
	HwEnCAN(CanNum);																	
	SoftRstCAN(CanNum);	
																
	CANEWL(CanNum).Bits.EWL_BIT = USE_EWL_CAN[CanNum];										
	//初始化波特率
	CANBTR(CanNum).Word = USE_BTR_CAN[CanNum];											
	//初始化中断为非向量中断
	//VICDefVectAddr =(INT32U)CANIntPrg;
	VICVectAddr8 = (INT32U)CANIntPrg;			//中断服务程序CANIntPrg
	VICVectCntl8 = (0x20|26);					//26通道中断位向量IRQ
	VICIntEnable |=(1<<(26+ CanNum));			//使能26通道中断
	CANIER(CanNum).Word= 0x01;					//只开放接收中断											
	//配置验收滤波器
	CANAFMR.Bits.AccBP_BIT =1;	
	
	#if 	USE_eFCAN_MODE																
	CANAFMR.Bits.eFCAN_BIT =1;	
	CANSFF_sa.Bits. SADR_BIT= USE_SFF_sa_VAL;
	CANSFF_GRP_sa.Bits. SADR_BIT=USE_SFF_GRP_sa_VAL;
	CANEFF_sa.Bits. SADR_BIT= USE_EFF_sa_VAL;
	CANEFF_GRP_sa.Bits. SADR_BIT=USE_EFF_GRP_sa_VAL;
	CANENDofTable.Bits. SADR_BIT=USE_ENDoffable_VAL;
	//请根据实际需要来填写下面的验收滤波器的表格
//p=(INT32U *)(	CANAFRAM_GADR +	USE_EFF_GRP_sa_VAL);
//*p=0x20000000;
//*(p+1)=0x20000006;
	#endif
	
	//初始化模式
	CANMOD(CanNum).Bits.TPM_BIT = USE_TPM_CAN[CanNum];										
	CANMOD(CanNum).Bits. LOM_BIT = USE_MOD_CAN[CanNum];
	//初始化接收环形缓冲区
	CANRcvBufApp.FullFlag1=CANRcvBufApp.FullFlag2=CANRcvBufApp.FullFlag3=CANRcvBufApp.FullFlag4=0;
	CANRcvBufApp.ReadPoint1=CANRcvBufApp.ReadPoint2=CANRcvBufApp.ReadPoint3=CANRcvBufApp.ReadPoint4=0;
	CANRcvBufApp.WritePoint1=CANRcvBufApp.WritePoint2=CANRcvBufApp.WritePoint3=CANRcvBufApp.WritePoint4=0;
	//启动CAN
	SoftEnCAN(CanNum);
	//睡眠模式
	//CANMOD(CanNum).Bits.SM_BIT = USE_CAN_SLEEP_MOD;
}
/*
***********************************************************************************************************
**函数原型	:  	INT32U	CANSendData(eCANNUM CanNum,INT32U Cmd,P_stcTxBUF Buf)
**参数说明	:  	CanNum	-->>	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
				Cmd		à>	发送命令字
				Buf		à>	要发送的数据
**返回值		:	无	
**说	明		:	本函数用于将数据发送到CAN总线
************************************************************************************************************/
INT32U		CANSendData(eCANNUM CanNum,INT32U Cmd,P_stcTxBUF Buf)
{
	INT32U i,status=0;
	if(0 != CANSR(CanNum).Bits.TBS1_BIT)
	{
		i=SEND_TX_BUF1;
	}
	else if(0 != CANSR(CanNum).Bits.TBS2_BIT)
	{
		i=SEND_TX_BUF2;
	}
	else if(0 != CANSR(CanNum).Bits.TBS3_BIT)
	{
		i=SEND_TX_BUF3;
	}
	else
	{
		i=0xFF;
	}
	status=WriteCanTxBuf(CanNum,i,  USE_TPM_CAN[CanNum],  Buf);
	if(status == 0)
	{
		#if 1
		if(CANMOD(CanNum).Bits.SM_BIT != 0)												
		{
			CanQuitSM(CanNum);
		}
		#endif
		CanSendCmd(CanNum,Cmd,i);
		//CANMOD(CanNum).Bits.SM_BIT = USE_CAN_SLEEP_MOD;
	}
	return (status);
}
/*
***********************************************************************************************************
**函数原型	:  	INT32U	ReadCANRcvCyBuf(eCANNUM CanNum,stcRxBUF *Buf)
**参数说明	:  	CanNum	-->>	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
				Buf		à>	使用驱动接收到的缓冲区数据
**返回值		:	=0,驱动接收到数据。
				!=0,驱动没接收到数据。	
**说	明		:	本函数用于用户调用使用CAN驱动接收到的数据。
************************************************************************************************************/
INT32U	ReadCANRcvCyBuf(eCANNUM CanNum,stcRxBUF *Buf)
{
	INT32U	status=0;
	switch(CanNum)
	{
		case	CAN1:
			if((0 != CANRcvBufApp.FullFlag1) ||
				(CANRcvBufApp.ReadPoint1 != CANRcvBufApp.WritePoint1))
			{
				*Buf=CANRcvBufApp.RcvBuf[CAN1][CANRcvBufApp.ReadPoint1];
				if(++CANRcvBufApp.ReadPoint1 >= USE_CAN_RCV_BUF_SIZE)
				{
					CANRcvBufApp.ReadPoint1 =0;
				}
				CANRcvBufApp.FullFlag1=0;
			}
			else 
			{
				status=1;
			}
			break;
		case	CAN2:
			if((0 != CANRcvBufApp.FullFlag2) ||
				(CANRcvBufApp.ReadPoint2 != CANRcvBufApp.WritePoint2))
			{
				*Buf=CANRcvBufApp.RcvBuf[CAN2][CANRcvBufApp.ReadPoint2];
				if(++CANRcvBufApp.ReadPoint2 >= USE_CAN_RCV_BUF_SIZE)
				{
					CANRcvBufApp.ReadPoint2 =0;
				}
				CANRcvBufApp.FullFlag2=0;
			}
			else 
			{
				status=1;
			}
			break;
		/////////////////////////////////////////////////////////////////////	
		#if	(CAN_MAX_NUM == 4)
			case	CAN3:
				if((0 != CANRcvBufApp.FullFlag3) ||
					(CANRcvBufApp.ReadPoint3 != CANRcvBufApp.WritePoint3))
				{
					*Buf=CANRcvBufApp.RcvBuf[CAN3][CANRcvBufApp.ReadPoint3];
					if(++CANRcvBufApp.ReadPoint3 >= USE_CAN_RCV_BUF_SIZE)
					{
						CANRcvBufApp.ReadPoint3 =0;
					}
					CANRcvBufApp.FullFlag3=0;
				}
				else 
				{
					status=1;
				}
				break;
			case	CAN4:
				if((0 != CANRcvBufApp.FullFlag4) ||
					(CANRcvBufApp.ReadPoint4 != CANRcvBufApp.WritePoint4))
				{
					*Buf=CANRcvBufApp.RcvBuf[CAN4][CANRcvBufApp.ReadPoint4];
					if(++CANRcvBufApp.ReadPoint4 >= USE_CAN_RCV_BUF_SIZE)
					{
						CANRcvBufApp.ReadPoint4 =0;
					}
					CANRcvBufApp.FullFlag4=0;
				}
				else 
				{
					status=1;
				}
				break;
		#endif
		///////////////////////////////////////////////////////////////////////////
		default:
			status=1;
			break;
	}
	return status;
}
/*
***********************************************************************************************************
**函数原型	:  	void	WriteCANRcvCyBuf(eCANNUM CanNum)
**参数说明	:  	CanNum	-->>	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
**返回值		:		
**说	明		:	本函数用于驱动将收到的CAN数据写入环形缓冲区
************************************************************************************************************/
void	WriteCANRcvCyBuf(eCANNUM CanNum)
{
	switch(CanNum)
	{
		case	CAN1:
			if((0 == CANRcvBufApp.FullFlag1))
			{
				CANRcvBufApp.RcvBuf[CAN1][CANRcvBufApp.WritePoint1] = RxBUF(CAN1);
				if(++CANRcvBufApp.WritePoint1 >= USE_CAN_RCV_BUF_SIZE)
				{
					CANRcvBufApp.WritePoint1=0;
				}
				if(CANRcvBufApp.WritePoint1 == CANRcvBufApp.ReadPoint1)
				{
					CANRcvBufApp.FullFlag1 =1;
				}
			}
			break;
		case	CAN2:
			if((0 == CANRcvBufApp.FullFlag2))
			{
				CANRcvBufApp.RcvBuf[CAN2][CANRcvBufApp.WritePoint2] = RxBUF(CAN2);
				if(++CANRcvBufApp.WritePoint2 >= USE_CAN_RCV_BUF_SIZE)
				{
					CANRcvBufApp.WritePoint2=0;
				}
				if(CANRcvBufApp.WritePoint2 == CANRcvBufApp.ReadPoint2)
				{
					CANRcvBufApp.FullFlag2 =1;
				}
			}
			break;
		//////////////////////////////////////////////////////////////////////
		///////////////////////////////////////////////////////////////////////	
		#if	(CAN_MAX_NUM == 4)
			case	CAN3:
				if((0 == CANRcvBufApp.FullFlag3))
				{
					CANRcvBufApp.RcvBuf[CAN3][CANRcvBufApp.WritePoint3] = RxBUF(CAN3);
					if(++CANRcvBufApp.WritePoint3 >= USE_CAN_RCV_BUF_SIZE)
					{
						CANRcvBufApp.WritePoint3=0;
					}
					if(CANRcvBufApp.WritePoint3 == CANRcvBufApp.ReadPoint3)
					{
						CANRcvBufApp.FullFlag3 =1;
					}
				}
				break;
			case	CAN4:
				if((0 == CANRcvBufApp.FullFlag4))
				{
					CANRcvBufApp.RcvBuf[CAN4][CANRcvBufApp.WritePoint4] = RxBUF(CAN4);
					if(++CANRcvBufApp.WritePoint4 >= USE_CAN_RCV_BUF_SIZE)
					{
						CANRcvBufApp.WritePoint4=0;
					}
					if(CANRcvBufApp.WritePoint4 == CANRcvBufApp.ReadPoint4)
					{
						CANRcvBufApp.FullFlag4 =1;
					}
				}
				break;
		#endif
		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		default:
			break;
	}
	RelCanRecBuf(CanNum);
}
//应用常量定义
//使用工作模式
const 	INT32U	USE_MOD_CAN[2] = 
{
	USE_MODE_CAN1,
	USE_MODE_CAN2,
	
	#if	(CAN_MAX_NUM == 4)
		USE_MODE_CAN3,
		USE_MODE_CAN4,
	#endif
};
//使用睡眠模式
const 	INT32U	USE_SLP_MOD_CAN[2] = 
{
	USE_SLP_MOD_CAN1,
	USE_SLP_MOD_CAN2,
	#if	(CAN_MAX_NUM == 4)
		USE_SLP_MOD_CAN3,
		USE_SLP_MOD_CAN4,
	#endif
};
//使用波特率
const 	INT32U	USE_BTR_CAN[2] = 
{
	USE_BTR_CAN1,
	USE_BTR_CAN2,
	#if	(CAN_MAX_NUM == 4)
		USE_BTR_CAN3,
		USE_BTR_CAN4,
	#endif
};
//使用发送缓冲区发送优先级模式选择
const 	INT32U	USE_TPM_CAN[2] = 
{
	USE_TPM_CAN1,
	USE_TPM_CAN2,
	#if	(CAN_MAX_NUM == 4)
		USE_TPM_CAN3,
		USE_TPM_CAN4,
	#endif
};
//应用中断
const 	INT32U	USE_INT_CAN[2] = 
{
	USE_INT_CAN1,
	USE_INT_CAN2,
	#if	(CAN_MAX_NUM == 4)
		USE_INT_CAN3,
		USE_INT_CAN4,
	#endif
};
//应用报警限制
const	INT32U	USE_EWL_CAN[2] = 
{
	USE_EWL_CAN1,
	USE_EWL_CAN2,
	#if	(CAN_MAX_NUM == 4)
		USE_EWL_CAN3,
		USE_EWL_CAN4,
	#endif
};

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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