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

📄 ofxplcdev.cpp

📁  ?  plc 与上位机通信接口 帮助有需要的人
💻 CPP
字号:
// OFxPLCDev.cpp: implementation of the COFxPLCDev class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "OFxPLCDev.h"

#include <cmath>
#include <string>
using  namespace  std;

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

COFxPLCDev::COFxPLCDev()
{

}
																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																
																																																																																																														
COFxPLCDev::~COFxPLCDev()
{

}
int COFxPLCDev::check_sum(BYTE *buf, int &buflen, BYTE &chSum)
{
	/*三菱的伺服放大器的检验和是将准备好的命令字符串从第一个开始,依次作加法运算。最后得到的字节转换成两位的字符。
	 *比如:  "00502303203"的检验和是FC。计算是这样进行的: 0x30+0x30+0x35+0x30+0x32+0x33+0x32+0x30+0x33 = 0xFC
	 *最后的字符串为:"00502303203FC"
	*/
	//输入  buf[], buflen
	//输出 chSum
	//

	char newBuf[128];
	memset(newBuf, 0x00, sizeof (newBuf));

	//将字符串拷贝到临时的缓冲区中。
	memcpy(newBuf, buf, buflen);
	int   l_get = 0;
	for (int i = 0; i<buflen; i++)
	{
		l_get += newBuf[i];
	}
	chSum = l_get;

	return SUCCESS;
}

int COFxPLCDev::get_response(BYTE *ibuf, int ilen, BYTE *rbuf, int &rlen, _retstruct *_ret)
{
	//读取返回值
	/*
	输入:	无
	输出:	resbuf   接受的数据缓冲区
			reslen   接受数据的长度
	返回:  成功返回success, 否则返回错误代码。
	*/
	char   inputbuf[128];
	memset(inputbuf, 0x00, sizeof(inputbuf));
	for (int i = 0; i<ilen ; i++)
	{
		inputbuf[i] = ibuf[i];		
	}

	if (inputbuf[2] == 'A' || inputbuf[2] == 'a')
	{
		memcpy(rbuf, &inputbuf[3], ilen - 6);
		rlen = ilen - 6;
		_ret->code = SUCCESS;
	}
	else
	{
		_ret->code =FAIL;
		_ret->discription = "响应错误";
		_ret->time = CTime::GetCurrentTime();
	}

	return   _ret->code;
}

int COFxPLCDev::InitDev(CString  strReg, _retstruct *_ret)
{
	/*
		执行步骤:
		1、读取注册表strReg中的串口参数
		2、这些参数赋值给它的属性数据
		3、调用InitComm
	*/
	LONG  hr;
	HKEY   hKey = NULL;
	DWORD  cbData;
	DWORD  dwType = REG_DWORD;
	DWORD  dwDisposition;
	
	hr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, strReg, 0, NULL, REG_OPTION_NON_VOLATILE, \
		KEY_WRITE|KEY_READ, NULL, &hKey, &dwDisposition);

	if (ERROR_SUCCESS != hr)
		return FAIL;
	
	if(ERROR_SUCCESS != RegQueryValueEx(hKey, "Port", \
		NULL, &dwType, (BYTE*)&m_iPortID, &cbData) )
	{
		return FAIL;
	}
 	if(ERROR_SUCCESS != RegQueryValueEx(hKey, "BaudRate", NULL, &dwType, (BYTE*)&m_iBaudRate, &cbData))
	{
		return FAIL;
	}

	if (ERROR_SUCCESS != RegQueryValueEx(hKey, "ByteSize", NULL, &dwType, (BYTE*)&m_iBytesize, &cbData))
	{
		return FAIL;
	}
	
	if (ERROR_SUCCESS != RegQueryValueEx(hKey, "Parity", NULL, &dwType, (BYTE*)&m_iParity, &cbData))
	{
		return FAIL;
	}

	if (ERROR_SUCCESS != RegQueryValueEx(hKey, "StopBits", NULL, &dwType, (BYTE*)&m_iStopBits, &cbData))
	{
		return FAIL;
	}

	if (SUCCESS!= InitComm())
	{
		_ret->code = FAIL;	
		_ret->discription = _T("注册表损坏,请重新添加注册表文件!");
		_ret->time = CTime::GetCurrentTime();
	} 
	else
	{
		_ret->code = SUCCESS;
		_ret->discription = _T("初始化PLC成功");
		_ret->time = CTime::GetCurrentTime();

	}
		
	return _ret->code;
}

