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

📄 s7ppiprotocol.cpp

📁 串口与OPC通信
💻 CPP
字号:
// S7PPIprotocol.cpp : implementation file
//

#include "stdafx.h"
#include "protocol.h"
#include "S7PPIprotocol.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CS7PPIprotocol

CS7PPIprotocol::CS7PPIprotocol()
{
}

CS7PPIprotocol::~CS7PPIprotocol()
{
}

/////////////////////////////////////////////////////////////////////////////


//ReadVB函数用来读取vb的值plc(200plc编号),vbaddr(vb地址),count(读取个数),buffer(存放地址)   
//如果读取正确返回0,发送命令返回错误返回1,接受数据校验错误返回2

int CS7PPIprotocol::ReadVB(int plc,int vbaddr, int count, BYTE *buffer)
{
	BYTE sendcmd[33]={0x68,0x1B,0x1B,0x68,0x02,0x00,0x6C,0x32,0x01,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x04,0x01, 0x12,0x0A,0x10
		,0x02,0x00,0x01,0x00,0x01,0x84,0x00,0x03,0x20,0x8B,0x16};

    //plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	//计算地址
	vbaddr*=8;
	sendcmd[30]=vbaddr%256;
	sendcmd[29]=vbaddr/256;
	sendcmd[28]=vbaddr/65536;
	//计算读取个数
	sendcmd[24]=count;
	//计算校验码
	BYTE  fcs=0;
	for (int i=4;i<31;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[31]=fcs%256;

	m_SerialPort.SendData(sendcmd,33);
	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		BYTE confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}
	int buffercount=27+count;
	Sleep(300);
	BYTE *receive=new BYTE[buffercount];
	m_SerialPort.ReadData(receive,buffercount);

	fcs=0;
	for (i=4;i<buffercount-2;i++)
	{
		fcs+=receive[i];
		fcs%=256;
	}
    if (fcs!=receive[buffercount-2])
    {
		return 2;
    }

	Decodeprotocol(buffer,receive,count);
	delete[]  receive;


	return 0;
}

void CS7PPIprotocol::Decodeprotocol(BYTE *debuffer, BYTE *sbuffer, int count)
{

	memcpy(debuffer,sbuffer+25,count);
}

int CS7PPIprotocol::ReadVW(int plc,int vwaddr, int count, BYTE *buffer)
{
	unsigned char sendcmd[33]={0x68,0x1B,0x1B,0x68,0x02,0x00,0x6C,0x32,0x01,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x04,0x01, 0x12,0x0A,0x10
		,0x02,0x00,0x01,0x00,0x01,0x84,0x00,0x03,0x20,0x8D,0x16};
	//plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	////////////////////////
	vwaddr*=8;
	sendcmd[30]=vwaddr%256;
	sendcmd[29]=vwaddr/256;
	sendcmd[28]=vwaddr/65536;
	//计算读取个数
	sendcmd[24]=count*2;
	//计算校验码
	BYTE  fcs=0;
	for (int i=4;i<31;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[31]=fcs%256;
	
	m_SerialPort.SendData(sendcmd,33);
	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		unsigned char confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}

	int buffercount=27+count*2;
	Sleep(300);
	BYTE *receive=new BYTE[buffercount];	
	m_SerialPort.ReadData(receive,buffercount);
	
	fcs=0;
	for (i=4;i<buffercount-2;i++)
	{
		fcs+=receive[i];
		fcs%=256;
	}
    if (fcs!=receive[buffercount-2])
    {
		return 2;
    }
	
	Decodeprotocol(buffer,receive,count*2);
	delete[]  receive;
	
	
	return 0;
}

int CS7PPIprotocol::ReadVD(int plc,int vdaddr, int count, BYTE *buffer)
{
	unsigned char sendcmd[33]={0x68,0x1B,0x1B,0x68,0x02,0x00,0x6C,0x32,0x01,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x04,0x01, 0x12,0x0A,0x10
		,0x02,0x00,0x01,0x00,0x01,0x84,0x00,0x03,0x20,0x8D,0x16};
	//plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	////////////////////////
	vdaddr*=8;
	sendcmd[30]=vdaddr%256;
	sendcmd[29]=vdaddr/256;
	sendcmd[28]=vdaddr/65536;
	//计算读取个数
	sendcmd[24]=count*4;
	//计算校验码
	BYTE  fcs=0;
	for (int i=4;i<31;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[31]=fcs%256;
	
	m_SerialPort.SendData(sendcmd,33);
	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		unsigned char confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}
	
	int buffercount=27+count*4;
	Sleep(300);
	BYTE *receive=new BYTE[buffercount];	
	m_SerialPort.ReadData(receive,buffercount);
	
	fcs=0;
	for (i=4;i<buffercount-2;i++)
	{
		fcs+=receive[i];
		fcs%=256;
	}
    if (fcs!=receive[buffercount-2])
    {
		return 2;
    }
	
	Decodeprotocol(buffer,receive,count*4);
	delete[]  receive;

	return 0;
}

int CS7PPIprotocol::ReadM(int plc,int rm1, int rm2, BYTE *buffer)
{
	unsigned char sendcmd[33]={0x68,0x1B,0x1B,0x68,0x02,0x00,0x6C,0x32,0x01,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x04,0x01, 0x12,0x0A,0x10
		,0x01,0x00,0x01,0x00,0x00,0x83,0x00,0x00,0x00,0x00,0x16};
	//plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	////////////////////////	
	sendcmd[30]=(BYTE)(rm1*8+rm2);
	//计算校验码
	BYTE  fcs=0;
	for (int i=4;i<31;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[31]=fcs%256;
	
	m_SerialPort.SendData(sendcmd,33);
	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		unsigned char confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}

	Sleep(40);
	BYTE *receive=new BYTE[28];	
	m_SerialPort.ReadData(receive,28);
	
	fcs=0;
	for (i=4;i<26;i++)
	{
		fcs+=receive[i];
		fcs%=256;
	}
    if (fcs!=receive[26])
    {
		return 2;
    }
	
	*buffer=receive[25];
    delete[]  receive;
	return 0;
}

void CS7PPIprotocol::gp_to_float(BYTE *datasource, float *datadestination, int datacount)
{
	unsigned char *data=new unsigned char[datacount*4];
	
	
	/////////////////反向排序
	int b;
	for (int i=0;i<datacount*4;i++)
	{
		b=i%4;
		switch (b)
		{
			
		case 0:
            data[i]=datasource[i+3];
			break;
		case 1:
			data[i]=datasource[i+1];
			break;
		case 2:
			data[i]=datasource[i-1];
			break;
		case 3:
			data[i]=datasource[i-3];
			break;
		default:
			break;
		}
		
		
	}
	
	memcpy(datadestination,data,datacount*4);
	delete[]  data;

}

int CS7PPIprotocol::WriteVB(int plc,int vbaddr,BYTE data)
{

	BYTE sendcmd[38]={0x68,0x20,0x20,0x68,0x02,0x00,0x7C,0x32,0x01,0x00,0x00
		,0x00,0x00,0x00,0x0E,0x00,0x05,0x05,0x01,0x12,0x0A,0x10
		,0x02,0x00,0x01,0x00,0x01,0x84,0x00,0x03,0x20,0x00,0x04,0x00,0x08,0x00,0xB9,0x16};
   	//plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	////////////////////////
	//计算地址
	vbaddr*=8;
	sendcmd[30]=vbaddr%256;
	sendcmd[29]=vbaddr/256;
	sendcmd[28]=vbaddr/65536;
	//赋值
	sendcmd[35]=data;
	/////////////////////////////
	BYTE  fcs=0;
	for (int i=4;i<36;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[36]=fcs;
	
	m_SerialPort.SendData(sendcmd,38);
	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		BYTE confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}

	Sleep(50);
	BYTE *receive=new BYTE[24];
	m_SerialPort.ReadData(receive,24);
	

	//写完成后返回的命令
    BYTE  confirm_w[24]={0x68,0x12,0x12,0x68,0x00,0x02,0x08,0x32,0x03
		,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x05,0x01,0xFF,0x47,0x16};
	confirm_w[5]=(BYTE)plc;
	fcs=0;
	for (i=4;i<22;i++)
	{
		
		fcs+=confirm_w[i];
		fcs%=256;
	}
	sendcmd[22]=fcs;
	if (!memcmp(receive,confirm_w,24))
	{
		return 2;
	}

	return 0;
}

int CS7PPIprotocol::WriteVW(int plc,int vwaddr, BYTE* data)
{

	BYTE sendcmd[39]={0x68,0x21,0x21,0x68,0x02,0x00,0x7C,0x32,0x01,0x00,0x00
		,0x00,0x00,0x00,0x0E,0x00,0x06,0x05,0x01,0x12,0x0A,0x10
		,0x04,0x00,0x01,0x00,0x01,0x84,0x00,0x03,0x20,0x00,0x04,0x00,0x10,0x00,0x10,0xB9,0x16};
	//plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	////////////////////////
	//计算地址
	vwaddr*=8;
	sendcmd[30]=vwaddr%256;
	sendcmd[29]=vwaddr/256;
	sendcmd[28]=vwaddr/65536;
    //赋值
	sendcmd[35]=*data;
	sendcmd[36]=*(data+1);
	//计算校验码
	BYTE  fcs=0;
	for (int i=4;i<37;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[37]=fcs;

	m_SerialPort.SendData(sendcmd,39);
	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		unsigned char confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}
	//////////////////////////
	Sleep(50);
	BYTE *receive=new BYTE[24];
	m_SerialPort.ReadData(receive,24);
	
	//写完成后返回的命令
    BYTE  confirm_w[24]={0x68,0x12,0x12,0x68,0x00,0x02,0x08,0x32,0x03
		,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x05,0x01,0xFF,0x47,0x16};
	confirm_w[5]=(BYTE)plc;
	fcs=0;
	for (i=4;i<22;i++)
	{
		
		fcs+=confirm_w[i];
		fcs%=256;
	}
	sendcmd[22]=fcs;
	if (!memcmp(receive,confirm_w,24))
	{
		return 2;
	}

	return 0;
}

int CS7PPIprotocol::WriteVD(int plc,int vdaddr, BYTE *data)
{
	BYTE sendcmd[41]={0x68,0x23,0x23,0x68,0x02,0x00,0x7C,0x32,0x01,0x00,0x00
		,0x00,0x00,0x00,0x0E,0x00,0x08,0x05,0x01,0x12,0x0A,0x10
		,0x06,0x00,0x01,0x00,0x01,0x84,0x00,0x03,0x20,0x00,0x04,0x00,0x20,0x00,0x10,0x00,0x00,0xB9,0x16};
	//plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	////////////////////////
	//计算地址
	vdaddr*=8;
	sendcmd[30]=vdaddr%256;
	sendcmd[29]=vdaddr/256;
	sendcmd[28]=vdaddr/65536;
    //赋值
	sendcmd[35]=*data;
	sendcmd[36]=*(data+1);	
	sendcmd[37]=*(data+2);
	sendcmd[38]=*(data+3);
	//计算校验码
	BYTE  fcs=0;
	for (int i=4;i<39;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[39]=fcs;

	m_SerialPort.SendData(sendcmd,41);
	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		unsigned char confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}
	//////////////////////////
	Sleep(50);
	BYTE *receive=new BYTE[24];
	m_SerialPort.ReadData(receive,24);
	
	//写完成后返回的命令
    BYTE  confirm_w[24]={0x68,0x12,0x12,0x68,0x00,0x02,0x08,0x32,0x03
		,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x05,0x01,0xFF,0x47,0x16};
	confirm_w[5]=(BYTE)plc;
	fcs=0;
	for (i=4;i<22;i++)
	{
		
		fcs+=confirm_w[i];
		fcs%=256;
	}
	sendcmd[22]=fcs;
	if (!memcmp(receive,confirm_w,24))
	{
		return 2;
	}
	return 0;
}

int CS7PPIprotocol::WritetoPLC(int plc,int addr, float value)
{

	BYTE tempdata[4],data[4];
	memcpy(tempdata,&value,4);

	data[0]=tempdata[3];
	data[1]=tempdata[2];
	data[2]=tempdata[1];
	data[3]=tempdata[0];
	return WriteVD(plc,addr,data);
}

int CS7PPIprotocol::WriteM(int plc,int m1, int m2, BYTE value)
{

	BYTE sendcmd[38]={0x68,0x20,0x20,0x68,0x02,0x00,0x7C,0x32,0x01,0x00,0x00
		,0x00,0x00,0x00,0x0E,0x00,0x05,0x05,0x01,0x12,0x0A,0x10
		,0x01,0x00,0x01,0x00,0x00,0x83,0x00,0x00,0x00,0x00,0x03,0x00,0x01,0x00,0xB9,0x16};

	//plc的编号赋值
	sendcmd[4]=(BYTE)plc;
	////////////////////////
	sendcmd[30]=(BYTE)(m1*8+m2);
	if (value==0)
	{
		sendcmd[35]=0x00;
	} 
	else
	{
		sendcmd[35]=0x01;
	}
	//计算校验码
	BYTE  fcs=0;
	for (int i=4;i<36;i++)
	{
		
		fcs+=sendcmd[i];
		fcs%=256;
	}
	sendcmd[36]=fcs;

	m_SerialPort.SendData(sendcmd,38);

	Sleep(20);
	BYTE confirm_buffer;
	m_SerialPort.ReadData(&confirm_buffer,1);
	if (confirm_buffer==0xE5)
	{
		unsigned char confirmcmd[6]={0x10,0x02,0x00,0x5C,0x5E,0x16};
		confirmcmd[1]=(BYTE)plc;
		confirmcmd[4]=0x5C+plc;
		m_SerialPort.SendData(confirmcmd,6);
		
	}
	else
	{
		return 1;
	}
	//////////////////////////
	Sleep(50);
	BYTE *receive=new BYTE[24];
	m_SerialPort.ReadData(receive,24);
	
	//写完成后返回的命令
    BYTE  confirm_w[24]={0x68,0x12,0x12,0x68,0x00,0x02,0x08,0x32,0x03
		,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x05,0x01,0xFF,0x47,0x16};
	confirm_w[5]=(BYTE)plc;
	fcs=0;
	for (i=4;i<22;i++)
	{
		
		fcs+=confirm_w[i];
		fcs%=256;
	}
	sendcmd[22]=fcs;
	if (!memcmp(receive,confirm_w,24))
	{
		return 2;
	}

	return 0;
}

int CS7PPIprotocol::ReadfromPLC(int plc,int vdaddr, int count, float *buffer)
{
    BYTE *databuffer=new BYTE[count*4];
	int return_va=ReadVD(plc,vdaddr,count,databuffer);
	gp_to_float(databuffer,buffer,count);
	delete[] databuffer;

	return return_va;
}

BOOL CS7PPIprotocol::OpenComport(int comid)
{
	return m_SerialPort.Open(comid,9600);
}

BOOL CS7PPIprotocol::CloseComport(int comid)
{
   	return m_SerialPort.Close();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -