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

📄 icanslave.c

📁 ICAN协议例程
💻 C
📖 第 1 页 / 共 3 页
字号:
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void ICANRxMsgObjExplain(uchar order) {
    //ICAN模块从机通信接收处理程序
    tCANFrame xdata CANFrame;
    if (ICAN_ControlInfo[order].ReDataCtr) {
        //有数据处理,需要处理数据
        ICAN_ControlInfo[order].ReDataCtr--;
//需要加入你的代码===================================================================
        if (CAN_ucReadBuffer(pReceFrameBuff[order], &CANFrame) != EMPTY) {
//       if (1) {//如果到数据
//需要加入你的代码===================================================================
            //如果数据不为空则处理
            ICAN_ObjIDRestore(&ICANSlav_ObjID[order], CANFrame.ulID);
            //ICAN报文标识码还原
           switch (ICANSlav_ObjID[order].FUNCID) {
                //根据功能处理对应报文
                case 0x01:
                    //用于对单个或者多个资源节点的数据写入
                    iCAN_WriteACK(order, ICANSlav_ObjID[order].SourceID, &CANFrame); //写数据命令命令
                   break;
                case 0x02:
                    //用于对单个或者多个资源节点的数据读取
                    iCAN_ReadACK(order, ICANSlav_ObjID[order].SourceID, &CANFrame); //读数据命令命令
                    break;
                case 0x03:
                    //返回0X0F出错响应
 					ICAN_ErrorIDACK(order, ErrID_NotFunctionID) ;//错误代码返回报文
					//iCAN_CyclicACK(order);
                    break;
                case 0x04:
                    //用于和iCAN节点建立连接
                    iCAN_ConnectACK(order, &CANFrame); //建立连接命令
                    break;
                case 0x05:
                    //用于删除与iCAN节点建立的连接
                    iCAN_UnConnectACK(order, &CANFrame); //建立连接命令
                    break;
                case 0x06:
                    //用于复位iCAN节点
                    iCAN_ResetACK(order, &CANFrame); //建立连接命令
                    break;
                case 0x07:
					//用于检测是否有相同的MACID
                    if(ICANSlav_ObjID[order].ACK==0){//接收到检测命令
					 	//用于响应网络上是否有相同MACID节点的检测
						iCAN_MACIDTest(order,1);//接收到MACID检测命令并返回响应命令
                    }else{//接收到响应命令
						MACIDTemp=ICAN_Source[order].Area[MACID];//记录当前的MACID
						ICAN_ControlInfo[order].MACIDTestStep = 9;//检测到相同的MACID节点
					}
					break;
                default://功能码不存在
                    //返回0X0F出错响应
 					ICAN_ErrorIDACK(order, ErrID_NotFunctionID) ;//错误代码返回报文
                    break;
            }
        }
    }
}



//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
 /*void ICANSlaveISR(uchar order, unsigned long ulMsgObjID) {
    //ICAN模块从机通信处理程序
    tCANFrame xdata CANFrame;
    if (ulMsgObjID) {
        //有中断产生   
       
         // 中断接收数据
        for (i = 0; i < 4; i++) {
            //对4个接收邮箱进行读数据处理
            if (ulMsgObjID & (0x00000001 << (ulICANRxMsgNbrTbl[i] - 1))) {
                //只要有一个邮箱接收数据则进行处理
                MsgObjectBuf.pucMsgData = CANFrame.ucDataBuff; //获取数据指针
                CANMessageGet(pCAN_Node_Info[order]->ulChNr, ulICANRxMsgNbrTbl[i], &MsgObjectBuf, 1); //读取邮箱数据
                if (pReceFrameBuff[order]->ucBufFull != 0) {
                    //接收缓冲区未满 
                    CANFrame.ucXID = 1; //扩展ID
                    CANFrame.ulID = (MsgObjectBuf.ulMsgID & 0x1FFFFFFF); //读取ID内容
                    CANFrame.ucDLC = MsgObjectBuf.ulMsgLen; //获取数据长度
                    CAN_ucWriteBuffer(pReceFrameBuff[order], &CANFrame);//  把接收的数据写入指定的接收缓存
                    
                }
                ICAN_ControlInfo[order].ReDataCtr++;
            }
        }
         */
        /*
         *  中断发送数据
         
        for (i = 0; i < 4; i++) {
            //对4个发送邮箱进行读数据处理
            if ((ulMsgObjID & (0x00000001 << (pCAN_Node_Info[order]->ulTxMsgObjNr - 1)))) {//有中断生产
                ClearIntFlag(pCAN_Node_Info[order], pCAN_Node_Info[order]->ulTxMsgObjNr);//清除发送中断标志
//                if ((SendBuffToBus((void*)pCAN_Node_Info[order])) == 0) {
//                    //总线不忙
                    ICAN_ControlInfo[order].Idle = 0;
//                }
            }
        }
    }
} */