int COFxPLCDev::SendENQ(_retstruct *_ret)
{
	char  chStrRET[2];
	memset(chStrRET, 0x00, sizeof(chStrRET));
	char   chStrENQ[2];
	
	memset(chStrENQ, 0x00, sizeof(chStrENQ));
	chStrENQ[0] = ENQ;
	int   iLen = 1;
	if (SUCCESS != WritePort((BYTE*)chStrENQ, strlen(chStrENQ), 10))
		return  FAIL;
	
	if(SUCCESS == ReadPort((BYTE*)chStrENQ, iLen, 20))
	{
		if(chStrENQ[0] == ACK)
		{
			_ret->code = SUCCESS;
			_ret->time =  CTime::GetCurrentTime();
			_ret->discription = "LCA连接成功。";
		}
		else if(chStrENQ[0] == NAK)
		{
			_ret->code = FAIL;
			_ret->time =  CTime::GetCurrentTime();
			_ret->discription = "LCA连接失败。返回NAK。";
		}
		else
		{
			_ret->code = FAIL;
			_ret->time = CTime::GetCurrentTime();
			_ret->discription = "LCA连接失败。其他未知错误。";
			
		}
		return _ret->code;
	}
	else
	{
		_ret->code = FAIL;
		_ret->time =  CTime::GetCurrentTime();
		_ret->discription = "LCA连接失败。请检查通信线路是否正常!";
	}
	
	return  _ret->code;
}

//D1, D3
int COFxPLCDev::GetSpeed(_retstruct *_ret, int istation, int &Speed)
{
	/*
		执行步骤:
		1、组合命令;
		2、将数据添加检验和,并添加命令首部
		3、WritePort
		4、ReadPort
		5、解析返回数据,并将数据送给Speed.
	*/

	CString  strstation;
	strstation.Empty();

	strstation.Format("%04X", istation);
	CString  strcmd;
	strcmd = "\x30"+strstation+"\x30\x32\x03";
	
	
	//组成命令
	char  chCmd[128];
	memset(chCmd, 0x00, sizeof(chCmd));

	int      strcmdlen = 0;
	strcmdlen = strlen(strcmd);
	memcpy(chCmd, strcmd, strcmdlen);
	BYTE chSum = 0;
	check_sum((BYTE*)chCmd, strcmdlen , chSum);
	CString  schSum;
	schSum.Format("%02X", chSum);
	
	CString   strfin;
	strfin = "\x02" + strcmd +schSum;
	
	int  strfinlen = 0;
	strfinlen = strlen(strfin);

	memset(chCmd, 0x00, sizeof(chCmd));
	memcpy(chCmd, strfin, strfinlen);
	//发送命令
	if (SUCCESS != WritePort((BYTE*)chCmd, strfinlen, 10))
	{
		_ret->code = FAIL;
		_ret->discription = "写入数据错误!";
		_ret->time = CTime::GetCurrentTime();
	}
	else
	{
		
		//取得响应并解析值
		char   recbuf[128];
		memset(recbuf, 0x00, sizeof(recbuf));
		int ilen = 128;
		if (SUCCESS != ReadPort((BYTE*)recbuf, ilen,90))
		{
			_ret->code = FAIL;
			_ret->discription = "读取数据错误!";
			_ret->time = CTime::GetCurrentTime();
		}
		else
		{
			if (0x02!=recbuf[0])			
			{
				_ret->code = FAIL;
				return FAIL;
			}
			if (0x03!=recbuf[5])
			{
				_ret->code = FAIL;
				return FAIL;
			}
			
			char chtemp;

			chtemp = recbuf[1];
			recbuf[1] = recbuf[3];
			recbuf[3] = recbuf[4];
			recbuf[4] = recbuf[2];
			recbuf[2] = recbuf[3];
			recbuf[3] = chtemp;
			char  tempbuf[5];
			memset(tempbuf, 0x00, 5);
			memcpy(tempbuf, &recbuf[1], 4);
			tempbuf[4] = 0;
			
			sscanf(tempbuf, "%x", &Speed);

			_ret->code = SUCCESS;
		}
	}

	return _ret->code;
}

//D5, D7
int COFxPLCDev::SetSpeed(_retstruct *_ret, int istation, int Speed)
{

	CString   strSpeed;
	strSpeed.Empty();

	strSpeed.Format("%04X", Speed);

	char chSpeed[5];

	for (int i = 0; i<4; i++)
	{
		chSpeed[i] = strSpeed.GetAt(i);
	}
	//strcpy(chSpeed, strSpeed.Left(5));
	chSpeed[4] = 0;
	char  chtemp;
	chtemp = chSpeed[0];
	chSpeed[0] = chSpeed[2];
	chSpeed[2] = chSpeed[1];
	chSpeed[1] = chSpeed[3];
	chSpeed[3] = chSpeed[2];
	chSpeed[2] = chtemp;

	CString  strsetspeed;
	strsetspeed.Empty();
	
	strsetspeed.Format("%s", chSpeed);

	CString  strstation;
	strstation.Empty();

	strstation.Format("%04X", istation);
	CString  strcmd;
	strcmd = "\x31"+strstation+"\x30\x32"+ strsetspeed +"\x03";
	
	
	//组成命令
	char  chCmd[128];
	memset(chCmd, 0x00, sizeof(chCmd));

	int      strcmdlen = 0;
	strcmdlen = strlen(strcmd);
	memcpy(chCmd, strcmd, strcmdlen);
	BYTE chSum = 0;
	check_sum((BYTE*)chCmd, strcmdlen , chSum);
	CString  schSum;
	schSum.Format("%02X", chSum);
	
	CString   strfin;
	strfin = "\x02" + strcmd +schSum;
	
	int  strfinlen = 0;
	strfinlen = strlen(strfin);

	memset(chCmd, 0x00, sizeof(chCmd));
	memcpy(chCmd, strfin, strfinlen);
	//发送命令
	if (SUCCESS != WritePort((BYTE*)chCmd, strfinlen, 30))
	{
		_ret->code = FAIL;
		_ret->discription = "写入数据错误!";
		_ret->time = CTime::GetCurrentTime();
	}
	else
	{
		
		//取得响应并解析值
		char   recbuf[128];
		memset(recbuf, 0x00, 128);
		int ilen = 1;
		if (SUCCESS != ReadPort((BYTE*)recbuf, ilen, 100))
		{
			_ret->code = FAIL;
			_ret->discription = "读取数据错误!";
			_ret->time = CTime::GetCurrentTime();
		}
		else
		{
			if (0x06!=recbuf[0])			
			{
				_ret->code = FAIL;
				return FAIL;
			}
			_ret->code = SUCCESS;
		}
	}
	return _ret->code;
}

//强制输出为on  S、X、Y、M、T、C
int COFxPLCDev::force_on(_retstruct *_ret, int istation)
{
	//先将istation作如下的转化:istation转化为16进制,然后将低位放在前面,高位在后;
	CString  strstation;
	strstation.Empty();

	strstation.Format("%04X", istation);
	CString  strcmd;
	strcmd = "\x37"+strstation+"\x03";
	
	
	//组成命令
	char  chCmd[128];
	memset(chCmd, 0x00, sizeof(chCmd));

	int      strcmdlen = 0;
	strcmdlen = strlen(strcmd);
	memcpy(chCmd, strcmd, strcmdlen);
	BYTE chSum = 0;
	check_sum((BYTE*)chCmd, strcmdlen , chSum);
	CString  schSum;
	schSum.Format("%02X", chSum);
	
	CString   strfin;
	strfin = "\x02" + strcmd +schSum;
	
	int  strfinlen = 0;
	strfinlen = strlen(strfin);

	memset(chCmd, 0x00, sizeof(chCmd));
	memcpy(chCmd, strfin, strfinlen);
	//发送命令
	if (SUCCESS != WritePort((BYTE*)chCmd, strfinlen, 50))
	{
		_ret->code = FAIL;
		_ret->discription = "写入数据错误!";
		_ret->time = CTime::GetCurrentTime();
	}
	else
	{
		
		//取得响应并解析值
		char   recbuf[128];
		memset(recbuf, 0x00, 128);
		int ilen = 1;
		if (SUCCESS != ReadPort((BYTE*)recbuf, ilen, 150))
		{
			_ret->code = FAIL;
			_ret->discription = "读取数据错误!";
			_ret->time = CTime::GetCurrentTime();
		}
		else
		{
			if (0x06!=recbuf[0])			
			{
				_ret->code = FAIL;
				return FAIL;
			}
			_ret->code = SUCCESS;
		}
	}
	return _ret->code;
}

//强制输出为off	S、X、Y、M、T、C
int COFxPLCDev::force_off(_retstruct *_ret, int istation)
{
	CString  strstation;
	strstation.Empty();

	strstation.Format("%04X", istation);
	CString  strcmd;
	strcmd = "\x38"+strstation+"\x03";
	
	
	//组成命令
	char  chCmd[128];
	memset(chCmd, 0x00, sizeof(chCmd));

	int      strcmdlen = 0;
	strcmdlen = strlen(strcmd);
	memcpy(chCmd, strcmd, strcmdlen);
	BYTE chSum = 0;
	check_sum((BYTE*)chCmd, strcmdlen , chSum);
	CString  schSum;
	schSum.Format("%02X", chSum);
	
	CString   strfin;
	strfin = "\x02" + strcmd +schSum;
	
	int  strfinlen = 0;
	strfinlen = strlen(strfin);

	memset(chCmd, 0x00, sizeof(chCmd));
	memcpy(chCmd, strfin, strfinlen);
	//发送命令

	if (SUCCESS != WritePort((BYTE*)chCmd, strfinlen, 50))
	{
		_ret->code = FAIL;
		_ret->discription = "写入数据错误!";
		_ret->time = CTime::GetCurrentTime();
	}
	else
	{
		
		//取得响应并解析值
		char   recbuf[128];
		memset(recbuf, 0x00, 128);
		int ilen = 1;
		if (SUCCESS != ReadPort((BYTE*)recbuf, ilen, 150))
		{
			_ret->code = FAIL;
			_ret->discription = "读取数据错误!";
			_ret->time = CTime::GetCurrentTime();
		}
		else
		{
			if (0x06!=recbuf[0])			
			{
				_ret->code = FAIL;
				return FAIL;
			}
			_ret->code = SUCCESS;
		}
	}
	return _ret->code;
}

//读取一个字节数据
int COFxPLCDev::read_one(_retstruct *_ret, int istation, char &value)
{
	CString  strstation;
	strstation.Empty();

	strstation.Format("%04X", istation);
	CString  strcmd;
	strcmd = "\x30"+strstation+"\x30\x31\x03";
	
	
	//组成命令
	char  chCmd[128];
	memset(chCmd, 0x00, sizeof(chCmd));

	int      strcmdlen = 0;
	strcmdlen = strlen(strcmd);
	memcpy(chCmd, strcmd, strcmdlen);
	BYTE chSum = 0;
	check_sum((BYTE*)chCmd, strcmdlen , chSum);
	CString  schSum;
	schSum.Format("%02X", chSum);
	
	CString   strfin;
	strfin = "\x02" + strcmd +schSum;
	
	int  strfinlen = 0;
	strfinlen = strlen(strfin);

	memset(chCmd, 0x00, sizeof(chCmd));
	memcpy(chCmd, strfin, strfinlen);
	//发送命令
	if (SUCCESS != WritePort((BYTE*)chCmd, strfinlen, 10))
	{
		_ret->code = FAIL;
		_ret->discription = "写入数据错误!";
		_ret->time = CTime::GetCurrentTime();
	}
	else
	{
		
		//取得响应并解析值
		char   recbuf[128];
		memset(recbuf, 0x00, sizeof(recbuf));
		int ilen = 128;
		if (SUCCESS != ReadPort((BYTE*)recbuf, ilen,90))
		{
			_ret->code = FAIL;
			_ret->discription = "读取数据错误!";
			_ret->time = CTime::GetCurrentTime();
		}
		else
		{
			if (0x02!=recbuf[0])			
			{
				_ret->code = FAIL;
				return FAIL;
			}
			if (0x03!=recbuf[3])
			{
				_ret->code = FAIL;
				return FAIL;
			}
			if (recbuf[1]&0x80)
				value = 1;
			else 
				value = 0;
			_ret->code = SUCCESS;
		}
	}

	return _ret->code;
}

⌨️ 快捷键说明

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