📄 secdlink.c
字号:
}
//编辑从动站应答10帧
void EditSec101_2002Fra10(INT8U Port, INT8U Function)
{
INT8U i, j;
INT8U *p;
i = Port - 1;
if (ComLink[i]->TxdStatus==TXDSEND)
ComLink[i]->TxdTail=0;
ComLink[i]->FrameHead=ComLink[i]->TxdTail;
p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;
p[0]=STARTCODE10;
p[1]=Function;
ComLink[i]->LastControl=Function;
p[1]&=(~P101_DFC);
p[1]&=(~P101_PRM);
p[1]&=(~P101_DIR);//清方向位,防止干扰。
p[1]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0
//if(FlagData1&&(!BalanMode)&&(Function!=DLSTATUSOK))//一级数据位
if(ComLink[i]->FlagData1&&(!ComLink[i]->BalanMode))//一级数据位,为了适应胜利油田在链路过程总再次召唤链路的要求
p[1]|=P101_ACD;
else
p[1]&=(~P101_ACD);
for(j=0;j<ComLink[i]->LinkAddrSize;j++)
p[2+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);
p[2+ComLink[i]->LinkAddrSize]=CheckSum(Port,p);
p[3+ComLink[i]->LinkAddrSize]=ENDCODE;
ComLink[i]->TxdTail+=ComLink[i]->FixFrmLength;//移动发送尾指针
memcpy(ComLink[i]->TxdBuf_Sec,p,ComLink[i]->FixFrmLength);
ComLink[i]->TxdTail_Sec=ComLink[i]->FixFrmLength;
}
/*编辑68帧*/
//Function:链路功能码
//FrameLength:应用层报文长度(从类型标识开始),是应用层调用返回的
void S101_2002EditFra68(INT8U Port, INT8U Function, INT16U FrameLength)
{
INT8U *p, i;
INT16U length, j;
i = Port - 1;
if (ComLink[i]->TxdStatus==TXDSEND)
ComLink[i]->TxdTail=0;
ComLink[i]->FrameHead=ComLink[i]->TxdTail;
p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;
p[0]=p[3]=STARTCODE68;
p[1]=p[2]=FrameLength+1+ComLink[i]->LinkAddrSize;
p[4]=Function;
ComLink[i]->LastControl=Function;
if ((Function==DLSENDNOCON))
p[4]&=(~P101_FCV);
else
p[4]|=P101_FCV;
if (p[4]&P101_FCV)
{
if (ComLink[i]->TlaConCode&0x20)
{
p[4]&=(~P101_FCB);
ComLink[i]->TlaConCode&=0xDF;
}
else
{
p[4]|=P101_FCB;
ComLink[i]->TlaConCode|=0x20;
}
ComLink[i]->TlaConCode|=0x10;
}
else
{
p[4]&=(~P101_FCB);
ComLink[i]->TlaConCode&=0xEF;
}
p[4]|=P101_PRM;
p[4]&=(~P101_DIR);//清方向位,防止干扰。
p[4]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0。
for(j=0;j<ComLink[i]->LinkAddrSize;j++)
p[5+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);
length=7+ComLink[i]->LinkAddrSize+FrameLength;//全部报文长度
p[length-2]=CheckSum(Port, p);
p[length-1]=ENDCODE;
ComLink[i]->TxdTail+=length;
memcpy(ComLink[i]->TxdBuf_Pri,p,length);
ComLink[i]->TxdTail_Pri=length;
}
void EditSec101_2002Fra68(INT8U Port, INT8U Function, INT16U FrameLength)
{
INT8U *p, i;
INT16U length, j;
i = Port - 1;
if (ComLink[i]->TxdStatus==TXDSEND)
ComLink[i]->TxdTail=0;
ComLink[i]->FrameHead=ComLink[i]->TxdTail;
p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;
p[0]=p[3]=STARTCODE68;
p[1]=p[2]=FrameLength+1+ComLink[i]->LinkAddrSize;
p[4]=Function;
ComLink[i]->LastControl=Function;
if(ComLink[i]->FlagData1&&(!ComLink[i]->BalanMode))
p[4]|=P101_ACD;
else
p[4]&=(~P101_ACD);
p[4]&=(~P101_DFC);
p[4]&=(~P101_PRM);
p[4]&=(~P101_DIR);//清方向位,防止干扰。
p[4]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0。
for(j=0;j<ComLink[i]->LinkAddrSize;j++)
p[5+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);
length=7+ComLink[i]->LinkAddrSize+FrameLength;//全部报文长度
p[length-2]=CheckSum(Port,p);
p[length-1]=ENDCODE;
ComLink[i]->TxdTail+=length;
memcpy(ComLink[i]->TxdBuf_Sec,p,length);
ComLink[i]->TxdTail_Sec=length;
}
void SecEditE5(INT8U Port)//编辑E5帧
{
INT8U i;
i = Port - 1;
if (ComLink[i]->TxdStatus==TXDSEND)
ComLink[i]->TxdTail=0;
ComLink[i]->FrameHead=ComLink[i]->TxdTail;
*(ComLink[i]->TxdBuf+ComLink[i]->FrameHead)=0xe5;
ComLink[i]->LastControl=0xe5;
ComLink[i]->TxdTail++;
*(ComLink[i]->TxdBuf_Sec)=0xe5;
ComLink[i]->TxdTail_Sec=1;
}
void S101_2002DLSendProc(INT8U Port)
{
INT8U i;
i = Port - 1;
if(ComApp[i]->AppCommand&APP_HAVEDATA1)//还有一级数据
{
ComLink[i]->FlagData1=TRUE;
ComApp[i]->AppCommand&=0x7FFF;
}
else
ComLink[i]->FlagData1=FALSE;
switch(ComApp[i]->AppCommand)
{
case APP_APPCON: //应用层对收到的数据做应答
EditSec101_2002Fra10(Port, DLCON);
S101_2002SendDataToMISI(Port);
break;
case APP_APPDIABALE: //应用层无效
break;
case APP_SENDCON: //发送03命令
S101_2002EditFra68(Port, DLSENDCON,ComApp[i]->LengthOut);
S101_2002SendDataToMISI(Port);
ComLink[i]->TimeOutTick_Pri=TimeDelay(Port,ComApp[i]->LengthOut+8+5)+(ComLink[i]->TimeOutValue/100);
ComLink[i]->DLPriStatus=PRISENDCON;
ComLink[i]->RetryCount=MAXRETRYNUM;
break;
case APP_SENDNOCON: //发送04命令 平衡模式
S101_2002EditFra68(Port, DLSENDNOCON,ComApp[i]->LengthOut);
S101_2002SendDataToMISI(Port);
ComLink[i]->TimeOutTick_Pri=0;
break;
case APP_SENDDATA://发送08命令
EditSec101_2002Fra68(Port, DLRESDATA,ComApp[i]->LengthOut);
S101_2002SendDataToMISI(Port);
break;
case APP_NODATA://应用层无数据
if(!ComLink[i]->BalanMode)
{
SecEditE5(Port);
S101_2002SendDataToMISI(Port);
}
break;
case APP_NOJOB://应用层无任务
if(ComApp[i]->BalanMode&&(ComLink[i]->DLPriStatus==PRIWAITSTATUS))
CallDLStatus(Port);
break;
default:
break;
}
}
void CallUData(INT8U Port)//取紧急数据
{
INT8U i;
i= Port-1;
ComApp[i]->LengthIn=0;
ComApp[i]->DLCommand=DL_CALLUDATA;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002EditFra68(Port,DLSENDCON,ComApp[i]->LengthOut);
S101_2002SendDataToMISI(Port);
ComLink[i]->TimeOutTick_Pri=TimeDelay(Port, (ComApp[i]->LengthOut+8+5))+(ComLink[i]->TimeOutValue/100);
ComLink[i]->DLPriStatus=PRISENDCON;
ComLink[i]->RetryCount=MAXRETRYNUM;
}
//平衡模式的遥控过程
void CallUMsg(INT8U Port)//取遥控消息
{
INT8U i;
i = Port-1;
ComApp[i]->LengthIn=0;
ComApp[i]->DLCommand=DL_CALLDBMSG;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
if(ComApp[i]->LengthOut!=0)
{
S101_2002EditFra68(Port,DLSENDCON,ComApp[i]->LengthOut);
S101_2002SendDataToMISI(Port);
ComLink[i]->TimeOutTick_Pri=TimeDelay(Port, ComApp[i]->LengthOut+8+5)+(ComLink[i]->TimeOutValue/100);
ComLink[i]->DLPriStatus=PRISENDCON;
ComLink[i]->RetryCount=MAXRETRYNUM;
}
}
void SendDataEnd(INT8U Port) //发送结束
{
INT8U i;
i = Port - 1;
if(ComLink[i]->DLPriStatus==PRIENABLE)
{
switch(ComLink[i]->LastControl)//最近一次发送的命令
{
case DLSENDNOCON://平衡模式,发送04命令后调用应用层服务
case DLCON:
ComApp[i]->DLCommand=DL_SCAN1S;
ComApp[i]->LengthIn=0;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
break;
default:
break;
}
}
}
/*编辑10帧——启动站的10帧*/
void EditFra10(INT8U Port, INT8U Function)
{
INT8U *p, i, j;
i=Port-1;
if (ComLink[i]->TxdStatus==TXDSEND)
ComLink[i]->TxdTail=0;
ComLink[i]->FrameHead=ComLink[i]->TxdTail;
p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;
p[0]=STARTCODE10;
p[1]=Function;
ComLink[i]->LastControl=Function;
if ((Function==DLRESETRDL)||(Function==DLREQACD)||(Function==DLREQSTATUS))
p[1]&=(~P101_FCV);
else
p[1]|=P101_FCV;
if (p[1]&P101_FCV)//FCV有效,翻转FCB
{
if (ComLink[i]->TlaConCode&0x20)
{
p[1]&=(~P101_FCB);
ComLink[i]->TlaConCode&=0xDF;
}
else
{
p[1]|=P101_FCB;
ComLink[i]->TlaConCode|=0x20;
}
}
else//FCV无效,清FCB
p[1]&=(~P101_FCB);
p[1]|=P101_PRM;
p[1]&=(~P101_DIR);//清方向位,防止干扰。
p[1]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0。
for(j=0;j<ComLink[i]->LinkAddrSize;j++)
p[2+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);
p[2+ComLink[i]->LinkAddrSize]=CheckSum(Port,p);
p[3+ComLink[i]->LinkAddrSize]=ENDCODE;
ComLink[i]->TxdTail+=ComLink[i]->FixFrmLength;//移动发送尾指针
memcpy(ComLink[i]->TxdBuf_Pri,p,ComLink[i]->FixFrmLength);//将发送数据保存到启动站重发数据区
ComLink[i]->TxdTail_Pri=ComLink[i]->FixFrmLength;
}
BOOL DLStatusCheck(INT8U Port)
{
INT8U i;
i = Port - 1;
return (ComLink[i]->DLPriStatus==PRIENABLE);
}
//超时处理函数
void TimeOut(INT8U Port)
{
INT8U i;
i=Port-1;
if(ComLink[i]->TimeOutTick_Pri)//单位是秒
{
ComLink[i]->TimeOutTick_Pri--;
if(!ComLink[i]->TimeOutTick_Pri)
{
ComLink[i]->ComStatus.TimeOutCount++;
TimeOutFun(Port,1,1);
}
}
if(ComLink[i]->TimeOutTick_Sec)//单位是秒
{
ComLink[i]->TimeOutTick_Sec--;
if(!ComLink[i]->TimeOutTick_Sec)
{
ComLink[i]->ComStatus.TimeOutCount++;
TimeOutFun(Port,1,0);
}
}
if(ComLink[i]->BalanMode)//平衡模式下,为了在链路空闲期内及时处理应用层的一级数据任务,在超过设定的空闲时间后每秒检测应用层一次。
{
ComLink[i]->IdleTimeCount++;
if((ComLink[i]->IdleTimeCount>=ComLink[i]->DLIdleTime)&&(ComLink[i]->DLPriStatus==PRIENABLE))//DLIdleTime最小不能小于2
{
ComApp[i]->DLCommand=DL_SCAN1S;
ComApp[i]->LengthIn=0;
//应用层调用
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -