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

📄 canapp.c

📁 以LPC2194为平台开发的整车ECU控制器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************
**                               广州周立功单片机发展有限公司
**                                     研    究    所
**                                        产品一部 
**                                 http://www.zlgmcu.com
**-----------------------------------------------------------文件信息--------------------------------------------------------------------------------
**	文   件  	名:	CANAPP.C
** 	版  		本:	v1.0
** 	日		期:	2004年2月23日
**	描		述:	CAN模块应用接口函数说明文件。该文件中的函数,如果用户有特别的需要,可以进行修改。
********************************************************************************************************/
#define		_CANAPP_GLOBAL_
#include	"config.h"
#include	"canapp.h"
#include	<math.h>

UINT32 CANReadData_29bit(eCANNUM CanNum,uint32* CANPGN, uint32* pLengthOfData, pRCV_candata pData);

uint8 can_buf[8];
/****************************************************************************
* 名称:can_xiaoyan(uint8 *buf3)
* 功能:用来对报文数据第8字节进行校验
* 入口参数:无
* 出口参数:无
****************************************************************************/
uint8 can_xiaoyan(uint8 *buf)
{
	uint8  add1;	
	if(buf[0]+buf[1]>0xFF)
	{
		add1=buf[0]+buf[1]+1;
	}
	else add1=buf[0]+buf[1];
	if(add1+buf[2]>0xFF)
	{
		add1=add1+buf[2]+1;
	}
	else add1=add1+buf[2];
	if(add1+buf[3]>0xFF)
	{
		add1=add1+buf[3]+1;
	}
	else add1=add1+buf[3];
	if(add1+buf[4]>0xFF)
	{
		add1=add1+buf[4]+1;
	}
	else add1=add1+buf[4];
	if(add1+buf[5]>0xFF)
	{
		add1=add1+buf[5]+1;
	}
	else add1=add1+buf[5];
	if(add1+buf[6]>0xFF)
	{
		add1=add1+buf[6]+1;
	}
	else add1=add1+buf[6];							
	add1=add1 ^ 0x7E;
	buf[7]=add1;
	//return add;
}

/****************************************************************************
* 名称:can_de_xiaoyan(uint8 *buf3)
* 功能:用来对报文数据进行解校验
* 入口参数:无
* 出口参数:无
****************************************************************************/
uint8 can_de_xiaoyan(void)
{
	uint8  add1;	
	//数组前7个字节累加和计算、相与计算							
	if((*pcanData).Word+(*(pcanData+1)).Word>0xFF)
	{
		add1=(*pcanData).Word+(*(pcanData+1)).Word+1;
	}
	else add1=(*pcanData).Word+(*(pcanData+1)).Word;
	if(add1+(*(pcanData+2)).Word>0xFF)
	{
		add1=add1+(*(pcanData+2)).Word+1;
	}
	else add1=add1+(*(pcanData+2)).Word;
	if(add1+(*(pcanData+3)).Word>0xFF)
	{
		add1=add1+(*(pcanData+3)).Word+1;
	}
	else add1=add1+(*(pcanData+3)).Word;
	if(add1+(*(pcanData+4)).Word>0xFF)
	{
		add1=add1+(*(pcanData+4)).Word+1;
	}
	else add1=add1+(*(pcanData+4)).Word;
	if(add1+(*(pcanData+5)).Word>0xFF)
	{
		add1=add1+(*(pcanData+5)).Word+1;
	}
	else add1=add1+(*(pcanData+5)).Word;
	if(add1+(*(pcanData+6)).Word>0xFF)
	{
		add1=add1+(*(pcanData+6)).Word+1;
	}
	else add1=add1+(*(pcanData+6)).Word;
	add1=add1 ^ 0x7E;
	//校验码计算后与报文中的比较
	if(add1==((*(pcanData+7)).Word))
	{
		return (1);
	} 
	else 
	{
		return(0);
	}
}

/************************************************************************************************************
**函数原型		:  	void	CANIntPrg(void)
**参数说明		:  	无
**返回值		:	无	
**说	明		:	CAN控制器中断处理函数
************************************************************************************************************/
__irq		void		CANIntPrg(void)
{
	UINT32 	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);
			rec_flag=1;
		}
		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);
		}
	}
	VICVectAddr = 0;
}

/****************************************************************************************
*
*Filename	:different_boud.c
*date		:20050707
*author		:zhangjia
*
*unsigned int boud_caculate(unsigned int boud_kbps)
*description	:基于ZLG ARM 2119 开发板的CAN总线波特率计算函数
*               :给定3种波特率: 250
                                  100
                                   20
                :方法对于有:    不改变前3个参数,只改变最后的分频就可以。                          
*input		:unsigned int boud_kbps
*			 ----需要设定的波特率。单位Kbps
*return		:UINT32 为所需波特率对应的BTR value
****************************************************************************************/
UINT32 boud_caculate_1(unsigned int boud_kbps_1)
{
//   uCANBTR boud_BTR;
  switch(boud_kbps_1)
  {
     case 250 :
      return 0x00174003;
     break;
     case 125:
      return 0x00174007;
      break;
     case 100 :
      return 0x00174009;
     break;
     case 20:
      return 0x00974032;
     default:
     return 0;
     break; 
   }     
   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   //add different boud_kpbs
   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   return  0x00174009;
 }

/************************************************************************************************************
**函数原型		:  	void	InitCAN_byd(eCANNUM CanNum,unsigned int boud)
**参数说明		:  	CanNum	-->>	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
*					unsigned int boud_k	-->> CAN的初始化波特率值.unit:kbps
**返回值		:	无	
**说	明		;	在初始化CAN函数的基础上增加设定波特率的功能
*               :  对于波特率的使用只需要在主函数中修改就行,此出无须改动
*               :  给定特定的波特率的值就行了          
*********************************************************************************/
void InitCAN_byd(eCANNUM CanNum,unsigned int boud_kbps_1)
{	
	HwEnCAN(CanNum);																	
	SoftRstCAN(CanNum);																
	CANEWL(CanNum).Bits.EWL_BIT = USE_EWL_CAN[CanNum];										
	//初始化波特率
	//CANBTR(CanNum).Word = USE_BTR_CAN[CanNum];	
	CANBTR(CanNum).Word = boud_caculate_1(boud_kbps_1);											
	//初始化中断为非向量中断
	VICDefVectAddr =(UINT32)CANIntPrg;
	VICIntEnable |=(1<<19)|(1<<(20+ CanNum))|(1<<(26+ CanNum));
	CANIER(CanNum).Word= USE_INT_CAN[CanNum];												
	//配置验收滤波器(旁路状态)
	CANAFMR.Bits.AccBP_BIT =1;	
	//初始化模式
	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);
}

/************************************************************************************************************
**函数原型		:  	UINT32	CANSendData(eCANNUM CanNum,UINT32 Cmd,P_stcTxBUF Buf)
**参数说明		:  	CanNum	-->>	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
					Cmd	-->	发送命令字
					Buf	-->	要发送的数据
**返回值		:	无	
**说	明		:	本函数用于将数据发送到CAN总线
************************************************************************************************************/
UINT32		CANSendData(eCANNUM CanNum,UINT32 Cmd,P_stcTxBUF Buf)
{
	UINT32 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);
	}
	return (status);
}

/************************************************************************************************************
**函数原型		:  	UINT32	ReadCANRcvCyBuf(eCANNUM CanNum,stcRxBUF *Buf)
**参数说明		:  	CanNum	-->	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
					Buf		-->	使用驱动接收到的缓冲区数据
**返回值		:	=0,驱动接收到数据。
					!=0,驱动没接收到数据。	
**说	明		:	本函数用于用户调用使用CAN驱动接收到的数据。
************************************************************************************************************/
UINT32	ReadCANRcvCyBuf(eCANNUM CanNum,stcRxBUF *Buf)
{
	UINT32	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;
		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;
		default:
			status=1;
			break;
	}
	return status;
}

/************************************************************************************************************
**函数原型		:  	void	WriteCANRcvCyBuf(eCANNUM CanNum)
**参数说明		:  	CanNum	-->>	CAN控制器,值不能大于CAN_MAX_NUM 规定的值
**返回值		:		
**说	明		:	本函数用于驱动将收到的CAN数据写入环形缓冲区
************************************************************************************************************/
void	WriteCANRcvCyBuf(eCANNUM CanNum)
{
	switch(CanNum)
	{
		case	CAN1:

⌨️ 快捷键说明

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