📄 functions.cpp
字号:
buf[1] = 0x0F;
buf[2] = 0;
buf[3] = ykno;
buf[4] = 0;
buf[5] = 1;
buf[6] = 1;
buf[7] = value;
WORD crc = CRC16(buf, 8);
buf[8] = LOBYTE(crc);
buf[9] = HIBYTE(crc);
}
// 解遥控报文
local
BOOL Explain_YK(BYTE *buf,RTU *rtu)
{
/* ADDR 0FH 遥控对象 QUANTITY CRC16 10+8=18
1byte 1byte 2byte 2byte 2byte */
if( (buf[0]!=rtu->Addr) ||
(buf[1]!=0x0F) ||
(buf[2]!=rtu->YkNoHigh) ||
(buf[3]!=rtu->YkNoLow) ||
(MAKEWORD(buf[4],buf[5])!=0x0001) ) //
return FALSE;
WORD crc = CRC16(buf, 6);
if(crc!=MAKEWORD(buf[6],buf[7]))
return FALSE;
return TRUE;
}
//
void Explain_YKYT_SELECT(BOOL rel,CChannel *tempCh,RTU *pRtu)
{
pRtu->YKEchoFlag = TRUE;
pRtu->YKEcho[1] = rel?0x33:0xFF;
tempCh->nWaitRcv = 0;
}
//
local
BOOL Explain(CChannel *tempCh,CSystemPara *sp,RTU *pRtu,int num)
{
BOOL rel = FALSE;
switch (tempCh->nWaitRcv)
{
case CMD_YC1:
rel = Explain_YC1(tempCh->RcvBuf,pRtu);
break;
case CMD_YC2:
rel = Explain_YC2(tempCh->RcvBuf,pRtu);
break;
case CMD_YC3:
rel = Explain_YC3(tempCh->RcvBuf,pRtu);
break;
case CMD_YX:
rel = Explain_YX(tempCh->RcvBuf,pRtu,tempCh,sp);
break;
case CMD_YK:
rel = Explain_YK(tempCh->RcvBuf,pRtu);
break;
case CMD_YT:
rel = Explain_YT(tempCh->RcvBuf,pRtu);
break;
case CMD_YK_SELECT:
case CMD_YT_SELECT:
rel = Explain_YX(tempCh->RcvBuf,pRtu,tempCh,sp);
Explain_YKYT_SELECT(rel,tempCh,pRtu);
break;
}
if(rel)
pRtu->nReply = NORMAL_REPLY;
return rel;
}
//
local
BOOL AddDataToList(CChannel *tempCh, COMDATA *cd)
{
if(tempCh->DGramLink != NULL)
{
delete tempCh->DGramLink;
tempCh->DGramLink = NULL;
}
tempCh->DGramLink = cd;
tempCh->scflag = WAITSEND;
return TRUE;
}
//
void MakeFrame(CChannel *tempCh, CSystemPara *sp, BYTE RtuNo, BYTE type)
{
BYTE *buf;
BYTE lenth;
COMDATA *tempCd;
RTU *pRtu = sp->m_rtus[RtuNo];
tempCd = new COMDATA();
tempCd->RtuNo = RtuNo;
lenth = (type==CMD_YK)?10:8;
tempCd->SendBuf = new BYTE[lenth];
tempCd->SendNum = lenth;
buf = tempCd->SendBuf;
memset(buf,0,lenth);
switch(type)
{
case CMD_YX:
tempCd->RecNum = 41;
MakeFrame_YX(buf,pRtu->Addr);
break;
case CMD_YC1:
tempCd->RecNum = 49;
MakeFrame_YC1(buf,pRtu->Addr);
break;
case CMD_YC2:
tempCd->RecNum = 45;
MakeFrame_YC2(buf,pRtu->Addr);
break;
case CMD_YC3:
tempCd->RecNum = 45;
MakeFrame_YC3(buf,pRtu->Addr);
break;
case CMD_YK_SELECT:
case CMD_YT_SELECT:
tempCd->RecNum = 41;
MakeFrame_YX(buf,pRtu->Addr);
break;
case CMD_YK:
// sp->YKReserved[3]: 0-21 遥控序号
tempCd->RecNum = 8;
/* 遥控对象 */ /* 值 */
MakeFrame_YK(buf,pRtu->Addr,sp->YKReserved[3]+1,sp->YKReserved[7]);
break;
case CMD_YT:
{// sp->YKReserved[3]: 0-2 遥调序号 0 - 一/二段控母电压 1 - 一组电池电压 2 - 二组电池电压
BYTE yttype, tmp;
if(sp->YKReserved[3]==0)
yttype = U_M_YT;
else if(sp->YKReserved[3]==1)
{
// 一组电池均充:YX17
tmp = pRtu->YxwValue[1] & 0x0002;
yttype = (tmp)?U_EC_YT:U_VC_YT;
}
else if(sp->YKReserved[3]==2)
{
// 二组电池均充:YX23
tmp = pRtu->YxwValue[1] & 0x0080;
yttype = (tmp)?U_EC_YT:U_VC_YT;
}
tempCd->RecNum = 8;
/* 遥调对象 */ /* 值 */
MakeFrame_YT(buf,pRtu->Addr, yttype, MAKEWORD(sp->YKReserved[7],sp->YKReserved[8]));
}
break;
}
AddDataToList(tempCh, tempCd);
if(type==CMD_YK_SELECT)
pRtu->nYKYTSelect = CMD_YK_SELECT;
else if(type==CMD_YT_SELECT)
pRtu->nYKYTSelect = CMD_YT_SELECT;
else
pRtu->nYKYTSelect = 0;
}
//
int GetYKYTCmdInfoFromHMI(CChannel *tempCh,CSystemPara *sp)
{
int nCommand = NULL_YKYT;
if( (tempCh->nFlagYK != 0xAA) && (tempCh->nFlagYK != 0xCC) )
return nCommand;
switch (sp->YKReserved[0])
{
case 0x11:
nCommand = (tempCh->nFlagYK == 0xAA)?SELECT_YK:SELECT_YT;
break;
case 0x22:
nCommand = (tempCh->nFlagYK == 0xAA)?EXECUTE_YK:EXECUTE_YT;
break;
case 0x33:
nCommand = (tempCh->nFlagYK == 0xAA)?CANCEL_YK:CANCEL_YT;
break;
default:
break;
}
tempCh->nFlagYK = 0;
return nCommand;
}
//
void OnYKYT(CChannel *tempCh,CSystemPara *sp, int type)
{
BYTE RtuNo = (BYTE)tempCh->ykrtuno;
switch(type)
{
case SELECT_YK:
MakeFrame(tempCh,sp,RtuNo,CMD_YK_SELECT);
break;
case EXECUTE_YK:
MakeFrame(tempCh,sp,RtuNo,CMD_YK);
break;
case SELECT_YT:
MakeFrame(tempCh,sp,RtuNo,CMD_YT_SELECT);
break;
case EXECUTE_YT:
MakeFrame(tempCh,sp,RtuNo,CMD_YT);
break;
}
}
//
void GetNextDGRAMType(CChannel *tempCh,RTU *pRtu,BYTE *type)
{
BYTE reply =pRtu->nReply;
if( (reply == NO_REPLY) || (reply == INVALID_REPLY) || (reply == SENDFAIL_REPLY) )
{
*type = CMD_YX;
return;
}
switch(pRtu->nDGRAMTypeLast)
{
case CMD_YC1:
*type = CMD_YC2;
break;
case CMD_YC2:
*type = CMD_YC3;
break;
case CMD_YC3:
*type = CMD_YX;
break;
case CMD_YX:
*type = CMD_YC1;
break;
case CMD_YK:
case CMD_YK_SELECT:
case CMD_YT:
case CMD_YT_SELECT:
case CMD_NULL:
*type = CMD_YX;
break;
default:
break;
}
}
//
void ReleaseMem(CChannel *tempCh)
{
COMDATA *tempCD,*tempCD2;
tempCD = tempCh->DGramLink;
while(tempCD != NULL)
{
tempCD2 = tempCD->next;
delete tempCD;
tempCD = tempCD2;
}
tempCh->DGramLink = NULL;
}
//
void OnNormal(CChannel *tempCh, CSystemPara *sp)
{
BYTE RtuNo;
RTU *pRtu;
BYTE DGramType;
int RtuNum = tempCh->channel.GetRtuNum();
BOOL bSpyChan = (RtuNum == tempCh->GZRtuNum); // TRUE:该通道已被链入故障通道表链,处被探测状态
if(tempCh->DGramLink == NULL)
{// 通道启用后,尚未组报文
for(int i=0;i<RtuNum;i++)
{// RTU协议参数初始化
RtuNo = (BYTE)tempCh->channel.GetRtuNo(i);
pRtu = sp->m_rtus[RtuNo];
pRtu->nReply = NORMAL_REPLY;
pRtu->nDGRAMTypeLast = CMD_NULL;
pRtu->nYKYTSelect = 0;
}
if(bSpyChan)
{// 依次探测不同的RTU
if(tempCh->nNextRtuIndex+1>RtuNum)
tempCh->nNextRtuIndex = 0;
}
else
tempCh->nNextRtuIndex = 0;
tempCh->nWaitRcv = 0;
RtuNo = (BYTE)tempCh->channel.GetRtuNo(tempCh->nNextRtuIndex);
MakeFrame(tempCh,sp,RtuNo,CMD_YX);
tempCh->nNextRtuIndex++;
return;
}
if(tempCh->nNextRtuIndex+1>RtuNum)
tempCh->nNextRtuIndex = 0;
RtuNo = (BYTE)tempCh->channel.GetRtuNo(tempCh->nNextRtuIndex);
pRtu = sp->m_rtus[RtuNo];
if(pRtu->nReply == UNCERTAIN_REPLY)
{// 收操作尚未进行
return;
}
GetNextDGRAMType(tempCh,pRtu,&DGramType);
MakeFrame(tempCh,sp,RtuNo,DGramType);
tempCh->nNextRtuIndex++;
}
//
local
void OnError(CChannel *tempCh,RTU *pRtu,BYTE RtuNo)
{
SetChanGZPara(tempCh,pRtu,RtuNo,CHANJAM);
if(tempCh->GZRtuNum == (BYTE)tempCh->channel.GetRtuNum())
{// 在此通道即将被移出正常通道链表前释放相应的内存
ReleaseMem(tempCh);
tempCh->scflag = ALREADYSEND;
}
}
//
local
void OnYKYTFailure(RTU *pRtu)
{
pRtu->YKEchoFlag = TRUE;
pRtu->YKEcho[1] = 0xFF;
}
//
local
void OnRcvFailure(CChannel *tempCh, CSystemPara *sp, RTU *pRtu, BYTE RtuNo)
{
if( (tempCh->nWaitRcv == CMD_YK_SELECT) || (tempCh->nWaitRcv == CMD_YK) ||
(tempCh->nWaitRcv == CMD_YT_SELECT) || (tempCh->nWaitRcv == CMD_YT) )
OnYKYTFailure(pRtu);
pRtu->nReply = NO_REPLY;
tempCh->nWaitRcv = 0;
tempCh->bShowRcvBuf = SHW_ERROR;
OnError(tempCh,pRtu,RtuNo);
}
//
local
void AfterSend(CChannel *tempCh, CSystemPara *sp, COMDATA *tempCd,BOOL bSuccess)
{
BYTE RtuNo = tempCd->RtuNo;
RTU *pRtu = sp->m_rtus[RtuNo];
BYTE nDGramType = tempCd->SendBuf[1];
if(pRtu->nYKYTSelect)
{// 遥控选择/遥调选择
nDGramType = pRtu->nYKYTSelect;
pRtu->nYKYTSelect = 0;
}
tempCh->bShowSendBuf = (bSuccess)?SHW_NORM:SHW_ERROR;
tempCh->nWaitRcv = bSuccess?nDGramType:0;
tempCh->scflag = ALREADYSEND;
tempCh->nRtuNo = RtuNo;
pRtu->nDGRAMTypeLast = nDGramType;
if(!bSuccess)
{
pRtu->nReply = SENDFAIL_REPLY;
OnError(tempCh,pRtu,RtuNo);
}
else
pRtu->nReply = UNCERTAIN_REPLY;
if(nDGramType==CMD_YT)
{
pRtu->YTValueLow = tempCd->SendBuf[5];
pRtu->YTValueHigh = tempCd->SendBuf[4];
pRtu->YTRegLow = tempCd->SendBuf[3];
}
else if(nDGramType==CMD_YK)
{
pRtu->YkNoHigh = 0;
pRtu->YkNoLow = tempCd->SendBuf[3];
}
}
//
void SendDGram(CChannel *tempCh, CSystemPara *sp)
{
COMDATA *tempCd = NULL;
DWORD num;
if(tempCh->DGramLink!=NULL)
{
if(tempCh->scflag != WAITSEND)
{// 链表里的报文是陈旧的报文
return;
}
tempCd = tempCh->DGramLink;
}
if(tempCd == NULL)
return;
BOOL bSuccess = WriteChan(tempCh,sp,tempCd->SendBuf,tempCd->SendNum,&num);
// OutDGram_DEBUG(tempCd->SendBuf,num,1);
if(!bSuccess)
AfterSend(tempCh,sp,tempCd,FALSE);
else
AfterSend(tempCh,sp,tempCd,TRUE);
}
//
void RcvDGram(CChannel *tempCh, CSystemPara *sp)
{
DWORD num;
BYTE RtuNo = tempCh->nRtuNo;
RTU *pRtu = sp->m_rtus[RtuNo];
BYTE *RcvBuf = tempCh->RcvBuf;
BOOL bSpyChan = SpyChanGram(tempCh,sp,RcvBuf,0,&num);
if( (!bSpyChan) || (num == 0) )
{
OnRcvFailure(tempCh,sp,pRtu,RtuNo);
}
else
{
int nBytesInChan = num;
BOOL bReadSuccess = ReadChan(tempCh,sp,tempCh->RcvBuf,nBytesInChan,&num);
if(bReadSuccess && num != 0)
{
// OutDGram_DEBUG(tempCh->RcvBuf,num,0);
if(!Explain(tempCh,sp,pRtu,num))
OnRcvFailure(tempCh,sp,pRtu,RtuNo);
else
{
tempCh->nWaitRcv = 0;
tempCh->bShowRcvBuf = SHW_NORM;
SetChanGZPara(tempCh,pRtu,RtuNo,CHANNORM);
}
}
else
OnRcvFailure(tempCh,sp,pRtu,RtuNo);
memset(RcvBuf,MAX_RECV_LEN,0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -