⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocoldisa.cpp

📁 电力和自动化通讯规约模拟软件
💻 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 + -