📄 icanslave.c
字号:
//输出参数:
//返 回 值:
//创建日期: 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 + -