//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
uchar ICANTime1ms;
void ICAN_DlyCtr(uchar order) {//定时器处理程序
    
    //处理通信延时计数器
    ICANTime1ms++; //毫秒计数器加1
    if (ICANTime1ms >= 10) {
        //累积到10MS(ICAN时间片单位)
        ICANTime1ms -= 10; //毫秒计数器减10
        if (ICAN_ControlInfo[order].MACIDTestStep == 10) {
            //MACID检测完成,正常通信
            if (ICAN_Source[order].Area[CyclicMaster]) {
                //如果不为0则有连接超时
                if ((ICAN_ControlInfo[order].ConnectTOTimer >> 2) > ICAN_Source[order].Area[CyclicMaster]) {
                    //超过连接超时时间//连接定时器
                    ICAN_ControlInfo[order].ConnectTOFlag = 1; //连接超时标志置位
                }else{//连接未超时
                    ICAN_ControlInfo[order].ConnectTOFlag = 0; //连接超时标志清零
                	ICAN_ControlInfo[order].ConnectTOTimer++; //连接定时器+1
				}
            } else {
                //没有连接超时
                ICAN_ControlInfo[order].ConnectTOFlag = 0; //连接超时标志清零
                ICAN_ControlInfo[order].ConnectTOTimer = 0; //连接超时定时器清零
            }
            if (ICAN_Source[order].Area[CyclicParameter]) {
                //基于时间触发的通信//循环传送定时器
                ICAN_ControlInfo[order].CyclicTimer++; //循环传送定时器+1
                if (ICAN_ControlInfo[order].CyclicTimer > ICAN_Source[order].Area[CyclicParameter]) {
                    //循环传送时间//循环传送定时器
                    ICAN_ControlInfo[order].CyclicParameterFlag = 1; //循环传送标志置位
                    ICAN_ControlInfo[order].CyclicTimer = 0; //循环传送定时器清零
               }
            } else {
                //不存在基于时间触发的通信
                ICAN_ControlInfo[order].CyclicParameterFlag = 0; //循环传送标志清零
                ICAN_ControlInfo[order].CyclicTimer = 0; //循环传送定时器清零
            }
        } else if (ICAN_ControlInfo[order].MACIDTestStep < 10) {
            //检测MACID两次
            if (ICAN_ControlInfo[order].MACIDTestTimer < 101) {
                //MACID检测定时器小于1S
                ICAN_ControlInfo[order].MACIDTestTimer++; //MACID检测定时器+1
            }
        }
    }
}

//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void ICANTxMsgObjSend(uchar order) {//单帧发送报文
    //ICAN模块从机通信接收处理程序
    tCANFrame xdata CANFrame;
 	tICAN_RWBUFF  *pICAN_TrBuff;  //定义一个从机ICAN节点资源读缓冲 
   uchar i;
    if ((ICAN_TrBuff[order].TrBegin||ICAN_TrBuffR[order].TrBegin||ICAN_TrBuffC[order].TrBegin) 
		&& (ICAN_ControlInfo[order].Idle == 0)) {
        if(ICAN_TrBuff[order].TrBegin){//通用报文发送
		  pICAN_TrBuff=(tICAN_RWBUFF *)(&ICAN_TrBuff[order]);
		}else if(ICAN_TrBuffR[order].TrBegin){//读应答报文发送
		  pICAN_TrBuff=&ICAN_TrBuffR[order];
		}else{//循环应答报文发送
		  pICAN_TrBuff=&ICAN_TrBuffC[order];
		}		
		//发送标志有效并且总组空闲
		CANFrame.ulID = pICAN_TrBuff->ulID; //生成ICAN报文ID
        CANFrame.ucXID = pICAN_TrBuff->ucXID; //  0 标准帧;1 扩展帧//  
         CANFrame.ucDataBuff[0] = ICAN_ObjByte0Manage(pICAN_TrBuff->ucDataCtr, pICAN_TrBuff->ucDataLenth); //生成分段码
        if((CANFrame.ulID&0x00000F00)!=0x00000F00){//不是正常功能码
		       ICAN_ControlInfo[order].ConnectTOTimer = 0; //连接超时定时清零
		}	//为正常功能码时,定时清0;为异常功能码时,不清0;
       for (i = 1; i < 8; i++) {
            //获取8个字节
            CANFrame.ucDataBuff[i] = pICAN_TrBuff->ucDataBuff[pICAN_TrBuff->ucDataCtr]; //  报文数据场1字节//
            pICAN_TrBuff->ucDataCtr++; //数据指针加1
            if (pICAN_TrBuff->ucDataCtr >= pICAN_TrBuff->ucDataLenth) {
                //发送缓冲的数据没读取完毕
                pICAN_TrBuff->TrBegin = 0; //数据发送完毕
                break; //退出
            }
        }
        CANFrame.ucDLC = i; //  写入数据场长度
//===================================================================================================================
//加入你的发送缓冲代码
//===================================================================================================================

        CAN_ucWriteBuffer(pSendFrameBuff[order], &CANFrame); //将数据帧写入发送缓冲 
         if (SendBuffToBus((void*)pSendFrameBuff[order])) {//数据发送
		    ICAN_ControlInfo[order].CyclicTimer = 0; //此句为自己添加的,
			//循环传送定时器清零,如果是循环发送数据的话,将从发送完应答信息之后开始;
            ICAN_ControlInfo[order].Idle = 0;//发送成功总线忙

		    SFRPAGE = CONFIG_PAGE;
        	P7MDOUT=0x03;	
	        led0 =~led0;  //通信时,灯(P7.0)闪烁;

        }else{//没有发送成功则继续
            ICAN_ControlInfo[order].Idle = 2;
		}
//===================================================================================================================
//===================================================================================================================
    }
	if(ICAN_ControlInfo[order].Idle == 2){//没有发送成功继续发送
        if (SendBuffToBus((void*)pCAN_Node_Info[order])) {//数据发送
            ICAN_ControlInfo[order].Idle = 0;//发送成功总线忙

			SFRPAGE = CONFIG_PAGE;
        	P7MDOUT=0x03;	
	        led0 =~led0;  //通信时,灯(P7.0)闪烁;
        }
	}
}
//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void ICAN_Schedul(uchar order) {//ican通信调度程序
    //ican通信调度程序
    if (ICAN_ControlInfo[order].MACIDTestStep == 10) {//进入正常通信
        if(ICAN_ControlInfo[order].CyclicParameterFlag){//定时传送时间到
			iCAN_CyclicACK(order); //输入端口定时循环或者状态改变传送命令
            ICAN_ControlInfo[order].CyclicParameterFlag = 0; //循环传送标志置位
	    }
		    ICANRxMsgObjExplain(order); //ICAN模块从机通信接收处理程序
	    ICANTxMsgObjSend(order); //ICAN模块从机通信接收处理程序
    } else if (ICAN_ControlInfo[order].MACIDTestStep == 0) {//检测有没有与自己相同的MACID
//     	tCANFrame CANFrame;	 //将其屏蔽掉,因为没有用到,多余定义了一个结构体;
		iCAN_MACIDTest(order,0);//生成MACID检测报文
		ICANTxMsgObjSend(order);//发送数据到总线
	 	if(ICAN_ControlInfo[order].Idle == 0){//发送成功
			ICAN_ControlInfo[order].MACIDTestTimer=0;//MACID定时器清零
			ICAN_ControlInfo[order].MACIDTestStep = 1;//等待超时
		}
   	}else if (ICAN_ControlInfo[order].MACIDTestStep == 1) {//检测有没有与自己相同的MACID
    	if(ICAN_ControlInfo[order].MACIDTestTimer>100){//超时时间到没有检测到响应报文
			ICAN_ControlInfo[order].MACIDTestStep = 2;//再检测一次
		}
	}else if (ICAN_ControlInfo[order].MACIDTestStep == 2) {//检测有没有与自己相同的MACID
//     	tCANFrame CANFrame;	 //将其屏蔽掉,因为没有用到,多余定义了一个结构体;
		iCAN_MACIDTest(order,0);//生成MACID检测报文
		ICANTxMsgObjSend(order);//发送数据到总线
	 	if(ICAN_ControlInfo[order].Idle == 0){//发送成功
			ICAN_ControlInfo[order].MACIDTestTimer=0;//MACID定时器清零
			ICAN_ControlInfo[order].MACIDTestStep = 3;//等待超时
		}
    }else if (ICAN_ControlInfo[order].MACIDTestStep == 3) {//检测有没有与自己相同的MACID
    	if(ICAN_ControlInfo[order].MACIDTestTimer>100){//超时时间到没有检测到响应报文
			ICAN_ControlInfo[order].MACIDTestStep = 10;//进入正常通信
		}
	}else {//其他情况(预操作状态)
		if(MACIDTemp!=ICAN_Source[order].Area[MACID]){//等待MACID的改变
			ICAN_ControlInfo[order].MACIDTestStep=0;//继续检测是否相同的MACID
		}
	}
}
//****************************************************************************
//函数名称: 
//函数功能: 
//输入参数: 
//          
//          
//输出参数: 
//返 回 值: 
//创建日期: 2008.05.04
//创 建 人: 
//参考文档:
//说    明: 
//修改历史:
//****************************************************************************
void ICANSlaveCom(uchar order) {
	ICAN_Schedul(order) ;//ican通信调度程序
}




























⌨️ 快捷键说明

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