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

📄 ican_interface.c

📁 可自行修改移植的CAN应用层协议栈
💻 C
字号:
#include  "config.h"

extern  INT8U deviceinf[];
extern  iCANSLV iCANdeviceList[];
extern  ican_respond(INT8U *p,iCANSLV *p_iCANSLV);
/************************数组复制函数*************************************
 作者:张森
 日期:2008年4月1日
 p1 指向源指针
 p2 指向目标指针
 d_long 复制长度
**************************************************************************/
void array_copy(INT8U *p1,INT8U *p2,INT8U d_long)
{
for(;d_long>0;d_long--)
	{
	 *p2=*p1;
	 p1++;
	 p2++;
	}
}
/************************iCAN数据格式与芯片空间格式转换(发送)****************
 作者:张森
 日期:2008年4月2日
 SrcMACID	源地址
 DestMACID	目标地址
 iCAN_ACK	请求响应
 FunCID	功能ID
 SourceID 	资源ID
 segFlag	分段标志
 p			数据指针
 D_long	数据长度(*p 长度)
 注意:不同的芯片CAN报文在寄存器的映射不同
**************************************************************************/
void ican_send_interface(SrcMACID,DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,D_long)
INT8U SrcMACID;
INT8U DestMACID;
INT8U iCAN_ACK;
INT8U FunCID;
INT8U SourceID;
INT8U segFlag;
INT8U *p;
INT8U D_long;
{
stcTxBUF CTBuf;
   CTBuf.TxFrameInfo.Bits.PRIO_BIT=0;	//缓冲区数据发送优先级的值
   CTBuf.TxFrameInfo.Bits.RTR_BIT=0;//远程帧、数据帧辨别位(RTR=0数据帧,RTR=1远程帧)
   CTBuf.TxFrameInfo.Bits.FF_BIT=1;	//扩展帧、标准帧辨别位(FF=0标准帧,FF=1扩展帧)
   CTBuf.TxFrameInfo.Bits.DLC_BIT=D_long+1;//发送数据长度
  
   CTBuf.TxCANID.FrameFm.stcICAN.SourceID =SourceID;
   CTBuf.TxCANID.FrameFm.stcICAN.FuncID =FunCID;
   CTBuf.TxCANID.FrameFm.stcICAN.ACK =iCAN_ACK;
   CTBuf.TxCANID.FrameFm.stcICAN.DestMACID  =DestMACID;
   CTBuf.TxCANID.FrameFm.stcICAN.SrcMACID =SrcMACID;
   
   CTBuf.CANTDA.Bits.Data1_BIT=segFlag; 
   CTBuf.CANTDA.Bits.Data2_BIT=p[0];
   CTBuf.CANTDA.Bits.Data3_BIT=p[1];
   CTBuf.CANTDA.Bits.Data4_BIT=p[2];
   CTBuf.CANTDB.Bits.Data1_BIT=p[3];
   CTBuf.CANTDB.Bits.Data2_BIT=p[4];
   CTBuf.CANTDB.Bits.Data3_BIT=p[5];
   CTBuf.CANTDB.Bits.Data4_BIT=p[6];
   CANSendData(CAN1,0,&CTBuf);

}
/************************iCAN报文分段发送函数*******************************
 作者:张森
 日期:2008年4月2日
 DestMACID	目标地址
 iCAN_ACK	请求响应
 FunCID	功能ID
 SourceID 	资源ID
 p			数据指针
 D_long	数据长度(*p 长度) 0<D_long<65  程序不判断<0的情况 如需要请自行修改
**************************************************************************/
void ican_send(INT8U DestMACID,INT8U iCAN_ACK,INT8U FunCID,INT8U SourceID,INT8U *p,char D_long)
{
INT8U segFlag=0,i,l;

	if(D_long<8)
	{
	ican_send_interface(deviceinf[0x0e],DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,D_long);
	}
	else
	{
	 segFlag=0x40;
	 l=7;
	 
	for(i=0;D_long>0;)
	   {
	   	
	   if(D_long<8)
	   		{
				l=D_long;
				segFlag=0xc0|i;
		//		D_long=0;
		 		ican_send_interface(deviceinf[0x0e],DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,l);
		 		break;
			}
		
	    ican_send_interface(deviceinf[0x0e],DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,l);	
	 
		i++;
		segFlag=0x80|i;
		D_long=D_long-7; 
		p=p+7;
		
		}
	}

}
/************************寻找对应从站缓冲区********************************
 作者:张森
 日期:2008年4月1日
 SrcMAC_id 要搜索的ID
 p  	   结构体指针
**************************************************************************/
void *find_id_buff(INT8U SrcMAC_id,iCANSLV *p)
{ INT8U i;
	for(i=0;i<ICAN_SLV_NUM+1;i++)
	{if(p->SlvID==SrcMAC_id)
		{
		return  p;
		}
	   p++;
	}
	return (NULL);

}
/************************iCAN数据格式与芯片空间格式转换(接收)*********************
 作者:张森
 日期:2008年4月1日
 
 
**************************************************************************/
void ican_rec_interface(P_stcRxBUF rx_Buf)
{

ReadCanRxBuf(CAN1,rx_Buf);
RelCanRecBuf(CAN1);//释放接收缓冲区
}
/************************iCAN接收数据处理******************************
 作者:张森
 日期:2008年4月3日
 返回值:0x00 接收成功
 		 0x01 动态内存空间不足
 		 0x02 不支持此从站ID
 		 0x03 消息队列已满
 		 0x04 分段错误	
 		 0x05 非法数据格式
**************************************************************************/
INT8U ican_rec()
{
stcRxBUF ican_rec_buf;
iCANSLV *p_sla_buf;

INT8U ican_rec_transfrom_buf[13],flag_char_buf;
ican_rec_interface(&ican_rec_buf);

#if ican_soft_filter   //软件滤波宏控制 

if(ican_rec_buf.RxCANID.FrameFm.stcICAN.DestMACID==deviceinf[0x0e])//&&(从站信息列表||)在此添加从站信息比对
{

#endif

if(ican_rec_buf.CANRcvFS.Bits.FF_BIT==1)//扩展数据帧
{

flag_char_buf=ican_rec_buf.CANRDA.Bits.Data1_BIT;
	
	if(flag_char_buf==0)//没有分段
		{
/*--------------------------------------------非分段数据处理---------------------------------------------------*/

			#if	ican_auto_search_slave_list			//自动搜获从站列表中相应的从站空间位置返回从站列表位置
				p_sla_buf=find_id_buff(ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID,iCANdeviceList);
					if(p_sla_buf==NULL)
					{
						return 0x02;
	
					}
			#else
				p_sla_buf=&iCANdeviceList[ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID];
			#endif
			/***************************格式整理******************************************/
			ican_rec_transfrom_buf[0]=0x01;//0xff;//标志此消息是数据信息
			ican_rec_transfrom_buf[1]=ican_rec_buf.CANRcvFS.Bits.DLC_BIT-1; //数据长度为 CAN数据区内容减去减去分段标号长度
			ican_rec_transfrom_buf[2]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID;//源地址
			ican_rec_transfrom_buf[3]=ican_rec_buf.RxCANID.FrameFm.stcICAN.ACK;//响应位
			ican_rec_transfrom_buf[4]=ican_rec_buf.RxCANID.FrameFm.stcICAN.FuncID;//功能号
			ican_rec_transfrom_buf[5]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SourceID;//资源ID号
			ican_rec_transfrom_buf[6]=ican_rec_buf.CANRDA.Bits.Data2_BIT;//数据内容1
			ican_rec_transfrom_buf[7]=ican_rec_buf.CANRDA.Bits.Data3_BIT;//数据内容2
			ican_rec_transfrom_buf[8]=ican_rec_buf.CANRDA.Bits.Data4_BIT;//数据内容3
			ican_rec_transfrom_buf[9]=ican_rec_buf.CANRDB.Bits.Data1_BIT;//数据内容4
			ican_rec_transfrom_buf[10]=ican_rec_buf.CANRDB.Bits.Data2_BIT;//数据内容5
			ican_rec_transfrom_buf[11]=ican_rec_buf.CANRDB.Bits.Data3_BIT;//数据内容6
			ican_rec_transfrom_buf[12]=ican_rec_buf.CANRDB.Bits.Data4_BIT;//数据内容7
			/***************************格式整理结束****************************************/
			//UART0_SendNByte(ican_rec_transfrom_buf,ican_rec_transfrom_buf[1]+6);
			ican_respond(ican_rec_transfrom_buf,p_sla_buf);
			return 0x00;
/*------------------------------------以上是非分段处理-----------------------------------------------------------*/
	}
	else //收到为分段帧
	{
			#if	ican_auto_search_slave_list			//自动搜获从站列表中相应的从站空间位置返回从站列表位置
				p_sla_buf=find_id_buff(ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID,iCANdeviceList);
					if(p_sla_buf==NULL)
					{
						return 0x02;
					}
			#else
				p_sla_buf=&iCANdeviceList[ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID];
			#endif
			/***************************格式整理******************************/
			ican_rec_transfrom_buf[0]=0x01;//0xff;
			ican_rec_transfrom_buf[1]=ican_rec_buf.CANRcvFS.Bits.DLC_BIT-1; //数据长度为CAN数据区内容 -分段标号
			ican_rec_transfrom_buf[2]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID;//源地址
			ican_rec_transfrom_buf[3]=ican_rec_buf.RxCANID.FrameFm.stcICAN.ACK;//响应位
			ican_rec_transfrom_buf[4]=ican_rec_buf.RxCANID.FrameFm.stcICAN.FuncID;//功能号
			ican_rec_transfrom_buf[5]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SourceID;//资源ID号
			ican_rec_transfrom_buf[6]=ican_rec_buf.CANRDA.Bits.Data2_BIT;//数据内容1
			ican_rec_transfrom_buf[7]=ican_rec_buf.CANRDA.Bits.Data3_BIT;//数据内容2
			ican_rec_transfrom_buf[8]=ican_rec_buf.CANRDA.Bits.Data4_BIT;//数据内容3
			ican_rec_transfrom_buf[9]=ican_rec_buf.CANRDB.Bits.Data1_BIT;//数据内容4
			ican_rec_transfrom_buf[10]=ican_rec_buf.CANRDB.Bits.Data2_BIT;//数据内容5
			ican_rec_transfrom_buf[11]=ican_rec_buf.CANRDB.Bits.Data3_BIT;//数据内容6
			ican_rec_transfrom_buf[12]=ican_rec_buf.CANRDB.Bits.Data4_BIT;//数据内容7
		//	ican_rec_transfrom_buf[13]=ican_rec_buf.CANRDA.Bits.Data1_BIT;
			/****************************************************************************/
		
			if((flag_char_buf & 0xc0)==0x40)//第一分段帧
			{
				if((flag_char_buf & 0x3f)!=0x00)//分段吗不为零 分段错误
				{
					return 0x04;	
				}

				array_copy(ican_rec_transfrom_buf,(*p_sla_buf).BUF,13);//放入从机分段缓冲区	
			}

			if(flag_char_buf>0x80)//后段数据
			{
				if((flag_char_buf & 0x3f)*7 !=(*p_sla_buf).BUF[1])//如果分段不是比上段大1
				{
				//UART0_SendNByte(&(*p_sla_buf).BUF[1],1);
					return 0x04;	
				}
				array_copy(&ican_rec_transfrom_buf[6],&(*p_sla_buf).BUF[(*p_sla_buf).BUF[1]+6],ican_rec_transfrom_buf[1]);//考入对应的位置
				(*p_sla_buf).BUF[1]=(*p_sla_buf).BUF[1]+ican_rec_transfrom_buf[1];//更改存入的数据长度
				if(flag_char_buf>0xc0)//最后分段
				{
	
					ican_respond((*p_sla_buf).BUF,p_sla_buf);
					return 0x00;
				}
		
			}
		}

}

#if ican_soft_filter   //软件滤波宏控制 
}//控制宏
#endif
return 0x05;
}
/************************iCAN滤波校验初始化******************************
 作者:张森
 日期:2008年4月3日

**************************************************************************/

