📄 processsc1801.cpp
字号:
///////////////////////////////////////////////////////////////////////
// ProcessSC1801.cpp
#include "stdafx.h"
#include "fert2000.h"
#include "process.h"
extern bool bStopFlag;
extern CHANNEL Channels[MAX_CHANNEL_NUM];
extern RTU Rtus[MAX_RTU_NUM];
extern SYSTEMCOUNT SystemCount;
//extern CDatabase Database;
extern BYTE DebugCommand[0x23];//当前调试的命令数组
extern char DebugRtuNo;
extern EVENT Events;
extern RecSendThread RecSendThread1;
extern long ProgramStartTime;
extern NetProcess NetProcess1;
extern char YKEchoFlag[MAX_RTU_NUM];
extern BYTE YKEcho[MAX_RTU_NUM][6];//?
extern BYTE YKReserved[24];//?
extern unsigned char TBCH0[];
extern CFert2000App theApp;
//////////////////////////////////////////////////////////////////////////
//SC1801 protocol
void SC1801(int ChNo)
{
int RecRtuNo = 0;
if (Channels[ChNo].CurSendRtuNo == -1)
{
for (int j=0;j<Channels[ChNo].ChRtuNum;j++)
if (Rtus[Channels[ChNo].ChRtuNo[j]].Flag) break;
if (j<Channels[ChNo].ChRtuNum) Channels[ChNo].CurSendRtuNo = j;
}
else
SC_Send(ChNo);
if(SC_Receive(ChNo,&RecRtuNo))
{
Rtus[RecRtuNo].bWorking = TRUE;
Channels[ChNo].bWorking = true;
SC_Protocol(ChNo,RecRtuNo);
}
//Add by yzw 2000.12.20
else
Rtus[RecRtuNo].bWorking=FALSE;
//Add by yzw 2000.12.20
}
bool SC_Receive(int ChanNo,int *RtuNo)
{
BYTE RecBuf[1024];
char Temp[2048];
int Lenth;
*RtuNo=-1;
int iNum = MoxaBufIqueue(ChanNo);
if (Channels[ChanNo].ChStatus & 0x400)//接受到一桢
{
Lenth=Channels[ChanNo].FileHead[2]* 256 + Channels[ChanNo].FileHead[3];
if (iNum<(Lenth+1))
return false;
for (int k=0;k<4;k++)// RecBuf[k]=Rtus[Channels[ChanNo].ChRtuNo[0]].RecBuf[k];
RecBuf[k]=Channels[ChanNo].FileHead[k];
Channels[ChanNo].ChStatus &= 0xfbff;
}
else
{
BYTE *FileHead = &Channels[ChanNo].FileHead[0];
if (Channels[ChanNo].WorkType == 0)//前置机
{
if (iNum < 5)
return false;
if (iNum >1000)
{
MoxaBufRead(ChanNo,(BYTE*)&Temp[0],2000);
return false;
}
MoxaBufRead(ChanNo,(BYTE*)RecBuf,4);
Lenth = RecBuf[2]*256 + RecBuf[3];
if (Lenth>500)
{
MoxaBufRead (ChanNo,(BYTE *)&Temp[0],2048);
return false;
}
if (iNum<(Lenth+5))
{
Channels[ChanNo].ChStatus |= 0x400;
for (int k=0;k<4;k++)
Channels[ChanNo].FileHead[k]=RecBuf[k];
return false;
}
}
else if (Channels[ChanNo].WorkType == 1)//旁听
{
int j = 0;
if (!(Channels[ChanNo].ChStatus & 0x2000))
{
if (iNum < 5 )
return false;
else if (iNum > 1000)
{
MoxaBufRead(ChanNo,(BYTE*)&Temp[0],2000);
return false;
}
MoxaBufRead(ChanNo,FileHead,2);
j=2;
}
bool Ok = false;
while(j < (iNum-1))//留最后一个;
{
MoxaBufRead(ChanNo,(FileHead + 2),1);
j++;
for (int k=0;k < Channels[ChanNo].ChRtuNum;k++)
{
if (FileHead[0] == Rtus[Channels[ChanNo].ChRtuNo[k]].Addr) break;
}
if ((k < Channels[ChanNo].ChRtuNum) && (FileHead[1] & 0x40) && (FileHead[2] <= 3)
&& ((FileHead[1] & 0x3f) <= 0x1f))//Notes: 未考虑挂葫芦
{
Ok = true;
break;
}
else
{
FileHead[0] = FileHead[1];
FileHead[1] = FileHead[2];
}
}
if (Ok)
{
Channels[ChanNo].ChStatus &= 0xdfff;
MoxaBufRead(ChanNo,(FileHead+3),1);
}else
{
Channels[ChanNo].ChStatus |= 0x2000;
return false;
}
iNum = MoxaBufIqueue(ChanNo);
Lenth = FileHead[2]*256 + FileHead[3];
if (iNum<(Lenth+1))
{
Channels[ChanNo].ChStatus |= 0x400;
return false;
}
for (int k=0;k<4;k++)
RecBuf[k] = FileHead[k];
}
}
Channels[ChanNo].ChStatus &= 0xfbff;
MoxaBufRead(ChanNo,&RecBuf[4],Lenth+1);
MoxaBufRead(ChanNo,(BYTE*)&Temp[0],2048);//清通道 buffer
Rtus[Channels[ChanNo].ChRtuNo[Channels[ChanNo].CurSendRtuNo]].RecFrameSum ++;
BYTE iLpc = 0xff;
for(int i=0;i<Lenth + 4;i++)//LPC校验
iLpc ^= RecBuf[i];
if (iLpc != RecBuf[Lenth + 4])
{
Rtus[Channels[ChanNo].ChRtuNo[Channels[ChanNo].CurSendRtuNo]].ErrFrameSum ++;
return false;
}
for (int j = 0;j < Channels[ChanNo].ChRtuNum;j++)
{
BYTE RtuAddr = Rtus[Channels[ChanNo].ChRtuNo[j]].Addr;
if (RecBuf[0] == RtuAddr)
{
*RtuNo = Channels[ChanNo].ChRtuNo[j];
break;
}
}
if (*RtuNo==-1)
return false;
for ( i = 0;i <5+Lenth;i++)
Rtus[*RtuNo].RecBuf[i] = RecBuf[i];
Rtus[*RtuNo].RecLen = Lenth+5;
Rtus[*RtuNo].bReceiveCanDisp = TRUE;
return true;
}
void SC_Protocol(int ChNo,int RtuNo)
{
BYTE* RtuRecBuf=&(Rtus[RtuNo].RecBuf[0]);
WORD ByteLen=RtuRecBuf[3]+RtuRecBuf[2]*256;
int i;
bool bSaveFrame = true;
//int YxNo;
BYTE BrandNo;
WORD KwhNum=0,YcNum=0,YxNum=0;
// Rtus[RtuNo].CommandSendFlag[RtuRecBuf[1] & 0x3f]=0;
switch (RtuRecBuf[1]&0x3f)
{
case 0x0://NAK
SC_RtuState(RtuRecBuf[4],RtuNo);
break;
case 0x1://RRC 配置
SC_RtuState(RtuRecBuf[4],RtuNo);
for (i=0;i<16;i++) Rtus[RtuNo].RRC[i]=RtuRecBuf[i+5];
for (i=0;i<16;i++)
{
switch(RtuRecBuf[i+5])
{
case 0x32:
YcNum +=12;
break;
case 0x11:
YxNum +=24;
break;
case 0x3b:
KwhNum +=8;
}
}
Rtus[RtuNo].YxwNum = (Rtus[RtuNo].YxNum+15)/16;
Rtus[RtuNo].KwhNum=KwhNum;
Rtus[RtuNo].YcNum=YcNum;
Rtus[RtuNo].YxNum=YxNum;
break;
case 0x2://DRF 全数据
SC_RtuState(RtuRecBuf[4],RtuNo);
if ((RtuRecBuf[5] & 0xc0) == 0x40)//yc
{
BYTE *RtuRecBufYx;
BYTE State=0;
WORD YcNum=Rtus[RtuNo].YcNum;
for (i=0;i<YcNum;i++)
{
Rtus[RtuNo].YcValue[i]=(float)RtuRecBuf[5+i*2+1] + (RtuRecBuf[5+i*2] &0xf)*256;
}
RtuRecBufYx=&RtuRecBuf[5+YcNum*2];
for (i=0;i<Rtus[RtuNo].YxNum;i++)
{
State = (RtuRecBufYx[(int)i/6] & (1<<i%6))?1:0;
if(Rtus[RtuNo].YxValue[i] != State)
{
Rtus[RtuNo].YxValue[i] = State;
if (Rtus[RtuNo].RecFullYx == 1) YxEvent(RtuNo,i,State);
}
}
}else if ((RtuRecBuf[5] & 0xc0) == 0x80)//yx
{
BYTE *RtuRecBufYc;
BYTE State=0;
WORD YxNum=Rtus[RtuNo].YxNum;
for (i=0;i<YxNum;i++)
{
State = (RtuRecBuf[5+(int)i/6] & (1<<i%6))?1:0;
if (Rtus[RtuNo].YxValue[i] != State)
{
Rtus[RtuNo].YxValue[i] = State;
if (Rtus[RtuNo].RecFullYx == 1) YxEvent(RtuNo,i,State);
}
}
RtuRecBufYc=&RtuRecBuf[5+YxNum/6];
for (i=0;i<Rtus[RtuNo].YcNum;i++)
{
Rtus[RtuNo].YcValue[i]=(float)RtuRecBufYc[i*2+1] + (RtuRecBufYc[i*2] &0xf)*256;
}
}else break;
Rtus[RtuNo].RecFullYx = 1;
break;
case 0x03://XRF 异常数据
int No;
SC_RtuState(RtuRecBuf[4],RtuNo);
for (i=0;i<ByteLen-1;i+=3)
{
if (RtuRecBuf[5+i+1] & 0x40)//yc
{
BrandNo=RtuRecBuf[5+i]>>4;
No=0;
if (Rtus[RtuNo].RRC[BrandNo] != 0x32) continue;
for (int j=0;j<BrandNo;j++) //由槽号取点号
if (Rtus[RtuNo].RRC[j]==0x32) No +=12;
No=No + (RtuRecBuf[5+i] & 0xf);
Rtus[RtuNo].YcValue[No]=(float)RtuRecBuf[5+i+2] + (RtuRecBuf[5+i+1] & 0xf)*256;
}else if(RtuRecBuf[5+i+1] & 0x80)
{
BrandNo=RtuRecBuf[5+i] & 0xf;
No=0;
if (Rtus[RtuNo].RRC[BrandNo] != 0x11) continue;
for (int j=0;j<BrandNo;j++)
if (Rtus[RtuNo].RRC[j]==0x11) No +=24;
No=No + ((RtuRecBuf[5+i]>>4) & 0x3)*6;
for (j=0;j<6;j++)
{
if (RtuRecBuf[5+i+2] & (1<<j))
{
if (Rtus[RtuNo].YxValue[No+j] == ((RtuRecBuf[5+i+1] & (1<<j)) ? 1:0)) continue;
Rtus[RtuNo].YxValue[No+j]=(RtuRecBuf[5+i+1] & (1<<j)) ?1 :0;
if (Rtus[RtuNo].RecFullYx == 1)
YxEvent(RtuNo,No+j,Rtus[RtuNo].YxValue[No+j]);//生成变位遥信Event
}
}
}
}
if (Rtus[RtuNo].RecFullYx == 0) //如果全数据未收到
{
Rtus[RtuNo].CommandSendFlag [0x01] = true;
Rtus[RtuNo].CommandSendFlag [0x02] = true;
}
break;
case 0x04://SOE
SC_RtuState(RtuRecBuf[4],RtuNo);
SC_SOE_Event(&RtuRecBuf[5],ByteLen-1,RtuNo);
break;
case 0x05://脉冲累加值
SC_RtuState(RtuRecBuf[4],RtuNo);
ByteLen--;
for (i=0;i<ByteLen;i +=2)
{
Rtus[RtuNo].KwhValue[i/2] = RtuRecBuf[5+i]*256 + RtuRecBuf[5+i+1];
}
Rtus[RtuNo].CommandSendFlag[0x08] = true;
break;
case 0x06://PAZ 脉冲清零
case 0x09://SDB 死区值
case 0x19://SST 对钟
case 0x1a://报告时钟
case 0x1c://SIM 设置接口
SC_RtuState(RtuRecBuf[4],RtuNo);
break;
// case 0x07://PAF
// case 0x08://PAT
// SC_MakeFrame(RtuNo,0x05);//报告脉冲值
// Rtus[RtuNo].CommandSendFlag[0x05]=true;
// break;
case 0x0a://报死区值
SC_RtuState(RtuRecBuf[4],RtuNo);
//add dispose deadarea
break;
case 0x0d://COA//遥控预制
//SC_MakeFrame(RtuNo,0x11);
//YxNo=0;
BYTE Temp;
Temp=~RtuRecBuf[6];
// Temp += 1;
BrandNo=Temp>>4;
if (RtuNo==*((WORD*)(YKReserved+1)))
{
BYTE YkNo = (YKReserved[7] == 0x33)?YKReserved[3]:YKReserved[4];
BYTE ReturnYkNo = 0;
for(i=0;i<BrandNo;i++)
if(Rtus[RtuNo].RRC[i]==0x05) ReturnYkNo +=16;
ReturnYkNo = ReturnYkNo + (Temp & 0xf);
if (ReturnYkNo == YkNo)
YKEcho[RtuNo][1] = YKReserved[7];
else YKEcho[RtuNo][1] = 0xff;
YKEchoFlag[RtuNo]=1;
}
break;
case 0x08://PAT
case 0x0e://COD 直接输出控制
case 0x11://COE 执行输出
case 0x15://COL 控制输出锁存
break;
case 0x18://DRL 锁存数据报告
SC_RtuState(RtuRecBuf[4],RtuNo);
//add dispose lock
break;
case 0x1b://RIM 报告接口
SC_RtuState(RtuRecBuf[4],RtuNo);
//add dispose port
break;
default:
break;
}
if((Rtus[RtuNo].CurSendFrameType &0x3f) == (RtuRecBuf[1] &0x3f)) Rtus[RtuNo].CurSendFrameType=0;
if (RtuNo == Channels[ChNo].ChRtuNo[Channels[ChNo].CurSendRtuNo]) Channels[ChNo].CurSendRtuNo++;
}
void SC_RtuState(BYTE RtuStateByte,int RtuNo)
{
Rtus[RtuNo].RTUStatus=RtuStateByte & 0x7f;
if (RtuStateByte & 0x01)//RTU Reset
{
// SC_MakeFrame(RtuNo,1);//配置
if (Rtus[RtuNo].CurSendFrameType!=1) Rtus[RtuNo].CommandSendFlag[1]=true;
// SC_MakeFrame(RtuNo,0x09);//SDB 死区
Rtus[RtuNo].CommandSendFlag[0x09]=true;
Rtus[RtuNo].CommandSendFlag[2]=true;
Rtus[RtuNo].CommandSendFlag[3]=true;
// Rtus[RtuNo].CommandSendFlag[4]=true;
Rtus[RtuNo].CommandSendFlag[5]=true;
// Rtus[RtuNo].CommandSendFlag[6]=true;
Rtus[RtuNo].CommandSendFlag[0x19]=true;
}
if (RtuStateByte & 0x02)
{
//SC_MakeFrame(RtuNo,0x19);//时钟
Rtus[RtuNo].CommandSendFlag[0x19]=true;
//SC_MakeFrame(RtuNo,0x02);//全数据
Rtus[RtuNo].CommandSendFlag[0x02]=true;
}
if (RtuStateByte & 0x1c) Rtus[RtuNo].CommandSendFlag[0x04]=true; //SC_MakeFrame(RtuNo,0x04);//SOE
if (RtuStateByte & 0x20) Rtus[RtuNo].CommandSendFlag[0x05]=true;//SC_MakeFrame(RtuNo,0x05);//报告脉冲值
if (RtuStateByte & 0x40) Rtus[RtuNo].CommandSendFlag[0x1e]=true; //SC_MakeFrame(RtuNo,0x1e);//复位
if (RtuStateByte == 0) Rtus[RtuNo].CommandSendFlag [0x03] = true;
}
void SC_Send(int ChNo)
{
static int TimeFlag=0;
static BYTE SendSort[25]={0x1e,0x11,0x0e,0x0d,0x04,0x01,0x09,0x19,0x02,0x06,0x15,0x0a,0x07,
0x18,0x1a,0x1c,0x1b,0x08,0x05,0x03,0,0,0,0,0};//modify by feng 99.11.1 22:28 0x05
int i;
BYTE *CurChanRtuNo=&Channels[ChNo].ChRtuNo[0];
if (Channels[ChNo].ChStatus & 0x100)
{
if(YKReserved[0] == 0x11) Rtus[YKReserved[1]].CommandSendFlag[0x0d]=true;
else if(YKReserved[0] == 0x22) Rtus[YKReserved[1]].CommandSendFlag[0x11] = true;
Channels[ChNo].ChStatus &= 0xfeff;
}
if (Channels[ChNo].ReviseTimeFlag & 0x08) //脉冲值清零
{
for (i=0;i<Channels[ChNo].ChRtuNum;i++) Rtus[CurChanRtuNo[i]].CommandSendFlag[0x06]=true;//SC_MakeFrame(Channels[ChNo].ChRtuNo[i],0x06);
Channels[ChNo].ReviseTimeFlag &= 0xf7;
}
if (Channels[ChNo].ReviseTimeFlag & 0x01)//异常数据
{
Channels[ChNo].ReviseTimeFlag &= 0xfe;
for (i=0;i<Channels[ChNo].ChRtuNum;i++) Rtus[CurChanRtuNo[i]].CommandSendFlag[0x03]=true; //SC_MakeFrame(Channels[ChNo].ChRtuNo[i],0x02);
if (Channels[ChNo].ReviseTimeFlag &0x02) //全数据
{
for (i=0;i<Channels[ChNo].ChRtuNum;i++)
{
Rtus[CurChanRtuNo[i]].CommandSendFlag[0x01]=true;
Rtus[CurChanRtuNo[i]].CommandSendFlag[0x02]=true;
}
Channels[ChNo].ReviseTimeFlag &= 0xfd;
}
if (Channels[ChNo].ReviseTimeFlag & 0x04)//对时
{
for (i=0;i<Channels[ChNo].ChRtuNum; i++)
{
Rtus[CurChanRtuNo[i]].CommandSendFlag[0x19]=true;
Rtus[CurChanRtuNo[i]].CommandSendFlag[0x09]=true;
Rtus[CurChanRtuNo[i]].CommandSendFlag[0x07]=true;
}
Channels[ChNo].ReviseTimeFlag &= 0xfb;
}
}
Channels[ChNo].CurSendRtuNo = Channels[ChNo].CurSendRtuNo % Channels[ChNo].ChRtuNum;
int RtuNo = Channels[ChNo].ChRtuNo[Channels[ChNo].CurSendRtuNo];
if (!Rtus[RtuNo].Flag)
{
int j = Channels[ChNo].CurSendRtuNo;
int RtuNum = Channels[ChNo].ChRtuNum;
for (int l=0;l<Channels[ChNo].ChRtuNum;l++)
if(Rtus[Channels[ChNo].ChRtuNo[++j%RtuNum]].Flag) break;
if (l>=Channels[ChNo].ChRtuNum)
{
Channels[ChNo].CurSendRtuNo = -1;
return;
}else Channels[ChNo].CurSendRtuNo = j % RtuNum;
}
RtuNo = Channels[ChNo].ChRtuNo[Channels[ChNo].CurSendRtuNo];
if (!Rtus[RtuNo].CurSendFrameType)
{
int m = 0,SendCommandNo = 0;
if(RtuNo != DebugRtuNo)
{
for (m=0;m<20;m++) if (Rtus[RtuNo].CommandSendFlag[SendSort[m]]) break;
if (m<20) SendCommandNo = SendSort[m];
}
else if (DebugCommand[0x20])//进行调试
{
for (m=0;m<20;m++) if (DebugCommand[SendSort[m]]) break;
if (m<20) SendCommandNo = SendSort[m];
DebugCommand[SendCommandNo] = 0;
}else
{
if(DebugCommand[0x21]<DebugCommand[0x22])
SendCommandNo = DebugCommand[DebugCommand[0x21]];
else m=20;
DebugCommand[0x21]++;
}
if (m<20)
{
SC_MakeFrame(RtuNo,ChNo,SendCommandNo);
Rtus[RtuNo].IsWait = true;
Rtus[RtuNo].CommandSendFlag[SendCommandNo]=false;
}else Channels[ChNo].CurSendRtuNo++;
}
else
{
if (!Rtus[RtuNo].IsWait)
{
SC_MakeFrame(RtuNo,ChNo,Rtus[RtuNo].CurSendFrameType);
Rtus[RtuNo].IsWait = true;
}else if (Rtus[RtuNo].ReSendTimeFlag >Rtus[RtuNo].AnswerWaitTime)//Wait AnswerWaitTime Seconds ReSend
{
if (Rtus[RtuNo].CurSendFrameType & 0x80)
Rtus[RtuNo].CurSendFrameType=0;
else Rtus[RtuNo].IsWait = false;
Channels[ChNo].CurSendRtuNo = ++Channels[ChNo].CurSendRtuNo%Channels[ChNo].ChRtuNum;
}
}
char temp[2048];
if (Rtus[RtuNo].TXBufPtr)
{
if (Channels[Rtus[RtuNo].RtuChNo].WorkType == 1)
{
Rtus[RtuNo].TXBufPtr = 0;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -