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

📄 icanslave.c

📁 ICAN协议例程
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
将ican协议加入程序中,假设主站ID为:0x00,节点ID为:0x01;

******************************************************************************/
#define ICANSLAVEFILE //定义为主程序
#include "config.h"
//unsigned long  ICANFrameIDTbl[]={0};
#define ICANMASK                    0x001FE000//与自己的MACID相同才允许接收
uint32 xdata ulICANFrameIDMaskTbl[] =  {
    0, 0, 0, 0
}; //
uchar xdata MACIDTemp;
sbit led0=P7^0;
//****************************************************************************
//函数名称: void ICAN_Init(uchar order)
//函数功能: ICAN模块初始化
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void ICAN_Init(uchar order) {
    //ICAN模块初始化
//ICAN硬件初始化==================================================================
	pCAN_Node_Info[order] = &CAN_Node_Info[order]; //CAN节点软件结构指针初始化
    pReceFrameBuff[order] = &ReceFrameBuff[order]; //CAN节点接收缓冲指针初始化
    pSendFrameBuff[order] = &SendFrameBuff[order]; //CAN节点发送缓冲指针初始化
//ICAN硬件初始化==================================================================
    //  创建软件CAN节点             	                                                                   
    ICAN_Source[order].Area[0] = 0x0f; //厂商代码
//    ICAN_Source[order].Area[MACID] = 0x01; //设置目标节点的MACID
	ICAN_Source[order].Area[MasterMACID] = 0x00; //设置主站的MACID
    ICAN_Source[order].Area[VendorID] = 0x03; //厂商代码
    ICAN_Source[order].Area[VendorID + 1] = 0x33; //厂商代码
    ICAN_Source[order].Area[ProductType] = 0x0F; //产品类型
    ICAN_Source[order].Area[ProductType + 1] = 0xb1; //产品类型
    ICAN_Source[order].Area[ProductCode] = 0; //产品型号
    ICAN_Source[order].Area[ProductCode + 1] = 0; //产品型号
    ICAN_Source[order].Area[HardwareVersion] = 0x00; //产品硬件版本
    ICAN_Source[order].Area[HardwareVersion + 1] = 0x10; //产品硬件版本
    ICAN_Source[order].Area[FirmwareVersion] = 0x00; //产品固件版本
    ICAN_Source[order].Area[FirmwareVersion + 1] = 0x10; //产品固件版本
    ICAN_Source[order].Area[SerialNumber] = 0x13; //4字节产品SN号码
    ICAN_Source[order].Area[SerialNumber + 1] = 0x08; //4字节产品SN号码
    ICAN_Source[order].Area[SerialNumber + 2] = 0x11; //4字节产品SN号码
    ICAN_Source[order].Area[SerialNumber + 3] = 0x01; //4字节产品SN号码
    ICAN_Source[order].Area[BaudRateSet] = 0x01; //波特率设定
   	ICANSlav_ObjID[order].DestMACID = ICAN_Source[order].Area[MACID];
	ICANSlav_ObjID[order].SrcMACID=	ICAN_Source[order].Area[MasterMACID];
    //读取目标节点的MACID
    SourceType[order][0] = 0x00; //  开关量输入总数
    SourceType[order][1] = 0x00; //  开关量输出总数		    
    SourceType[order][2] = 0x10; //  模拟量输入总数
    SourceType[order][3] = 0x00; //  模拟量输出总数
    ICAN_ControlInfo[order].Idle = 0; //总线空闲
    ICAN_ControlInfo[order].TrDataCtr = 0; //有数据没有发送(帧为单位)
    ICAN_ControlInfo[order].TrLenth = 0; //有数据没有发送(帧为单位)
    ICAN_ControlInfo[order].ReDataCtr = 0; //有数据没有发送(帧为单位)
}

//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
 uchar ICAN_SourceTest(uchar order,uchar sourceid,uchar sourcelenth,uchar readorwrite){//资源检测
 		uchar data i;
		if(sourceid<0x20){//DI区域
		   i= SourceType[order][0] ; //  开关量输入总数
		   if(readorwrite)return 1;//资源不存在
		}else if(sourceid<0x40){//DO区域
		   i= SourceType[order][1] ; //  开关量输出总数
		   sourceid-=0x20;
		   if(readorwrite==0)return 1;//资源不存在
		}else if(sourceid<0x60){//AI区域
		   i= SourceType[order][2] ; //  模拟量输入总数
		   sourceid-=0x40;
		   if(readorwrite)return 1;//资源不存在
		}else if(sourceid<0x80){//AO区域
		   i= SourceType[order][3] ; //  模拟量输出总数
		   sourceid-=0x60;
		   if(readorwrite==0)return 1;//资源不存在
		}else{//其他区域为可读写了
		   return 0;//可读写区域
		} 	
		if(i==0)return 1;//资源不存在
		if(sourcelenth+sourceid>i)return 1;//资源不存在
		return 0;//可读写区域
 }
 //****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
uint32 ICAN_ObjIDManage(ICAN_OBJ  * ICAN_ObjID) {
    //ICAN报文标识码生成
    uint32 xdata ulObjId;
    ulObjId = 0;
    ulObjId = (ICAN_ObjID->SrcMACID << 21) +  //源节点编号
    (ICAN_ObjID->DestMACID << 13) +  //目标节点编号
    (ICAN_ObjID->ACK << 12) +  //应答标志
    (ICAN_ObjID->FUNCID << 8) +  //功能码
    (ICAN_ObjID->SourceID); //资源节点编号
    return (ulObjId);
}

//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void ICAN_ObjIDRestore(ICAN_OBJ *  ICAN_ObjID, uint32  Receive_ObjID) {
    //ICAN报文标识码还原
    ICAN_ObjID->SourceID = (Receive_ObjID) & 0x000000FF; //资源节点编号
    ICAN_ObjID->FUNCID = (Receive_ObjID >> 8) & 0x000000F; //功能码
    ICAN_ObjID->ACK = (Receive_ObjID >> 12) & 0x00000001; //应答标志
    ICAN_ObjID->DestMACID = (Receive_ObjID >> 13) & 0x000000FF; //目标节点编号
    ICAN_ObjID->SrcMACID = (Receive_ObjID >> 21) & 0x000000FF; //源节点编号
}

//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
uchar ICAN_ObjByte0Manage(uint TxCtr, uint Lenth) {
    //ICAN报文数据段0字节生成
    uchar ucTemp;
    if (Lenth < 8) {
        //小于8字节时
        ucTemp = 0; //分段标志SegFlag=0
    } else {
        //
        if (TxCtr == 0) {
            //批量数据的第一个分段
            ucTemp = 0x40;
        } else if (TxCtr + 7 >= Lenth) {
            //批量数据的最后一个分段
            ucTemp = 0xC0;
        } else {
            //中间数据段
            if (TxCtr > 448) {
                return (0xFF);
            }
            //发送数据超过448字节
            ucTemp = TxCtr / 7+0x80; //计数对应的段数,并标识为中间段
        }
    }
    return (ucTemp); //生成标识符			
}

//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
uchar ICAN_ObjByte0Restore(uint * RxCtr, uchar segflag) {
    //ICAN报文数据段0字节生成
    uchar ucTemp;
    if (segflag == 0) {//没有分段
        *RxCtr = 0x00; //接收数据指针指向零
        ucTemp = 0x00; //数据接收过程中
    } else if ((segflag & 0xC0) == 0xC0) {
        //批量数据的最后一个分段
        ucTemp = 65; //数据接收完毕
    } else  if ((segflag & 0x40) == 0x40) {//启始段
        //批量数据的第一个分段
        ucTemp = 0x01; //数据接收完毕
        *RxCtr = 0x00; //接收数据指针指向零
    } else {
        //中间数据段
        ucTemp = segflag & 0x3f; //数据接收过程中
        *RxCtr = (segflag&0x3f)*7; //接收数据指针
    }
    return (ucTemp); //生成标识符			
}
//****************************************************************************
//函数名称:void ICAN_ErrIDACK(uchar order) 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void ICAN_ErrorIDACK(uchar order,  uchar ErrID) {//错误代码返回报文
    //发送报文的生成
    ICAN_OBJ xdata ICAN_ObjIDTmp;
    ICAN_ObjIDTmp.SourceID = ICANSlav_ObjID[order].SourceID; //资源节点编号
    ICAN_ObjIDTmp.FUNCID = 0x0F; //功能码
    ICAN_ObjIDTmp.ACK = 1; //应答标志
    ICAN_ObjIDTmp.DestMACID = ICANSlav_ObjID[order].SrcMACID; //目标节点编号
    ICAN_ObjIDTmp.SrcMACID = ICANSlav_ObjID[order].DestMACID; //源节点编号
    
	ICAN_TrBuff[order].ulID = ICAN_ObjIDManage(&ICAN_ObjIDTmp); //生成ICAN报文ID
    ICAN_TrBuff[order].ucXID = 1; //  0 标准帧;1 扩展帧//  
    ICAN_TrBuff[order].ucDataBuff[0] = ErrID; //  返回对应的错误代码//
    ICAN_TrBuff[order].ucDataLenth = 2; //  数据场长度1字节//
    ICAN_TrBuff[order].ucDataCtr = 0; //  读数据指针指0字节//
    ICAN_TrBuff[order].TrBegin = 1; //发送开始标志置位	
}

//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
uchar function = 0;
void iCAN_ConnectACK(uchar order, tCANFrame *  pCANFrame) {
    //建立连接命令
    ICAN_OBJ xdata ICAN_ObjIDTmp;

	if(function>=1){
	    ICAN_ErrorIDACK(order,ErrID_NotCommand);//之前已经建立过连接,再次建立连接报错;	
	}
	else if(pCANFrame->ulID&0x00000400!=0x00000400){
		ICAN_ErrorIDACK(order,ErrID_NotFunctionID);//功能码不对;
	}										 
/* 	else if(ICAN_Source[order].Area[MasterMACID]!=pCANFrame->ucDataBuff[1]){//
		ICAN_ErrorIDACK(order,ErrID_NotCommand);//错误代码返回报文(命令不技持,主站ID不对);
	} */
 	else if((pCANFrame->ucDataBuff[0]!=0)){//参数非法 
		ICAN_ErrorIDACK(order,ErrID_ParameterError);//错误代码返回报文(参数非法)
	}
	else{
    ICAN_Source[order].Area[MasterMACID] = pCANFrame->ucDataBuff[1]; //读取目标主站节点的MACID
    ICAN_Source[order].Area[CyclicMaster] = pCANFrame->ucDataBuff[2]; //读取目标主站节点定时通信节拍数
    ICAN_ObjIDTmp.SourceID = 0xf7; //资源节点编号
    ICAN_ObjIDTmp.FUNCID = 0x04; //功能码
    ICAN_ObjIDTmp.ACK = 1; //应答标志
    ICAN_ObjIDTmp.DestMACID = ICAN_Source[order].Area[MasterMACID]; //目标节点编号
    ICAN_ObjIDTmp.SrcMACID = ICAN_Source[order].Area[MACID]; //源节点编号
    ICAN_TrBuff[order].ulID = ICAN_ObjIDManage(&ICAN_ObjIDTmp); //生成ICAN报文ID
    ICAN_TrBuff[order].ucXID = 1; //  0 标准帧;1 扩展帧//  
    ICAN_TrBuff[order].ucDataLenth = 5; //  数据场长度5字节//
    ICAN_TrBuff[order].ucDataCtr = 0; //  读数据指针指0字节//
    ICAN_TrBuff[order].ucDataBuff[0] = SourceType[order][0]; //  报文数据场2字节//DI资源数量
    ICAN_TrBuff[order].ucDataBuff[1] = SourceType[order][1]; //  报文数据场3字节//DO资源数量
    ICAN_TrBuff[order].ucDataBuff[2] = SourceType[order][2]; //  报文数据场4字节//AI资源数量
    ICAN_TrBuff[order].ucDataBuff[3] = SourceType[order][3]; //  报文数据场5字节//AO资源数量
    ICAN_TrBuff[order].TrBegin = 1; //发送开始标志置位	
	}
    function++;
}
//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void iCAN_MACIDTest(uchar order, uchar ack) {
    //MACID检测命令
    ICAN_OBJ xdata ICAN_ObjIDTmp;
    ICAN_ObjIDTmp.SourceID = 0xEE; //资源节点编号
    ICAN_ObjIDTmp.FUNCID = 0x07; //功能码
    ICAN_ObjIDTmp.ACK = ack; //应答标志
    ICAN_ObjIDTmp.DestMACID = ICAN_Source[order].Area[MACID]; //目标节点编号
    ICAN_ObjIDTmp.SrcMACID = ICAN_Source[order].Area[MACID]; //源节点编号
    ICAN_TrBuff[order].ulID = ICAN_ObjIDManage(&ICAN_ObjIDTmp); //生成ICAN报文ID
    ICAN_TrBuff[order].ucXID = 1; //  0 标准帧;1 扩展帧//  
    ICAN_TrBuff[order].ucDataLenth = 6; //  数据场长度6字节//
    ICAN_TrBuff[order].ucDataCtr = 0; //  读数据指针指0字节//
    ICAN_TrBuff[order].ucDataBuff[0] = ICAN_Source[order].Area[MACID]; //  报文数据场2字节//MACID
    ICAN_TrBuff[order].ucDataBuff[1] = ICAN_Source[order].Area[SerialNumber];//  报文数据场3字节//SN第1字节
    ICAN_TrBuff[order].ucDataBuff[2] = ICAN_Source[order].Area[SerialNumber+1]; //  报文数据场4字节//SN第2字节
    ICAN_TrBuff[order].ucDataBuff[3] = ICAN_Source[order].Area[SerialNumber+2]; //  报文数据场5字节//SN第3字节
    ICAN_TrBuff[order].ucDataBuff[4] = ICAN_Source[order].Area[SerialNumber+3]; //  报文数据场5字节//SN第4字节
    ICAN_TrBuff[order].TrBegin = 1; //发送开始标志置位	
}
//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void iCAN_UnConnectACK(uchar order, tCANFrame *  pCANFrame) {
    //删除连接命令
    ICAN_OBJ xdata ICAN_ObjIDTmp;

⌨️ 快捷键说明

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