void ican_master_af(INT8U myid,INT8U chna)
{
	INT32U		i,u=0;
	uCANAFMR 	afmr;
	INT32U 		bakAfmr;
	
	ican_stcAF_EFF_CELL mask = {-1,-1,-1,-1};
	ican_stcAF_EFF_CELL *pU32= (ican_stcAF_EFF_CELL  *)((INT32U)CANAFRAM_GADR + (INT32U)(CANEFF_GRP_sa)) ;
	afmr.Word = CANAFMR;
	bakAfmr = afmr.Word;
	afmr.Bits.AccBP_BIT = 1;
	CANAFMR = afmr.Word;
	
	for(i=0;i<((CANENDofTable- CANEFF_GRP_sa)/4);i++)
	{
		*(pU32 + i) = mask;			// disable all AF cell
	}

	for(i=0;i<63;i++)
	{		
			(*(pU32 + u)).myid = myid;
			(*(pU32 + u)).otherid=i;
			(*(pU32 + u)).other=0;
			(*(pU32 + u)).RSV_bit=chna;
							// set filter cell
			u++;
			(*(pU32 + u)).myid = myid;
			(*(pU32 + u)).otherid=i;
			(*(pU32 + u)).other=-1;	
			(*(pU32 + u)).RSV_bit=chna;	
			u++;
	}
	
	CANAFMR = bakAfmr;
	

}





⌨️ 快捷键说明

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