📄 ofxplcdev.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 + -