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

📄 ican.c

📁 可自行修改移植的CAN应用层协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "config.h"

OS_FLAG_GRP *ican_pevent;//系统消息指针
iCANSLV  iCANdeviceList[ICAN_SLV_NUM];//轮训列表

/*******************************************/
#if ican_DRAM_Enalbe
INT8U dram[2048];//动态内存
#endif
/*******************************************/

INT8U ican_cet,ALL_OVER;//0未连接,1建立连接,2重复id
DEVICERCSR myDEVICERCSR; //从站数据逻辑地址表
INT8U deviceinf[32] = 
{									 /*类别********************************逻辑地址***********数组中的位置/长度*****/
	0x00,0x01,						//生产商ID 							  0xE0--0xE1			   0/2
	0x01,0x00,						//产品类型							  0xE2--0xE3			   2/2
	0x01,0x00,						//产品型号							  0xE4--0xE5			   4/2
	0xE8,0x03,						//产品硬件版本						  0xE6--0xE7			   6/2
	0xE8,0x03,						//产品固件版本						  0xE8--0xE9			   8/2
	0x80,0x40,0x32,0x03,			//序列号							  0xEA--0xED			   10/4
	0x02,							//本机节点ID						  0xEE					   
	0xff,							//CAN波特率 0xff为无效				  0xEF
	0x31,0x00,0x1C,0x00,			//用户特殊波特率					  0xF0--0xF3
	0xff,							//循环模式定时						  0xF4
	0xff,							//主站通讯定时						  0xF5
	0xff,							//状态改变触发使能					  0xF6
	0xff,							//主站地址							  0xF7
	0xff,							//输入输出通道选择					  0xF8
	0xff,							//输入输出配置参数					  0xF9
	0xff,0xff,0xff,0xff,0xff,0xff	//保留								  0xFA--0xFF
};
/******************************iCAN申请动态内存**************************
 作者:张森
 日期:2008年4月6日
*************************************************************************/
#if ican_DRAM_Enalbe
void *ican_malloc(INT32U size)
{INT8U *p;
	if(size>0)
	{
	 	p=reg_malloc (size);//申请
		if(p==NULL)//内存满
			{
				
				return (NULL);
			}
			else
			{
			return p;	
			}
	}
	else 
	{
     	return (NULL);
	}	
}
#endif
/******************************iCAN I/O初始化***************************
 作者:张森
 日期:2008年4月6日
*************************************************************************/
void ican_io_init(INT8U DI_len,INT8U *p_DI_len,INT8U DO_len,INT8U *p_DO_len,INT8U AI_len,INT8U *p_AI_len,INT8U AO_len,INT8U *p_AO_len)
{
	myDEVICERCSR.DILen=DI_len;
	myDEVICERCSR.DOLen=DO_len;
	myDEVICERCSR.AILen=AI_len;
	myDEVICERCSR.AOLen=AO_len;
	myDEVICERCSR.pDIData=p_DI_len;
	myDEVICERCSR.pDOData=p_DO_len;
	myDEVICERCSR.pAIData=p_AI_len;
	myDEVICERCSR.pAOData=p_AO_len;	
}
/************************iCAN主站初始化**********************************
 作者:张森
 日期:2008年4月2日
 
**************************************************************************/
void master_init()
{
INT8U i,err;
ican_pevent=OSFlagCreate(0,&err);
iCANdeviceList[deviceinf[0x0e]].sla_status=3;

/*******************************************/
#if ican_DRAM_Enalbe
	ican_init_mempool (dram,2048);//初始化动态内存
	for(i=0;i<ICAN_SLV_NUM;i++)
	{
		iCANdeviceList[i].P_DILen =NULL;
		iCANdeviceList[i].P_DOLen =NULL;
		iCANdeviceList[i].P_AILen =NULL;
		iCANdeviceList[i].P_AOLen =NULL;
	}
#else 

	for(i=1;i<=CANXS;i++)
	{	
		iCANdeviceList[i].DILen=2;
		iCANdeviceList[i].P_DILen=&Vbuf[10*(i-1)];
		iCANdeviceList[i].DOLen=2;
		iCANdeviceList[i].P_DOLen =&Vbuf[10*(i-1)+2];
		iCANdeviceList[i].AILen=4;
		iCANdeviceList[i].P_AILen =&Vbuf[10*(i-1)+4];
		iCANdeviceList[i].AOLen=3;
		iCANdeviceList[i].P_AOLen =&Vbuf[3*(i-1)+173];
	}

	for(i=CANXS+1;i<6;i++)
	{
		iCANdeviceList[i].sla_status=3;
	}
	
		iCANdeviceList[6].DILen=7;
		iCANdeviceList[6].P_DILen=&Vbuf[50];
		iCANdeviceList[6].DOLen=7;
		iCANdeviceList[6].P_DOLen =&Vbuf[57];
		iCANdeviceList[6].AILen=10;
		iCANdeviceList[6].P_AILen =&Vbuf[198];
		iCANdeviceList[6].AOLen=0;
		iCANdeviceList[6].P_AOLen =NULL;
	
#endif
/*******************************************/


CAN_Init(CAN1,5);	
}
/******************************连续读取从站数据命令**************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
 	   SourceID		资源ID
 	   SubSourceID	子资源ID(当SourceID<0xf9时,忽略子节点地址)
 	   length		读取长度
*****************************************************************************/
void  ican_read_sla(INT8U DestMACID,INT8U SourceID,INT8U SubSourceID,INT8U length)
{INT8U read_sla_buf[2];
 if(SourceID<0xf9)
	{
	ican_send(DestMACID,0,0x02,SourceID,&length,1);
	}
 else
 	{
 	read_sla_buf[0]=SubSourceID;
 	read_sla_buf[1]=length;
 	ican_send(DestMACID,0,0x02,SourceID,read_sla_buf,2);	
 	}	
}
/******************************连续读取从站数据响应**************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
 	   SourceID		资源ID (如有资源节点请放入*p的第一位)
 	   *p的数据长度
*****************************************************************************/
void  ican_read_sla_respond(INT8U DestMACID,INT8U SourceID,INT8U *p,INT8U D_long)
{
		ican_send(DestMACID,1,0x02,SourceID,p,D_long);	
}
/******************************连续写入从站数据命令**************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
 	   SourceID		资源ID(如有资源节点请放入*p的第一位)
 	   *p			写入的数据指针
 	   D_long		*p的数据长度
******************************************************************************/
void ican_write_sla(INT8U DestMACID,INT8U SourceID,INT8U *p,INT8U D_long)
{
	ican_send(DestMACID,0,0x01,SourceID,p,D_long);
}
/******************************连续写入从站数据响应***************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
 	   SourceID		资源ID
******************************************************************************/
void ican_write_sla_respond(INT8U DestMACID,INT8U SourceID)
{
	ican_send(DestMACID,1,0x01,SourceID,&SourceID,0);	//&SourceID只起到格式作用,并不传送
}
/******************************建立逻辑链接命令******************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
 	   Cyclicmaster	主站通讯定时参数
******************************************************************************/
void ican_create_cnnet_sla (INT8U DestMACID)
{
 INT8U create_cnnet_sla_buf[2];
 create_cnnet_sla_buf[0]=deviceinf[0x0e];
 create_cnnet_sla_buf[1]=deviceinf[0x15];
 ican_send(DestMACID,0,0x04,0xf7,create_cnnet_sla_buf,2);		
}
/******************************建立逻辑链接响应******************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
 	   Cyclicmaster	主站通讯定时参数
******************************************************************************/
void ican_create_cnnet_sla_respond (INT8U DestMACID)
{
 INT8U ican_create_cnnet_sla_respond[4];
 ican_create_cnnet_sla_respond[0]=myDEVICERCSR.DILen;
 ican_create_cnnet_sla_respond[1]=myDEVICERCSR.DOLen;
 ican_create_cnnet_sla_respond[2]=myDEVICERCSR.AILen;
 ican_create_cnnet_sla_respond[3]=myDEVICERCSR.AOLen;
 ican_send(DestMACID,1,0x04,0xf7,ican_create_cnnet_sla_respond,4);		
}
/******************************删除逻辑链接命令******************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
******************************************************************************/
void ican_del_cnnet_sla(INT8U DestMACID)
{
 ican_send(DestMACID,0,0x05,0xf7,&deviceinf[0x0e],1);		
}
/******************************删除逻辑链接响应******************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
******************************************************************************/
void ican_del_cnnet_sla_respond(INT8U DestMACID)
{
ican_send(DestMACID,1,0x05,0xf7,&DestMACID,0);//&DestMACID只起到格式作用,并不传送	
}
/*********************************复位从站命令*********************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
*******************************************************************************/
void ican_reset_sla(INT8U DestMACID)
{
ican_send(DestMACID,0,0x06,0x00,&DestMACID,1);	
}
/*********************************复位从站响应*********************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
*******************************************************************************/
void ican_reset_sla_respond(INT8U DestMACID)
{
ican_send(DestMACID,1,0x06,0x00,&DestMACID,0);//&DestMACID只起到格式作用,并不传送	
}
/*********************************MACID检测命令*********************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
*********************************************************************************/
void ican_check_slaID(INT8U DestMACID)
{
INT8U ican_check_slaID_buf[5];
ican_check_slaID_buf[0]=DestMACID;
ican_check_slaID_buf[1]=deviceinf[0x0a];
ican_check_slaID_buf[2]=deviceinf[0x0b];
ican_check_slaID_buf[3]=deviceinf[0x0c];
ican_check_slaID_buf[4]=deviceinf[0x0d];
ican_send(DestMACID,0,0x07,0x00,ican_check_slaID_buf,5);	
}
/*********************************MACID检测响应*********************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
*********************************************************************************/
void ican_check_slaID_respond(INT8U DestMACID)
{
INT8U ican_check_slaID_buf[5];
ican_check_slaID_buf[0]=DestMACID;
ican_check_slaID_buf[1]=deviceinf[0x0a];
ican_check_slaID_buf[2]=deviceinf[0x0b];
ican_check_slaID_buf[3]=deviceinf[0x0c];
ican_check_slaID_buf[4]=deviceinf[0x0d];
ican_send(DestMACID,1,0x07,0x00,ican_check_slaID_buf,5);	
}
/***********************************错误响应*************************************
 作者:张森
 日期:2008年4月6日
 参数:DestMACID	目标ID
 	   SourceID		资源ID号
 	   ERRID		错误类型
*********************************************************************************/
void ican_respond_err(INT8U DestMACID,INT8U SourceID,INT8U ERRID)
{
ican_send(DestMACID,1,0x0f,SourceID,&ERRID,1);	
}
/***********************************消息处理*************************************
 作者:张森
 日期:2008年4月8日
 参数:*p 			消息队列中储存的动态内存的地址
 	   *p_iCANSLV   从站列表结构体指针
*********************************************************************************/
void ican_respond(INT8U *p,iCANSLV *p_iCANSLV)
{
    
INT8U *p_buf,d_long,SrcMACID,ACK,FunCID,SourceID,err;
  
M(31,4)=M(31,5)=0;
               
p_buf=p;
p++;
d_long=*p;//长度
p++;
SrcMACID=*p;//数据来源
p++;
ACK=*p;//响应
p++;
FunCID=*p;//功能码
p++;
SourceID=*p;//资源编号
p++;//数据的第一位
if (ACK==0)//请求帧
switch(FunCID)
{
	case write_port://写入数据
	if(ican_cet==1)
	{
		if(SourceID<=0x1f)
		{
			ican_respond_err(SrcMACID,SourceID,cmd_unsupport);	//资源不支持此命令
		}
		else
		if(SourceID<=0x3f)
		{
			if(SourceID+d_long-1<=0x3f)//数据长度没有超出
			{
				array_copy(p,&myDEVICERCSR.pDOData[SourceID-0x20],d_long);
				ican_write_sla_respond(SrcMACID,SourceID);	
			}
			else
			{
				ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符	
			}
				
		}
		else
		if(SourceID<=0x5f)
		{
			ican_respond_err(SrcMACID,SourceID,cmd_unsupport);	//资源不支持此命令
		}
		else
		if(SourceID<=0x7f)
		{
			if(SourceID+d_long-1<=0x7f)//数据长度没有超出
			{
				array_copy(p,&myDEVICERCSR.pAOData[SourceID-0x60],d_long);
				ican_write_sla_respond(SrcMACID,SourceID);	
			}
			else
			{
					ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符	
			}		
		}
		else
		{
			ican_respond_err(SrcMACID,SourceID,res_unfound);//资源不存在
		}
	}
	else

	{
	ican_respond_err(SrcMACID,SourceID,cnet_unexist);	//没有建立连接
	}

	break;
	
	case read_port ://读取数据
	if(ican_cet==1)
	{
		
	
		if(SourceID<=0x1f)
		{
			if(SourceID+*p-1<=0x1f)//数据长度没有超出
			{			
				ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pDIData[SourceID],*p);	
			}
			else
			{
				ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符	
			}
		}
		else
		if(SourceID<=0x3f)
		{	
			if(SourceID+*p-1<=0x3f)//数据长度没有超出
			{
				ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pDIData[SourceID-0x20],*p);	
			}
			else
			{
				ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符	
			}
	
		}
		else
		if(SourceID<=0x5f)
		{
			if(SourceID+*p-1<=0x5f)//数据长度没有超出
			{
				ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pAIData[SourceID-0x40],*p);	
			}
			else
			{
				ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符	
			}
		}
		else
		if(SourceID<=0x7f)
		{	
			if(SourceID+*p-1<=0x7f)//数据长度没有超出
			{
				ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pAIData[SourceID-0x60],*p);	
			}
			else
			{
				ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符	
			}
		}
		else
		{
			ican_respond_err(SrcMACID,SourceID,res_unfound);//资源不存在	
		}
	}
	else
	{
	ican_respond_err(SrcMACID,SourceID,cnet_unexist);	//没有建立连接
	}	
	break;
	
//	case slv_to_mas_trigger	://从站自己触发的数据 没有这种情况
//	break;
	
	case creat_cnet://建立连接
			if(d_long==2&& *p<0x40 )
			{
			if(ican_cet==1)
				{
				ican_respond_err(SrcMACID,SourceID,cmd_unsupport);	//已经在连接状态
				}
				else
				{				
				 ican_cet=1;
				 deviceinf[0x17]=*p;
				 p++;
				 deviceinf[0x15]=*p;
				 ican_create_cnnet_sla_respond(SrcMACID);//连接成功
				}
			}
			else
			{
			ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//参数格式不对	
			}
			
	break;

	case del_cnet://删除链接
	
			if(d_long==1&& *p<0x40 )
			{
			if(ican_cet==1)
				{

⌨️ 快捷键说明

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