📄 icanslave.c
字号:
/****************************************************************************
将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 + -