📄 processcdt91rec.cpp
字号:
#include "stdafx.h"
#include "fert2000.h"
#include "process.h"
#include "math.h"
#include "fert2000Dlg.h"
extern bool bStopFlag;
extern RecSendThread RecSendThread1;
extern CFert2000App theApp;
extern CFert2000Dlg *MainDlg;
extern ADDR *Addr;
extern unsigned char TBCH0[];
extern ADDR *Addr;
extern BYTE bSynWord[6];
//////////////////////////////////////////////
void CDT91_RECEIVE(int i,int iRtuNo)
{
if (CDT91_Rec(i,iRtuNo))
{
CDT91_Protocol(i,iRtuNo);
}
CDT91_Send(i,iRtuNo);
}
bool CDT91_Rec(int i,int iRtuNo)
{
int iStatus=3;
BYTE Temp;
DWORD num=0;
CHANPARA *chanpara = Addr->ChanPara_addr + i;
//read data
BYTE RecBuf[1024];
if (chanpara->Start < 0 || chanpara->Start >= 1024) chanpara->Start = 0;
if (chanpara->End < 0 || chanpara->End >= 1024) chanpara->End = 0;
if (((chanpara->Start - chanpara->End + 1024 -1)%1024) == 0)
chanpara->Start = chanpara->End;
int iRet = ChanBufRead(i,RecBuf,(chanpara->Start - chanpara->End + 1024 - 1)%1024);
Sleep(10);
BYTE * ChanRecBuf = &chanpara->RecBuffer[0];
WORD ChanEnd = chanpara->End;
for (int j=0;j<iRet;j++)
{
ChanRecBuf[ChanEnd++] = RecBuf[j];
if (ChanEnd >= 1024) ChanEnd = 0;
}
chanpara->End = ChanEnd;
///////////////////////////
int SynstrCount = chanpara->SynstrCount;
int InLen = ChanBufIqueue(i);
if (InLen<6) return false;
if ((SynstrCount<6) && !(chanpara->ChStatus & 0x2000))//同步字个数小于6,并且不是第一个信息字
{
for (int j=0;j<InLen;j++)
{
ChanBufDataGet(i,&Temp,1);
if(Temp == bSynWord[SynstrCount])
SynstrCount++;
else
SynstrCount = 0;
if (SynstrCount==6)
{
DispBufData(i,255,1,bSynWord,6,iStatus);
break;
}
}
chanpara->SynstrCount = SynstrCount;
return false;
}
InLen=ChanBufIqueue(i);
if (SynstrCount==6)
{
if (InLen<6)
return false;
ChanBufDataGet(i,chanpara->FileHead ,6);
BYTE *buf = chanpara->FileHead ;
if (buf[0]==bSynWord[0] && buf[1]==bSynWord[1] && buf[2] == bSynWord[2] &&
buf[3]==bSynWord[3] && buf[4]==bSynWord[4] && buf[5] == bSynWord[5])//the second synword
{
chanpara->SynstrCount = 6;
// DispBufData(i,255,1,bSynWord,6,iStatus);
return false;
}
else if (chanpara->FileHead[5] != CDT_CheckCRC(chanpara->FileHead))
{
chanpara->SynstrCount = 0;
return false;
}
chanpara->SynstrCount = 0;
InLen -= 6;
chanpara->ChStatus |= 0x2000;
}
if (chanpara->ChStatus & 0x2000)
{
int Lenth = chanpara->FileHead[2] * 6;
if (InLen < Lenth && Lenth != 0)
return false;
else
{
for (int j = 0;j < 6;j++)
chanpara->ProcBuffer[j] = chanpara->FileHead [j];
ChanBufDataGet(i,&chanpara->ProcBuffer[6],Lenth);
chanpara->SynstrCount = 0;
chanpara->ChStatus &= 0xdfff;
DispBufData(i,255,1,chanpara->ProcBuffer,6+Lenth,iStatus);
}
}
else
return false;
return true;
}
void CDT91_Protocol(int i,int iRtuNo)
{
int NonceInfoWord = 0;
CHANPARA *chanpara = Addr->ChanPara_addr + i;
RTUPARA *rtupara = GetRtuParaPt(Addr,iRtuNo);
if (!rtupara) return;
BYTE* RecBuf=&(chanpara->ProcBuffer[0]);
int iLen = RecBuf[2] * 6;
for (NonceInfoWord=6;NonceInfoWord < iLen+6;NonceInfoWord +=6)//以信息字为单位,一个一个处理
{
int InfoCode=RecBuf[NonceInfoWord];//功能码
if (CDT_CheckCRC(&RecBuf[NonceInfoWord])!=RecBuf[NonceInfoWord+5])//校验不对
continue;
if ((InfoCode>=0)&&(InfoCode<=0x7f))//遥测,功能码在遥测定义起始码和7F之间
{
for (int j=0;j<2;j++)
{
WORD YcValue;
YcValue = RecBuf[NonceInfoWord+j*2+1] + RecBuf[NonceInfoWord+j*2+2]*256;
WORD YcSign = 0x800;//遥测符号位:11
if ((YcValue & 0x8000) || (YcValue & 0x4000)) continue;//遥测溢出或者无效
if (YcValue & YcSign)//遥测为负数
{
YcValue &= 0x7ff;
YcValue = 0x7ff + 1 - YcValue;
rtupara->YcValue[InfoCode*2+j]=-YcValue;
}
else
{
YcValue = YcValue & 0x7ff;
rtupara->YcValue[InfoCode*2+j]=YcValue;
}
}
}
else if ((InfoCode>=0xf0) && (InfoCode<=0xff))//遥信
{
// int iPosition = InfoCode - 0xf0;//第几组谣信已收到
int YxDWordPtr = InfoCode-0xf0;
int YxValuePtr=YxDWordPtr*32;
DWORD YxWord=*(DWORD*)&RecBuf[NonceInfoWord+1];
BYTE State=0;
for (int k=0;k<32;k++)
{
State = (YxWord & (1<<k)) ? 1 : 0;
if (rtupara->YxValue[YxValuePtr+k] != State)
rtupara->YxValue[YxValuePtr+k] = State;
}
}
else if(InfoCode>=0xa0 && InfoCode<=0xdf)//电能KWH
{
if (!(RecBuf[NonceInfoWord+4] & 0x80))//有效
{
DWORD KWHValue = 0;
if ((RecBuf[NonceInfoWord+4] & 0x20) == 0)//二进制
{
KWHValue = RecBuf[NonceInfoWord+1] + RecBuf[NonceInfoWord+2] * 256
+ RecBuf[NonceInfoWord+3] * 256 * 256;
}
else//bcd 字节内用BCD,字节间用二进制
{
BYTE *t = &RecBuf[NonceInfoWord+1];
KWHValue = ((t[2] & 0xf0)/16*10 + t[2] & 0x0f)*256*256
+ ((t[1] & 0xf0)/16*10 + t[1] & 0x0f)*256 + ((t[0] & 0xf0)/16*10 + t[0] & 0x0f);
}
rtupara->KwhValue[InfoCode-0xa0]=KWHValue;
}
}
else if ((InfoCode>=0x8d) && (InfoCode<=0x92))//水位
{
float WaterValue;
WaterValue =(float)((RecBuf[NonceInfoWord+1] & 0xf)/100.0);
WaterValue +=(float)((RecBuf[NonceInfoWord+1]>>4)/10.0);
WaterValue +=(float)(RecBuf[NonceInfoWord+2] & 0xf);
WaterValue +=(float)((RecBuf[NonceInfoWord+2]>>4)*10.0);
WaterValue +=(float)((RecBuf[NonceInfoWord+3] & 0xf)*100.0);
WaterValue +=(float)((RecBuf[NonceInfoWord+3]>>4)*1000.0);
rtupara->Water[InfoCode-0x8d]=WaterValue;
}
else if ((InfoCode>=0x86) && (InfoCode<=0x89))//总加遥测
{
}
else if (InfoCode==0x8a)//频率
{
float Freq;
for (int k=0;k<2;k++)
{
Freq =0;
Freq =(float)((RecBuf[NonceInfoWord+k*2+1] & 0xf)/100.0);
Freq +=(float)((RecBuf[NonceInfoWord+k*2+1]>>4)/10.0);
Freq +=(float)(RecBuf[NonceInfoWord+k*2+2] & 0xf);
Freq +=(float)((RecBuf[NonceInfoWord+k*2+2]>>4)*10.0);
rtupara->Freq[k] = Freq;
}
}
else
CDT91Rec_Answer(i,iRtuNo,NonceInfoWord);//SOE 子站时钟返送 子站状态信息,遥控返校 升降返校
}
if (RecBuf[0] == 0x71 && RecBuf[1] == 0xf4)//收到遥信报文
{
if (rtupara->RecFullYx == 255)
rtupara->RecFullYx = 0;
else if (rtupara->RecFullYx == 0)
rtupara->RecFullYx = 1;
}
}
void CDT91_Send(int i,int iRtuNo)
{
int iStatus=2;
int Sendlen=0;
STATION *station = Addr->Station_addr;
CHANPARA *chanpara = Addr->ChanPara_addr + i;
RTUPARA *rtupara = GetRtuParaPt(Addr,iRtuNo);
if (!rtupara) return;
BYTE *SendBuf = & chanpara->SendBuffer[0];
//遥控,升降执行.预制.撤消命令
if(rtupara->CommandSendFlag[8]==true || rtupara->CommandSendFlag[9]==true)
{
for (int l=0;l<6;l++) SendBuf[l] = bSynWord[l];
Sendlen=6;
if (rtupara->CommandSendFlag[8] == true)
{
rtupara->CommandSendFlag[8] = false;
if (rtupara->SetCommand[1] != YK) return;
}
else
{
rtupara->CommandSendFlag[9] = false;
if (rtupara->SetCommand[1] != YT) return;
}
SendBuf[6] = 0x71;//控制字节
SendBuf[8]=3;
SendBuf[9]=0x01;
SendBuf[10]=rtupara->rtuaddr;//目的站址
switch(rtupara->SetCommand[2])
{
case 0x11:
SendBuf[7] = 0x61;//帧类别遥控选择
SendBuf[12] = 0xe0;//信息字功能码
SendBuf[13] = rtupara->SetCommand[4];//遥控操作码
break;
case 0x22:
SendBuf[7] = 0xc2;//执行
SendBuf[12] = 0xe2;
SendBuf[13] = 0xaa;
rtupara->SetCommand[1] = 255;
break;
case 0x33:
SendBuf[7] = 0xb3;//撤消
SendBuf[12] = 0xe3;
SendBuf[13] = 0x55;
rtupara->SetCommand[1] = 255;
break;
}
SendBuf[11] = CDT_CheckCRC(&SendBuf[6]);
SendBuf[14] = rtupara->SetCommand[6];//遥控对象号
SendBuf[15] = SendBuf[13];//重复
SendBuf[16] = SendBuf[14];
SendBuf[17] = CDT_CheckCRC(&SendBuf[12]);
for(int k=0;k<12;k++) SendBuf[18+k]=SendBuf[12+k%6];//三个信息字相同
Sendlen+=24;
ChanBufWrite(i,SendBuf,Sendlen);
DispBufData(i,iRtuNo,0,SendBuf,Sendlen,iStatus);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -