📄 protocolcdt91.cpp
字号:
// ProtocolCDT91.cpp: implementation of the CProtocolCDT91 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RTUSim.h"
#include "ProtocolCDT91.h"
#include "ProtocalBase.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern BOOL OnOff;
BYTE bch_table[256] = {
0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,
0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D,
0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,
0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D,
0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,
0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,
0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,
0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD,
0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,
0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,
0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,
0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A,
0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32,
0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,
0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,
0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,
0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C,
0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4,
0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,
0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,
0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,
0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,
0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,
0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34,
0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,
0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,
0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,
0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13,
0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,
0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83,
0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,
0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3
};
CProtocolCDT91::CProtocolCDT91()
{
m_KgState=FALSE;
m_SendNo=0;
m_bFlag=FALSE;
}
CProtocolCDT91::~CProtocolCDT91()
{
}
void CProtocolCDT91::Explain()
{
//查看有无SOE、校时信息,无则发送全数据
while(m_baInBuffer.GetSize()>10)
{
if(m_baInBuffer[0] == 0xeb && m_baInBuffer[1] == 0x90&&m_baInBuffer[2] == 0xeb && m_baInBuffer[3] == 0x90&&m_baInBuffer[4] == 0xeb && m_baInBuffer[5] == 0x90)
{
if(m_baInBuffer[6] == 0x71 && m_baInBuffer[10] == (BYTE)m_wAddr)
{
switch(m_baInBuffer[7])
{
case 0x7a://校时
timeSynch();
m_baInBuffer.RemoveAll();
break;
case 0x61://遥控选择
PreOperate();
m_baInBuffer.RemoveAll();
break;
case 0xc2://遥控执行
Oper();
m_baInBuffer.RemoveAll();
break;
case 0xb3://遥控撤销
CancelOper();
m_baInBuffer.RemoveAll();
break;
case 0x3d://复归命令
break;
default:
break;
}
}
}
else
{
if(m_baInBuffer.GetSize() > 1)
m_baInBuffer.RemoveAt(0,1);
}
}
//判断是否有遥信变位
if(m_baDigital.GetSize() <= 0)
return;
if(m_KgState != (BYTE)(m_baDigital[0]&0x01))
{
m_KgState=m_baDigital[0]&0x01;
SOE((BYTE)m_wAddr);
SendRespons();
Sleep(100);
}
m_baOutBuffer.RemoveAll();
DataSend((BYTE)m_wAddr);
}
//CRC解调
BOOL CProtocolCDT91::check_revcode(BYTE *array)
{
BYTE temp;
temp = 0x00 ;
for( int i = 0 ;i < 5; i++ )
{
temp = temp ^ array[i] ;
temp = bch_table[ temp];
}
temp = temp^0xff ;
if( temp == array[5] )
return TRUE ;
else
return FALSE;
}
//CRC调制
BOOL CProtocolCDT91::check_sendcode(int bufno)
{
BYTE temp;
temp = 0x00 ;
for( int m = 0 ;m < 5; m++ )
{
temp = temp ^ m_baOutBuffer[bufno+m] ;
temp = bch_table[temp];
}
temp = temp^0xff ;
//m_baOutBuffer[bufno+5]=(char)temp;
m_baOutBuffer.Add(temp);
return TRUE;
}
//更新计算机时间
void CProtocolCDT91::timeSynch()
{
BYTE array[6];
if(m_baInBuffer.GetSize() < 18)
return;
for(int i=0;i<3;i++)
{
for(int j=0;j<6;j++)
{
array[j]=m_baInBuffer[i*6+j+6];
}
if(!check_revcode(array))
return;
}
SYSTEMTIME tm;
GetLocalTime(&tm);
LPSYSTEMTIME lpSystemTime =&tm;
lpSystemTime->wMonth=(WORD)m_baInBuffer[21];
lpSystemTime->wDay=(WORD)m_baInBuffer[20];
lpSystemTime->wHour=(WORD)m_baInBuffer[19];
lpSystemTime->wMinute=(WORD)m_baInBuffer[16];
lpSystemTime->wSecond=(WORD)m_baInBuffer[15];
lpSystemTime->wMilliseconds=(WORD)m_baInBuffer[13];
//更新计算机时间
SetLocalTime(lpSystemTime);
}
//遥控返校
BOOL CProtocolCDT91::OperBack(BYTE rtuAddress,BOOL state)
{
Data_ArrayS();
Data_ArrayC(rtuAddress,0x7a,2);
for(int i=0;i<3;i++)
{
m_baOutBuffer.Add(0xe1);
if(!state)
m_baOutBuffer.Add(0xff);
else
m_baOutBuffer.Add(m_baInBuffer[13+i*6]);
m_baOutBuffer.Add(m_baInBuffer[14+i*6]);
if(!state)
m_baOutBuffer.Add(0xff);
else
m_baOutBuffer.Add(m_baInBuffer[15+i*6]);
m_baOutBuffer.Add(m_baInBuffer[16+i*6]);
check_sendcode(12+6*i);
}
SendRespons();
return TRUE;
}
//置开关位置
BOOL CProtocolCDT91::Oper()
{
BYTE array[6];
if(!m_bFlag)
return FALSE;
m_bFlag=!m_bFlag;
if(m_baInBuffer.GetSize() < 30)
{
TRACE("遥控执行字节长度:%d\n",m_baInBuffer.GetSize());
return FALSE;
}
for(int i=0;i<4;i++)
{
for(int j=0;j<6;j++)
{
array[j]=m_baInBuffer[i*6+j+6];
}
if(!check_revcode(array))
return FALSE;
}
if(m_baInBuffer[10] != m_wAddr)
return FALSE;
m_KgState=!m_KgState;
OnOff=m_KgState;//通知界面
return TRUE;
}
//置SOE
BOOL CProtocolCDT91::SOE(BYTE rtuAddress)
{
int nCount=0;
SYSTEMTIME tm;
GetLocalTime(&tm);
LPSYSTEMTIME lpSystemTime =&tm;
Data_ArrayS();
Data_ArrayC(rtuAddress,0x26,5);
for(int i=0;i<6;i+=2)
{
nCount=12+i*6;
m_baOutBuffer.Add(0x80);
m_baOutBuffer.Add((BYTE)lpSystemTime->wMilliseconds);
m_baOutBuffer.Add((BYTE)lpSystemTime->wMilliseconds>>8);
m_baOutBuffer.Add((BYTE)lpSystemTime->wSecond);
m_baOutBuffer.Add((BYTE)lpSystemTime->wMinute);
check_sendcode(nCount);
m_baOutBuffer.Add(0x81);
m_baOutBuffer.Add((BYTE)lpSystemTime->wHour);
m_baOutBuffer.Add((BYTE)lpSystemTime->wDay);
m_baOutBuffer.Add(0x01);
m_baOutBuffer.Add(m_KgState<<7);
check_sendcode(nCount+6);
}
return TRUE;
}
//置信息字
void CProtocolCDT91::Data_ArrayS()
{
for(int i=0;i<6;i=i+2)
{
m_baOutBuffer.Add(0xeb);
m_baOutBuffer.Add(0x90);
}
}
//置控制字
void CProtocolCDT91::Data_ArrayC(BYTE rtuAddress,BYTE ctrl,BYTE infoNum)
{
m_baOutBuffer.Add(0x71);
m_baOutBuffer.Add(ctrl);
m_baOutBuffer.Add(infoNum+1);
m_baOutBuffer.Add(rtuAddress); //源地址
m_baOutBuffer.Add(0x00); //目标地址
check_sendcode(6); //校验码
}
void CProtocolCDT91::DataSend(BYTE rtuAddr)
{
Data_ArrayS();
switch(m_SendNo)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 6:
case 8:
if(m_waAnalog.GetSize()%2 == 0)
Data_ArrayC(rtuAddr,0x61,m_waAnalog.GetSize()/2-1);
else
Data_ArrayC(rtuAddr,0x61,m_waAnalog.GetSize()/2);
SendYc();
break;
case 5:
case 9:
if(m_baDigital.GetSize()%4 == 0)
Data_ArrayC(rtuAddr,0xf4,m_baDigital.GetSize()/4-1);
else
Data_ArrayC(rtuAddr,0xf4,m_baDigital.GetSize()/4);
SendYx();
break;
case 7:
Data_ArrayC(rtuAddr,0x85,m_dwaCount.GetSize()-1);
SendDd();
break;
default:
break;
}
m_SendNo++;
if(m_SendNo > 9)
m_SendNo=0;
SendRespons();
}
void CProtocolCDT91::SendYx()
{
int digLen=m_baDigital.GetSize();
if(digLen < 0 )
return;
int yushu=digLen%4; //取余数
int shang=digLen/4; //商
BYTE funcode=0xf0;
if(yushu != 0)
shang +=1;
for(int i=0;i<shang;i++)
{
m_baOutBuffer.Add(funcode);
if(shang-i != 1)
{
m_baOutBuffer.Add(m_baDigital[i*4]);
m_baOutBuffer.Add(m_baDigital[i*4+1]);
m_baOutBuffer.Add(m_baDigital[i*4+2]);
m_baOutBuffer.Add(m_baDigital[i*4+3]);
}
else
{
for(int j=0;j<yushu;j++)
{
m_baOutBuffer.Add(m_baDigital[i*4+j]);
}
for(int m=0;m<4-j;m++)
{
m_baOutBuffer.Add(0x00);
}
}
check_sendcode(i*6+12);
funcode++;
if(funcode > 0xfe)
break;
}
}
void CProtocolCDT91::SendYc()
{
int anaLen=m_waAnalog.GetSize();
if(anaLen < 0 )
return;
int yushu=anaLen%2; //取余数
int shang=anaLen/2; //商
BYTE funcode=0x00;
if(yushu != 0)
shang +=1;
for(int i=0;i<shang;i++)
{
m_baOutBuffer.Add(funcode);
if(shang-i != 1)
{
m_baOutBuffer.Add((BYTE)m_waAnalog[i*2]);
m_baOutBuffer.Add((BYTE)(m_waAnalog[i*2]>>8));
m_baOutBuffer.Add((BYTE)m_waAnalog[i*2+1]);
m_baOutBuffer.Add((BYTE)(m_waAnalog[i*2+1]>>8));
}
else
{
for(int j=0;j<1;j++)
{
m_baOutBuffer.Add((BYTE)m_waAnalog[i*2+2*j]);
m_baOutBuffer.Add((BYTE)m_waAnalog[i*2+2*j]>>8);
}
for(int m=0;m<1;m++)
{
m_baOutBuffer.Add(0x00);
m_baOutBuffer.Add(0x00);
}
}
check_sendcode(i*6+12);
funcode++;
if(funcode > 0x7e)
break;
}
}
void CProtocolCDT91::SendDd()
{
int countLen=m_dwaCount.GetSize();
if(countLen < 0)
return;
BYTE funcode=0xa0;
for(int i=0;i<countLen;i++)
{
m_baOutBuffer.Add(funcode);
m_baOutBuffer.Add((BYTE)m_dwaCount[i]);
m_baOutBuffer.Add((BYTE)m_dwaCount[i]>>8);
m_baOutBuffer.Add((BYTE)m_dwaCount[i]>>16);
m_baOutBuffer.Add((BYTE)m_dwaCount[i]>>24);
check_sendcode(i*6+12);
funcode++;
if(funcode > 0xde)
break;
}
}
void CProtocolCDT91::PreOperate()
{
BYTE array[6];
if(m_baInBuffer.GetSize() < 30)
return;
for(int i=0;i<4;i++)
{
for(int j=0;j<6;j++)
{
array[j]=m_baInBuffer[i*6+j+6];
}
if(!check_revcode(array))
OperBack(m_baInBuffer[10],FALSE);
}
if(m_baInBuffer[10] != m_wAddr)
return;
//m_KgState 1=合闸 0-分闸
if((m_baInBuffer[13] == 0xcc)&&(!m_KgState))//合闸
{
OperBack(m_baInBuffer[10],TRUE);
m_bFlag=TRUE;
}
else if((m_baInBuffer[13] == 0x33)&&m_KgState)//分闸
{
OperBack(m_baInBuffer[10],TRUE);
m_bFlag=TRUE;
}
else
{
OperBack(m_baInBuffer[10],FALSE);
}
TRACE("收到遥控选择命令并返回正确!\n");
}
void CProtocolCDT91::CancelOper()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -