📄 secapp.c
字号:
ComApp[i]->LastDevIndex=ComApp[i]->ActDevIndex;
ComApp[i]->LastFrame=BI;
ComApp[i]->BIFrame|=BIETFRAME;
ComApp[i]->LastDevType = SOEDATA;
ComApp[i]->LastDevNum = info.Num;
ComApp[i]->LengthOut=Len;
if(ComApp[i]->BalanMode)
ComApp[i]->AppCommand=APP_SENDCON;
else
ComApp[i]->AppCommand=APP_SENDDATA;
if(info.Num<0x10) //读完数据
ComApp[i]->Data1.Flag &= (~HaveSOE);
return;
}
ComApp[i]->Data1.Flag &= (~HaveSOE);
ComApp[i]->AppCommand = APP_NODATA;
}
//OK
void S101EnCodeAllDataConf(INT8U Port)//总召唤确认帧
{
INT8U i,jj;
INT16U addr;
i=Port-1;
ComApp[i]->TxMsg[0]=C_IC_NA;
*(ComApp[i]->pTxVSQ) = 1;
addr=S101GetAddrByDevIndex(Port, ComApp[i]->GroupTrn.DevIndex);
for(jj=0;jj<ComApp[i]->PubAddrSize;jj++)
ComApp[i]->TxMsg[ComApp[i]->PubAddrLocation+jj]=addr>>(8*jj);
*(ComApp[i]->pTxInfoAddr)=0;
*(ComApp[i]->pTxInfoAddr+1)=0;
ComApp[i]->TxMsg[ComApp[i]->CotLocation]=ACTCON;
*(ComApp[i]->pTxData)=ComApp[i]->GroupTrn.COT;//INTROGEN=20,响应总召唤——总召唤限定词或分组限定词
ComApp[i]->LengthOut=ComApp[i]->AsduHeadLength+1;
ComApp[i]->AppCommand=APP_SENDDATA;
ComApp[i]->AppCommand|=APP_HAVEDATA1;
if(ComApp[i]->BalanMode)
ComApp[i]->AppCommand=APP_SENDCON;
}
void S101ProcAllData(INT8U Port) //处理全数据
{
BOOL rc;
INT8U i, j, no, len, jj;
INT16U num, curnum, ycno, addr;
struct DBInfo info;
short Value;
i=Port-1;
no = ComApp[i]->GroupTrn.GroupNo;
curnum = ComApp[i]->GroupTrn.InfoAddr % 0x80;
info.SuperID = ComDb[i]->DBCfgs->DevID;
info.DevID = ComApp[i]->GroupTrn.DevIndex;
if ((no >= 1) && (no <= 8))//1——8组,遥信
{
num = 120; //一帧数据个数
info.Type = YXDATA;
info.Start = ComApp[i]->GroupTrn.InfoAddr - LBI;
if ((curnum+num) > 0x80)
{
info.Num = 0x80 - curnum;
ComApp[i]->GroupTrn.GroupNo++;
}
else
info.Num = num;
}
else if ((no >= 9) && (no <= 12)) //处理遥测
{
num = 60;
info.Type = YCDATA;
info.Start = ComApp[i]->GroupTrn.InfoAddr - LAI;
if ((curnum+num) > 0x80)
{
info.Num = 0x80 - curnum;
ComApp[i]->GroupTrn.GroupNo++;
}
else
info.Num = num;
}
else if (no == 13) //处理步位置信息
{
ComApp[i]->GroupTrn.GroupNo = 17;
}
else if (no == 14) //处理BCD码
{
ComApp[i]->GroupTrn.GroupNo = 17;
}
else if (no == 15) //处理子站远动终端
{
ComApp[i]->GroupTrn.GroupNo = 17;
}
else if (no == 16) //处理备用
{
ComApp[i]->GroupTrn.GroupNo = 17;
}
if (ComApp[i]->GroupTrn.GroupNo == 17) //数据发送完毕
{
ComApp[i]->AllDataNum++;
if (ComApp[i]->AllDataNum < ComDb[i]->DBCfgs->Info.Logic.DevNum) //指向下一台设备
{
if (!S101GetNextActDevIndex(Port, ComApp[i]->ActDevIndex, ACTDEVINDEX))
{
if(!(ComApp[i]->Sec101Pad.PBase.CmdControl&SETSECTIME))
ComApp[i]->MasterStatus=INUSE;
return;
}
else
{
ComApp[i]->GroupTrn.DevIndex = ComApp[i]->ActDevIndex;
ComApp[i]->GroupTrn.GroupNo = 1;
ComApp[i]->GroupTrn.InfoAddr = LBI;
ComApp[i]->EditAllDataCon=0xff;
ComApp[i]->Data1.Flag|=CallAllData;
}
}
else
{
if (ComApp[i]->GroupTrn.COT==BACK)//背景数据,无结束帧
{
ComApp[i]->AllDataNum = 0;
ComApp[i]->Data2Flag&=(~BackData);
ComApp[i]->LengthOut=0;
ComApp[i]->AppCommand=APP_NODATA;
return;
}
ComApp[i]->Data1.Flag&=(~CallAllData);
EnCodeGroupEnd(Port);
ComApp[i]->EditAllDataCon = 0xff;
ComApp[i]->AllDataNum = 0;
memset ((void *)&ComApp[i]->GroupTrn, 0, sizeof (struct PGroupTrn));
return;
}
}
rc = DBRead(ComApp[i]->Tmpbuf, &info); //读取数据
switch (info.Type) //组帧
{
case YXDATA:
if (info.Num)
{
ComApp[i]->TxMsg[0] = ComApp[i]->Sec101Pad.TypeID[ComApp[i]->GroupTrn.GroupNo-1];
(*ComApp[i]->pTxVSQ) |= VSQ_SQ;
ComApp[i]->TxMsg[ComApp[i]->CotLocation]=ComApp[i]->GroupTrn.COT;
len=SetMsg(Port,ComApp[i]->Tmpbuf,info.Num);
addr=S101GetAddrByDevIndex(Port, ComApp[i]->GroupTrn.DevIndex);
for(jj=0;jj<ComApp[i]->PubAddrSize;jj++)
ComApp[i]->TxMsg[ComApp[i]->PubAddrLocation+jj] = addr>>(8*jj);
*(ComApp[i]->pTxInfoAddr)=LOBYTE((ComApp[i]->GroupTrn.InfoAddr));
*(ComApp[i]->pTxInfoAddr+1)=HIBYTE((ComApp[i]->GroupTrn.InfoAddr));
ComApp[i]->LengthOut = len;
ComApp[i]->GroupTrn.InfoAddr += info.Num;
if (ComApp[i]->BalanMode)//平衡模式
{
if(ComApp[i]->GroupTrn.COT==BACK)
ComApp[i]->AppCommand=APP_SENDNOCON;
else
ComApp[i]->AppCommand=APP_SENDCON;
}
else//非平衡,可能是总召唤、分组、背景数据
{
ComApp[i]->AppCommand=APP_SENDDATA;
if(ComApp[i]->GroupTrn.COT!=BACK)//背景数据不设置一级数据标志
ComApp[i]->AppCommand|=APP_HAVEDATA1;
}
}
if ((!rc) || (info.Num != num))
{
if (ComApp[i]->GroupTrn.COT == REQ) //处理单组
ComApp[i]->GroupTrn.GroupNo = 17;
else
{
ComApp[i]->GroupTrn.GroupNo = 9;
ComApp[i]->GroupTrn.InfoAddr = LAI;
}
}
break;
case YCDATA:
if (info.Num)
{
ComApp[i]->TxMsg[0] = ComApp[i]->Sec101Pad.TypeID[ComApp[i]->GroupTrn.GroupNo-1];
(*ComApp[i]->pTxVSQ) |= VSQ_SQ;
ComApp[i]->Data2Flag &= (~HaveNVA);
ycno = S101GetActDevNo(Port, ComApp[i]->NvaActDevNo, YCDATA);
memcpy ((INT8U*)&ComApp[i]->YCValue[ycno], ComApp[i]->Tmpbuf, info.Num * 2);
switch(ComApp[i]->TxMsg[0])
{
case M_ME_NA: //9测量值,规一化值
len = 3;
for (j=0; j<info.Num; j++)
{
Value = (long)(ComApp[i]->Tmpbuf[2*j]+(ComApp[i]->Tmpbuf[2*j+1]<<8))*0x3FFF/(long)ComApp[i]->AIMaxVal[ycno+j];
memcpy ((ComApp[i]->pTxData+3*j), (INT8U*)&Value, 2);
ComApp[i]->pTxData[3*j + 2] = 0x00; //QDS
}
break;
case M_ME_NB: //11测量值,标度值
len = 3;
for (j=0; j<info.Num; j++)
{
memcpy ((ComApp[i]->pTxData+3*j), &ComApp[i]->Tmpbuf[2*j], 2);
ComApp[i]->pTxData[3*j + 2] = 0x00; //QDS
}
break;
default:
ComApp[i]->TxMsg[0] = M_ME_ND; //21不带品质描述的规一化值
len = 2;
for (j=0; j<info.Num; j++)
{
memcpy ((ComApp[i]->pTxData+2*j), &ComApp[i]->Tmpbuf[2*j], 2);
}
break;
}
(*ComApp[i]->pTxVSQ) = 0x80 | info.Num;
ComApp[i]->TxMsg[ComApp[i]->CotLocation] = ComApp[i]->GroupTrn.COT;
addr=S101GetAddrByDevIndex(Port, ComApp[i]->GroupTrn.DevIndex);
for(jj=0;jj<ComApp[i]->PubAddrSize;jj++)
ComApp[i]->TxMsg[ComApp[i]->PubAddrLocation+jj]=addr>>(8*jj);
*(ComApp[i]->pTxInfoAddr) =LOBYTE((ComApp[i]->GroupTrn.InfoAddr));
*(ComApp[i]->pTxInfoAddr+1)=HIBYTE((ComApp[i]->GroupTrn.InfoAddr));
ComApp[i]->LengthOut = ComApp[i]->AsduHeadLength + info.Num * len;
ComApp[i]->GroupTrn.InfoAddr += info.Num;
if (ComApp[i]->BalanMode)//平衡模式,总召唤或周期循环、或背景数据
{
if((ComApp[i]->GroupTrn.COT==BACK)||(ComApp[i]->GroupTrn.COT==PERCYC))
ComApp[i]->AppCommand=APP_SENDNOCON;
else
ComApp[i]->AppCommand=APP_SENDCON;
}
else//分组或总召唤,
{
ComApp[i]->AppCommand=APP_SENDDATA;
if((ComApp[i]->GroupTrn.COT!=PERCYC)&&(ComApp[i]->GroupTrn.COT!=BACK))
ComApp[i]->AppCommand|=APP_HAVEDATA1;
}
}
if ((!rc) || (info.Num != num))
{
ComApp[i]->GroupTrn.GroupNo = 17;
}
break;
default:
break;
}
//OSFlagPost(ComDb[i]->Event, FTXNEXT, OS_FLAG_SET, &err);
return;
}
//OK
INT8U SetMsg(INT8U Port,INT8U *pBuf,INT8U pNum) //组织发送帧;
{
INT16S FramePos;
INT16U i,j,len,no;
INT8U val;
struct SOE_t *soe;
struct COS_t *cos;
struct IEC101Time_t time;
struct SCDYX yx;
i=Port-1;
*(ComApp[i]->pTxVSQ) &= VSQ_SQ;
if(ComApp[i]->TxMsg[0]==M_PS_NA)
{
len = 0;
no = 0;
memset ((INT8U*)&yx, 0, sizeof (struct SCDYX));
yx.InfoAddr = ComApp[i]->GroupTrn.InfoAddr;
}
if ((*(ComApp[i]->pTxVSQ) & VSQ_SQ) == 0)//信息是散列的,每个信息都有自己的2字节的信息体地址
{
FramePos=-2;
if(ComApp[i]->InfoAddrSize==3)
FramePos=-3;
}
else//信息是序列的,所有信息只有开始的信息体地址,其他信息体地址顺序加1。
FramePos=0;
for(j=0; j<pNum; j++)
{
switch (ComApp[i]->TxMsg[0])
{
case M_SP_NA: //不带时标的单点信息
if ((*ComApp[i]->pTxVSQ & VSQ_SQ) == 0)
{
cos = (struct COS_t*)pBuf + j;
if ((FramePos==-2)||(FramePos==-3))//第一个信息的信息体放在缓冲区的头中
{
*(ComApp[i]->pTxInfoAddr)=LOBYTE(cos->No+LBI);
*(ComApp[i]->pTxInfoAddr+1)=HIBYTE(cos->No+LBI);
}
else//其他依次放到Data[]中相应位置
{
*(ComApp[i]->pTxData+FramePos)=LOBYTE(cos->No+LBI);
*(ComApp[i]->pTxData+FramePos+1)=HIBYTE(cos->No+LBI);
}
FramePos+=ComApp[i]->InfoAddrSize;
if (cos->Status == YX_H)
val = 0x01;
else
val = 0x00;
}
else
{
if (ComApp[i]->Tmpbuf[j] == YX_H)
val = 0x01;
else
val = 0x00;
}
*(ComApp[i]->pTxData+FramePos)=val;
FramePos+=sizeof(BYTE);
break;
case M_PS_NA: //具有状态变位检出的成组单点信息
if (ComApp[i]->Tmpbuf[j] == YX_H)
yx.ST |= (0x0001<<len);
len++;
if (len >= 16)
{
if(no==0)
{
memcpy ((INT8U*)(ComApp[i]->pTxInfoAddr), (INT8U*)&yx, sizeof (struct SCDYX));
if(ComApp[i]->InfoAddrSize==3)
FramePos+=sizeof (struct SCDYX) - 3;
else
FramePos+=sizeof (struct SCDYX) - 2;
}
else
{
memcpy ((INT8U*)(ComApp[i]->pTxData+FramePos), (INT8U*)&yx, sizeof (struct SCDYX));
FramePos+=sizeof (struct SCDYX);
}
len = 0;
no++;
yx.ST = 0;
yx.InfoAddr = ComApp[i]->GroupTrn.InfoAddr + no*16;
}
break;
case M_SP_TA: //带24时标的单点信息
soe = (struct SOE_t*)pBuf + j;
if ((FramePos==-2)||(FramePos==-3))//第一个信息的信息体放在缓冲区的头中
{
*(ComApp[i]->pTxInfoAddr)=LOBYTE(soe->No+LBI);
*(ComApp[i]->pTxInfoAddr+1)=HIBYTE(soe->No+LBI);
}
else//其他依次放到Data[]中相应位置
{
*(ComApp[i]->pTxData+FramePos)=LOBYTE(soe->No+LBI);
*(ComApp[i]->pTxData+FramePos+1)=HIBYTE(soe->No+LBI);
}
FramePos+=ComApp[i]->InfoAddrSize;
if (soe->Status == YX_H)
val = 0x01;
else
val = 0x00;
*(ComApp[i]->pTxData+FramePos) = val;
*(ComApp[i]->pTxData+FramePos+1) = LOBYTE(soe->Time.Msecond);
*(ComApp[i]->pTxData+FramePos+2) = HIBYTE(soe->Time.Msecond);
*(ComApp[i]->pTxData+FramePos+3) = soe->Time.Minute%60;
FramePos+=4;
break;
case M_SP_TB: //带56时标的单点信息
soe = (struct SOE_t*)pBuf + j;
if ((FramePos==-2)||(FramePos==-3))//第一个信息的信息体放在缓冲区的头中
{
*(ComApp[i]->pTxInfoAddr)=LOBYTE(soe->No+LBI);
*(ComApp[i]->pTxInfoAddr+1)=HIBYTE(soe->No+LBI);
}
else//其他依次放到Data[]中相应位置
{
*(ComApp[i]->pTxData+FramePos)=LOBYTE(soe->No+LBI);
*(ComApp[i]->pTxData+FramePos+1)=HIBYTE(soe->No+LBI);
}
FramePos+=ComApp[i]->InfoAddrSize;
if (soe->Status == YX_H)
val = 0x01;
else
val = 0x00;
*(ComApp[i]->pTxData+FramePos) = val;
TimeChange((void*)&time, IEC101TIME, (void*)&soe-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -