📄 protocoldisa.cpp
字号:
// ProtocolDisa.cpp: implementation of the CProtocolDisa class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ProtocolDisa.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern BYTE bch_table[256];
extern BOOL OnOff;
CProtocolDisa::CProtocolDisa()
{
m_KgState=FALSE;
m_SendNo=0;
m_bFlag=TRUE;
}
CProtocolDisa::~CProtocolDisa()
{
}
BOOL CProtocolDisa::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;
}
BOOL CProtocolDisa::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 CProtocolDisa::Data_ArrayC(BYTE rtuAddress, BYTE ctrl,BYTE infoNum)
{
m_baOutBuffer.Add(0x71);
m_baOutBuffer.Add(ctrl);
m_baOutBuffer.Add(infoNum+1);
m_baOutBuffer.Add(0x00); //源地址
m_baOutBuffer.Add(rtuAddress); //目标地址
check_sendcode(6); //校验码
}
void CProtocolDisa::Data_ArrayS()
{
for(int i=0;i<6;i=i+2)
{
m_baOutBuffer.Add(0xeb);
m_baOutBuffer.Add(0x90);
}
}
void CProtocolDisa::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);
}
BOOL CProtocolDisa::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;
}
BOOL CProtocolDisa::OperBack(BYTE rtuAddress,BOOL state)
{
Data_ArrayS();
Data_ArrayC(rtuAddress,0x7a,3);
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;
}
void CProtocolDisa::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 CProtocolDisa::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 CProtocolDisa::SendYx()
{
int digLen=m_baDigital.GetSize();
if(digLen < 0 )
return;
int yushu=digLen%4; //取余数
int shang=digLen/4; //商
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(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;
}
}
BOOL CProtocolDisa::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 CProtocolDisa::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);
}
void CProtocolDisa::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);
else
Data_ArrayC(rtuAddr,0xf4,m_baDigital.GetSize()/4+1);
SendYx();
break;
case 7:
Data_ArrayC(rtuAddr,0x85,m_dwaCount.GetSize());
SendDd();
break;
default:
break;
}
m_SendNo++;
if(m_SendNo > 9)
m_SendNo=0;
SendRespons();
}
void CProtocolDisa::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 CProtocolDisa::CancelOper()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -