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

📄 ofxplcdev.cpp.bak

📁  ?  plc 与上位机通信接口 帮助有需要的人
💻 BAK
字号:
// 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::SendTo(_retstruct *_ret,BYTE *addr, int adlen, BYTE *buf, int buflen)
{
	//向LCA寄存器发送数据
	/************************************************************************/
	/*相关函数:check_sum,为数据添加检验和位                                
	 *	        get_response, 取得LCA的响应数据
	*/
	/************************************************************************/
	/*
	输入:	addr   寄存器地址
			adlen  寄存器地址长度
			buf    将要发送的数据
			buflen 发送数据的长度
	输出:
	返回:	成功返回success, 否则返回错误代码。
	*/
	return SUCCESS;
}

int COFxPLCDev::ReadFrom(_retstruct *_ret,BYTE *addr, int adlen, BYTE *recbuf, int &reclen)
{
	//读取LCA寄存器数据
	/************************************************************************/
	/*相关函数:check_sum,为数据添加检验和位                                
	 *	        get_response, 取得LCA的响应数据,并返回错误代码
	*/
	/************************************************************************/
	/*
	输入:	addr   寄存器地址
			adlen  寄存器地址长度
			
	输出:	recbuf 将要读取的数据缓冲区
			reclen 读取数据的长度

	返回:	成功返回success, 否则返回错误代码。
	*/
	
	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();
	} 
		
	return _ret->code = SUCCESS;
}

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 = 0;
	if (SUCCESS != WritePort((BYTE*)chStrENQ, strlen(chStrENQ), 300))
		return  FAIL;
	
	if(SUCCESS == ReadPort((BYTE*)chStrENQ, iLen, 300))
	{
		if(chStrENQ[0] == ACK)
		{
			_ret->code = ACK;
			_ret->time =  CTime::GetCurrentTime();
			_ret->discription = "LCA连接成功。";
		}
		else if(chStrENQ[0] == NAK)
		{
			_ret->code = NAK;
			_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;
}

int COFxPLCDev::GetSpeed(_retstruct *_ret, int istation, int &Speed)
{
	/*
		执行步骤:
		1、组合命令;
		2、将数据添加检验和,并添加命令首部
		3、WritePort
		4、ReadPort
		5、解析返回数据,并将数据送给Speed.
	*/
	
	
	if (0>istation || istation>32)
	{
		_ret->code = FAIL;
		_ret->discription = _T(" 无效的站点");
		_ret->time = CTime::GetCurrentTime();
	}
	
	//添加站号 istation
	CString station;
	station.Format("%c", istation+0x30);

	//添加指令[0][5]
	CString  cmdstr;
	cmdstr = "\x30\x35";

	//添加参数[0][9]
	CString  cmdpra;
	cmdpra = "\x30\x39";
	
	//组成命令
	char  chCmd[128];
	memset(chCmd, 0x00, sizeof(chCmd));
	CString strcmd;
	strcmd = station +cmdstr + "\x02"+ cmdpra +"\x03";
	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 = "\x01" + 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
		{
			
			char   rbuf[128];
			memset(rbuf, 0x00, sizeof(rbuf));
			int rlen = 128;
			if(	SUCCESS == get_response((BYTE *)recbuf, ilen, (BYTE *)rbuf, rlen, _ret))
			{
				Speed = 0;
				for (int i = 1; i<8; i++)
				{
					if (0x40<rbuf[i]&&rbuf[i]<0x47)
						rbuf[i] = rbuf[i] - 7;
					Speed += (rbuf[i]-0x30)*pow(16, 7-i);
				}

				_ret->code = SUCCESS;
			}

		}
	}
	return _ret->code;
}
int COFxPLCDev::SetSpeed(_retstruct *_ret, int istation, int Speed)
{
	/*
		执行步骤:
		1、组合命令;
		2、将数据添加检验和,并添加命令首部
		3、WritePort
		4、ReadPort
		5、解析返回数据,是否设置成功.
	*/
	
	
	if (0>istation || istation>32)
	{
		_ret->code = FAIL;
		_ret->discription = _T(" 无效的站点");
		_ret->time = CTime::GetCurrentTime();
	}
	
	//添加站号 istation
	CString station;
	station.Format("%c", istation+0x30);

	//添加指令[0][5]
	CString  cmdstr;
	cmdstr = "\x38\x34";

	//添加参数[0][9]
	CString  cmdpra;
	cmdpra = "\x30\x39";
	
	//将Speed转换成8个16进制字符
	CString  cmdSpeed;
	cmdSpeed.Format("%08X", Speed);
	//组成命令
	char  chCmd[128];
	memset(chCmd, 0x00, sizeof(chCmd));
	CString strcmd;
	strcmd = station +cmdstr + "\x02"+ cmdpra + cmdSpeed +"\x03";
	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 = "\x01" + 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,200))
		{
			_ret->code = FAIL;
			_ret->discription = "读取数据错误!";
			_ret->time = CTime::GetCurrentTime();
		}
		else
		{
			
			char   rbuf[128];
			memset(rbuf, 0x00, sizeof(rbuf));
			int rlen = 128;
			if(	SUCCESS == get_response((BYTE *)recbuf, ilen, (BYTE *)rbuf, rlen, _ret))
			{
				Speed = 0;
				for (int i = 1; i<8; i++)
				{
					if (0x40<rbuf[i]&&rbuf[i]<0x47)
						rbuf[i] = rbuf[i] - 7;
					Speed += (rbuf[i]-0x30)*pow(16, 7-i);
				}

				_ret->code = SUCCESS;
			}

		}
	}
	return _ret->code;
}

⌨️ 快捷键说明

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