1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > OneApiConnect通讯demo fins欧姆龙协议实现

OneApiConnect通讯demo fins欧姆龙协议实现

时间:2021-05-15 02:01:45

相关推荐

OneApiConnect通讯demo fins欧姆龙协议实现

每家PLC厂商都有自己的通讯协议,三菱有MC、倍福有ADS,然而没有统一性的接口协议。

为适应每一家通讯,每一家设备商、MES和工厂等都需要针对每款产品开发相应的通讯接口。

OneConnectAPI为实现统一的接口,去适配每一家厂商的协议。为中国工控行业快速发展而贡献,每一家公司都需要重新制造轮子,这是非常浪费时间和金钱,同时也不能保证稳定性以及持续的维护。

我们采取高效的多线程处理方案,保证极其高效的读写性能,对电脑性能要求极其低,一直进行读写操作,CPU使用率不超过1%(Atom E3940下测试)。

用户可以在一台工控机上进行对上百台的PLC主动读写操作,我们在光伏行业大量应用和测试过。

我们在半导体行业深耕多年,积累大量的经验,实现功能的同时,也需要保证极其严格的稳定性,晶圆生成设备7*24小时不能出任何故障。

下载地址软件及资料书www.secsgemc.om

下边 /secsgem/one-api-connect/tree/master/

/SECSGEM/Fins

#pragma once#include <string>#include "InterfaceExport.h"#include "ModuleDevelopH.h"// 欧姆龙Fins协议class CFins{public:CFins();virtual ~CFins();// 参数CResult SetIP(std::string pIP);// 设置地址CResult SetPort(int nPort);// 设置端口号CResult SetTimeout(int nTimeMs);// 设置超时// 读出CResult Read(std::string pAddr, char& pData); CResult Read(std::string pAddr, __int16& pData); CResult Read(std::string pAddr, __int32& pData); CResult Read(std::string pAddr, __int64& pData);CResult Read(std::string pAddr, char* pData, int nSize); CResult Read(std::string pAddr, __int16* pData, int nSize); CResult Read(std::string pAddr, __int32* pData, int nSize); CResult Read(std::string pAddr, __int64* pData, int nSize); // 写入CResult Write(std::string pAddr, char& pData); CResult Write(std::string pAddr, __int16& pData); CResult Write(std::string pAddr, __int32& pData); CResult Write(std::string pAddr, __int64& pData); CResult Write(std::string pAddr, char* pData, __int32 nSize); CResult Write(std::string pAddr, __int16* pData, __int32 nSize); CResult Write(std::string pAddr, __int32* pData, __int32 nSize); CResult Write(std::string pAddr, __int64* pData, __int32 nSize); private:CResult SetParament(std::string pName, std::string pValue); CResult SetParament(std::string pName, int nValue); private:CInterfaceExport* m_pFins;CMgrDllDelegate m_pLoadInterface;};

#include "stdafx.h"#include "FinsHandle.h"CFinsHandle::CFinsHandle(){m_bEstablishCommunicationByFins = false;m_nIpNode = 0;}// 重写数据接收,用于协议识别void CFinsHandle::OnDataRecv(char* pData, int nSize){if (nSize > 0){m_pRecvData.Append(pData, nSize);if (m_pRecvData.Size() >= FINS_TCP_HEAD_SIZE){FINS_TCP_HEAD pHead;pHead.SetData(m_pRecvData.GetString());int nAllSize = pHead.GetLength();if (m_pRecvData.Size() >= nAllSize){SetRecvComplete(nAllSize);}}}}// 重写数据接收,开始接收数据,用于协议识别void CFinsHandle::OnBeginRecv(){m_pRecvData.SetSize(0);}// 通讯关闭void CFinsHandle::OnCloseConnect(){m_bEstablishCommunicationByFins = false;}long CFinsHandle::ReadMemoryData(int nAddr, int nSize, FINS_DATA_TYPE::ENUM nType, __int16* pData){long nCode = 0;if(nCode = EstablishCommunicationByFins()){return nCode;}CMyString pSendData;// 获取发送内存int nAllSize;nAllSize = FINS_TCP_HEAD_SIZE;nAllSize += FINS_CONTROL_HEAD_SIZE;nAllSize += FINS_MEMORY_AREA_READ_SIZE; pSendData.SetSize(nAllSize);char* pBuff = pSendData.GetString();// 头部信息FINS_TCP_HEAD pHead;pHead.nCommand = FINS_TCP_CMD_DATA;pHead.SetLength(nAllSize);//长度pHead.GetData(pBuff);// control部分FINS_CONTROL_HEAD pControlHead;pControlHead.nDA1 = 0; pControlHead.nSA1 = m_nIpNode;pControlHead.nCmd1 = 0x01;pControlHead.nCmd2 = 0x01;pControlHead.GetData(pBuff + FINS_TCP_HEAD_SIZE);// 数据部分FINS_MEMORY_AREA_READ pMemory;pMemory.nAreaCode = nType;pMemory.nAddr = nAddr;pMemory.nBitNo = 0;pMemory.nLength = nSize;pMemory.GetData(pBuff + FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE);//// 发送数据CMyString pRecvData;nCode = SendSyncData(pSendData, pRecvData);if (nCode == 0){// 先判断答复数据的头数据是否正确if(nCode = CheckReplyDataIsError(pRecvData.GetString(), pRecvData.Size())){return nCode;}// 数据头FINS_TCP_HEAD pHeadReply;pHeadReply.SetData(pRecvData.GetString());// 答复长度要求int nMinSize = FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE + FINS_MEMORY_AREA_READ_FIX_R_SIZE + nSize * 2;if(pHeadReply.GetLength() < nMinSize){return FINS_REPLY_READ_DATA_TOO_SHORT;}else{// FINS协议部分FINS_CONTROL_HEAD pControlHeadReply;pControlHeadReply.SetData(pRecvData.GetString());if (pControlHeadReply.nCmd1 != pControlHead.nCmd1 ||pControlHeadReply.nCmd2 != pControlHead.nCmd2){// 命令不一致return FINS_REPLY_CMD_NO_IS_REQUST_CMD;}// 答复数据FINS_MEMORY_AREA_READ_REPLY pReplyData;pReplyData.SetData(pRecvData.GetString(), pRecvData.Size());if(pReplyData.nEndCode != 0){return FINS_REPLY_READ_DATA_FAIL;}// 拷贝数据int nReadByte = nSize * 2;if (pReplyData.GetDataBytsSize() == nReadByte){memcpy(pData, pReplyData.GetData(), nReadByte);}else{return FINS_REPLY_READ_DATA_TOO_SHORT;}}}return nCode;}long CFinsHandle::WriteMemoryData(int nAddr, int nSize, FINS_DATA_TYPE::ENUM nType, __int16* pData){long nCode = 0;if(nCode = EstablishCommunicationByFins()){return nCode;}CMyString pSendData;int nBytsSize = nSize * 2;// 获取发送内存int nAllSize;nAllSize = FINS_TCP_HEAD_SIZE;nAllSize += FINS_CONTROL_HEAD_SIZE;nAllSize += FINS_MEMORY_AREA_READ_SIZE; nAllSize += nBytsSize;pSendData.SetSize(nAllSize);char* pBuff = pSendData.GetString();// 头部信息FINS_TCP_HEAD pHead;pHead.nCommand = FINS_TCP_CMD_DATA;pHead.SetLength(nAllSize);//长度pHead.GetData(pBuff);// control部分FINS_CONTROL_HEAD pControlHead;pControlHead.nDA1 = 0; pControlHead.nSA1 = m_nIpNode;pControlHead.nCmd1 = 0x01;pControlHead.nCmd2 = 0x02;pControlHead.GetData(pBuff + FINS_TCP_HEAD_SIZE);// 数据部分FINS_MEMORY_AREA_WRITE pMemory;pMemory.nAreaCode = nType;pMemory.nAddr = nAddr;pMemory.nBitNo = 0;pMemory.nLength = nSize;pMemory.pData.Append((char*)pData, nBytsSize);pMemory.GetData(pBuff + FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE);//// 发送数据CMyString pRecvData;nCode = SendSyncData(pSendData, pRecvData);if (nCode == 0){// 先判断答复数据的头数据是否正确if(nCode = CheckReplyDataIsError(pRecvData.GetString(), pRecvData.Size())){return nCode;}// 数据头FINS_TCP_HEAD pHeadReply;pHeadReply.SetData(pRecvData.GetString());// 答复长度要求int nMinSize = FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE + FINS_MEMORY_AREA_WRITE_R_SIZE;if(pHeadReply.GetLength() < nMinSize){return FINS_REPLY_READ_DATA_TOO_SHORT;}else{// FINS协议部分FINS_CONTROL_HEAD pControlHeadReply;pControlHeadReply.SetData(pRecvData.GetString());if (pControlHeadReply.nCmd1 != pControlHead.nCmd1 ||pControlHeadReply.nCmd2 != pControlHead.nCmd2){// 命令不一致return FINS_REPLY_CMD_NO_IS_REQUST_CMD;}// 答复数据FINS_MEMORY_AREA_WRITE_REPLY pReplyData;pReplyData.SetData(pRecvData.GetString());if(pReplyData.nEndCode != 0){return FINS_REPLY_WRITE_DATA_FAIL;}}}return nCode;}// 获取fins节点地址long CFinsHandle::GetFinsNodeAddress(){return 0;}// 检查答复数据是否错误long CFinsHandle::CheckReplyDataIsError(char* pData, int nSize){if (nSize < FINS_TCP_HEAD_SIZE){// 小于最小要求数据return FINS_REPLY_DATA_TOO_SHORT;}// 消息错误FINS_TCP_HEAD pHeadReply;pHeadReply.SetData(pData);if (pHeadReply.nErrorCode){return FINS_REPLY_ERROR_BY_MESSAGE;}return 0;}// 建立通讯long CFinsHandle::EstablishCommunicationByFins(){if (m_bEstablishCommunicationByFins){// 已经建立通讯连接了return 0;}long nCode = 0;CMyString pSendData;// 获取发送内存int nAllSize;nAllSize = FINS_TCP_HEAD_SIZE;nAllSize += FINS_CONNECT_REQUST_SIZE;pSendData.SetSize(nAllSize);char* pBuff = pSendData.GetString();// 头部信息FINS_TCP_HEAD pHead;pHead.nCommand = FINS_TCP_CMD_CONNECT_REQUST;pHead.SetLength(nAllSize);//长度pHead.GetData(pBuff);// IP地址FINS_CONNECT_REQUST pConnectRequst;pConnectRequst.GetData(pBuff + FINS_TCP_HEAD_SIZE);// 发送数据CMyString pRecvData;if(nCode = SendSyncData(pSendData, pRecvData)){return nCode;}// 处理返回值FINS_TCP_HEAD pHeadReply;pHeadReply.SetData(pRecvData.GetString());// 检查头信息if (pHeadReply.nErrorCode == 0 &&pHeadReply.nCommand == FINS_TCP_CMD_CONNECT_RESPONSE){// 提取 IP Node信息if (pHeadReply.GetLength() == FINS_TCP_HEAD_SIZE + FINS_CONNECT_RESPONS_SIZE){// 提取FINS_CONNECT_RESPONSE pConnectResponse;pConnectResponse.SetData(pRecvData.GetString());m_nIpNode = pConnectResponse.pClientAddrss[3];// 建立通讯成功m_bEstablishCommunicationByFins = true;return 0;}}return FINS_REQUST_CONNECT_FAIL;}

#pragma once

// 用于TCP/IP通讯

class CCommunication

{

public:

CCommunication();

virtual ~CCommunication();

// 释放

void Release();

void SetTimeout(int nMs);// 设置超时

void SetMode(bool bLongConnect); // 长连接或者短连接模式

void SetTcpIP(const char* pIP); // socket参数

void SetTcpPort(int nPort);// socket参数

int GetTimeout();

long SendSyncData(CMyString pSendData, CMyString& pRecvData); // 数据发读

void Disconnect(); // 断开通讯

protected:

// 数据接收

void SetRecvComplete(int nSize); // 告诉通讯,数据接收完成

virtual void OnBeginRecv(); // 重写数据接收,开始接收数据,用于协议识别

virtual void OnDataRecv(char* pData, int nSize) = 0; // 重写数据接收,用于协议识别

virtual void OnCloseConnect(); // 通讯关闭

private:

long Connect(); // TCP连接

void CloseConnect(); // TCP关闭连接

void InitSockWSA();

void ReleaseSockWSA();

// 接收数据线程

void CreateRecvThread(); // 创建接收线程

void ExitRecvThread(); // 退出接收线程

static void RunRecvThread(void* lp);

void RecvHandle();

bool IsExitThread();

void OneRecvData(); // 一次接收数据

void StartRecvData(); // 开始接收数据

void StopRecvData();

// 数据读取,从缓存内读取

long RecvData(CMyString& pRecvData);

private:

bool m_bLongConnect; // 长连接

int m_nRecvTimeout; // 接收超时

// socket

SOCKET m_hSock;

struct sockaddr_in m_pSA;

vCritical m_syncLock; // 每次只能单个tcp读写

vCritical m_syncLockTcp; // soekct操作

HANDLE m_hRecvTimeoutEvent; // 接收线程超时

HANDLE m_hRecvExitFinish; // 定时器线程退出完毕

HANDLE m_hRecvExit; // 接收退出

HANDLE m_hRecvStartData; // 开始接收数据

CMyString m_pRecvData; // 接收到的数据

long m_nRecvCode; // 读取错误代码

// 临时缓

int m_nSize;

int m_nRecvSize;

char m_pBuff[200];

};

#pragma once

#include "Communication.h"

class CFinsHandle : public CCommunication

{

public:

CFinsHandle();

long ReadMemoryData(int nAddr, int nSize, FINS_DATA_TYPE::ENUM nType, __int16* pData);

long WriteMemoryData(int nAddr, int nSize, FINS_DATA_TYPE::ENUM nType, __int16* pData);

private:

virtual void OnBeginRecv(); // 重写数据接收,开始接收数据

virtual void OnDataRecv(char* pData, int nSize); // 重写数据接收,用于协议识别

virtual void OnCloseConnect();// 通讯关闭

// 检查答复数据是否错误

long CheckReplyDataIsError(char* pData, int nSize); // 检查答复数据是否错误

long GetFinsNodeAddress(); // 获取fins节点地址

long EstablishCommunicationByFins(); // 建立Fins通讯

private:

CMyString m_pRecvData;

bool m_bEstablishCommunicationByFins; // 与Fins建立通讯

int m_nIpNode; // IP节点

};

#pragma once

#include "Export/InterfaceExport.h"

#include "FinsHandle.h"

class CFinsReadWrite : public CInterfaceExport

{

public:

// 参数

virtual CResult SetParament(const char* pName, const char* pValue);

// 初始化模块

virtual CResult Connect();

virtual CResult Disconnect();

// 释放

virtual void Release();

public:

// 读出

virtual CResult Read(const char* pAddr, char* pData, __int32 size, char* pCtrlData);

virtual CResult Read(const char* pAddr, __int16* pData, __int32 size, char* pCtrlData);

virtual CResult Read(const char* pAddr, __int32* pData, __int32 size, char* pCtrlData);

virtual CResult Read(const char* pAddr, __int64* pData, __int32 size, char* pCtrlData);

// 写入

virtual CResult Write(const char* pAddr, char* pData, __int32 size, char* pCtrlData);

virtual CResult Write(const char* pAddr, __int16* pData, __int32 size, char* pCtrlData);

virtual CResult Write(const char* pAddr, __int32* pData, __int32 size, char* pCtrlData);

virtual CResult Write(const char* pAddr, __int64* pData, __int32 size, char* pCtrlData);

private:

long ReadData(int nAddr, __int16* pData, int nSize, int nDataType); // 读取2字节一次

long WriteData(int nAddr, __int16* pData, int nSize, int nDataType); // 读取2字节一次

void GetDataTypeAndAddr(string pAddr, int& nDataType, int& nAddr); // 获取数据地址

int GetDataArea(string pArea); // 获取数据区

private:

CFinsHandle m_pHandle;

};

#include "stdafx.h"

#include "Communication.h"

CCommunication::CCommunication()

{

m_nRecvTimeout = 5000;

m_bLongConnect = true;

m_hSock = INVALID_SOCKET;

InitSockWSA();

memset(&m_pSA, 0, sizeof(struct sockaddr_in));

m_hRecvExit = CreateEvent(NULL, TRUE, FALSE, NULL);

m_hRecvExitFinish = CreateEvent(NULL, TRUE, FALSE, NULL);

m_hRecvTimeoutEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

m_hRecvStartData = CreateEvent(NULL, TRUE, FALSE, NULL);

CreateRecvThread();

}

CCommunication::~CCommunication()

{

ExitRecvThread();

ReleaseSockWSA();

CloseHandle(m_hRecvExit);

CloseHandle(m_hRecvExitFinish);

CloseHandle(m_hRecvTimeoutEvent);

CloseHandle(m_hRecvStartData);

}

void CCommunication::InitSockWSA()

{

// 必须的

WSADATA wsaData;

if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0)

{

}

}

void CCommunication::ReleaseSockWSA()

{

// 必须的

if(WSACleanup() != 0)

{

}

}

// 释放

void CCommunication::Release()

{

}

// TCP连接

long CCommunication::Connect()

{

if(m_hSock == INVALID_SOCKET)

{

m_hSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if(m_hSock != INVALID_SOCKET)

{

if(connect(m_hSock, (struct sockaddr*)&m_pSA, sizeof(m_pSA)) < 0)

{

closesocket(m_hSock);

m_hSock = INVALID_SOCKET;

return FINS_SOCKET_CONNECT_FAIL;

}

}

else

{

return FINS_SOCKET_CREATE_FAIL;

}

}

return 0;

}

// TCP关闭连接

void CCommunication::CloseConnect()

{

vLocker lock(&m_syncLockTcp);

if (m_hSock != INVALID_SOCKET)

{

shutdown(m_hSock, 2);

closesocket(m_hSock);

m_hSock = INVALID_SOCKET;

OnCloseConnect();

}

}

// 设置超时

void CCommunication::SetTimeout(__int32 nMs)

{

if(nMs < 100)

{

nMs = 100;

}

m_nRecvTimeout = nMs;

}

int CCommunication::GetTimeout()

{

return m_nRecvTimeout;

}

// 长连接或者短连接模式

void CCommunication::SetMode(bool bLongConnect)

{

m_bLongConnect = bLongConnect;

}

// socket参数

void CCommunication::SetTcpIP(const char* pIP)

{

m_pSA.sin_family = AF_INET;

m_pSA.sin_addr.s_addr = inet_addr(pIP);

}

// socket参数

void CCommunication::SetTcpPort(__int32 nPort)

{

m_pSA.sin_family = AF_INET;

m_pSA.sin_port = htons(nPort);

}

// 数据发读

long CCommunication::SendSyncData(CMyString pSendData, CMyString& pRecvData)

{

vLocker lock(&m_syncLock);

long nCode = Connect();

if(nCode != 0)

{

return nCode;

}

// 清空原来的数据

m_pRecvData.SetSize(0);

// 发送数据

int res = send(m_hSock, pSendData.GetString(), pSendData.Size(), 0);

if(res == SOCKET_ERROR)

{

CloseConnect();

return FINS_SEND_FAIL;

}

// 数据读取

nCode = RecvData(pRecvData);

// 短连接每次都关闭

if(!m_bLongConnect)

{

CloseConnect();

}

return nCode;

}

// 数据读取

// 带超时处理

long CCommunication::RecvData(CMyString& pRecvData)

{

long nCode = 0;

StartRecvData();

// 等待接收

ResetEvent(m_hRecvTimeoutEvent);

DWORD rs = WaitForSingleObject(m_hRecvTimeoutEvent, m_nRecvTimeout);

// 成功返回值

if (rs == WAIT_OBJECT_0)

{

pRecvData = m_pRecvData;

}

// 超时等其他错误

else

{

StopRecvData();

CloseConnect();

nCode = FINS_RECV_WAIT_TIMEOUT;

}

return nCode;

}

// 创建接收线程

//

void CCommunication::CreateRecvThread()

{

ResetEvent(m_hRecvExitFinish);

_beginthread(RunRecvThread, 0, this);

}

// 退出接收线程

//

void CCommunication::ExitRecvThread()

{

CloseConnect();

SetEvent(m_hRecvExit);

SetEvent(m_hRecvStartData);

WaitForSingleObject(m_hRecvExitFinish, INFINITE);

}

// 定时器线程

void CCommunication::RunRecvThread(void* lp)

{

CCommunication* pMC = (CCommunication*)lp;

pMC->RecvHandle();

SetEvent(pMC->m_hRecvExitFinish); // 处理完毕

}

// 定时器

void CCommunication::RecvHandle()

{

while (!IsExitThread())

{

WaitForSingleObject(m_hRecvStartData, INFINITE);

if (IsExitThread())

{

break;

}

OneRecvData();

}

}

// 一次接收数据

void CCommunication::OneRecvData()

{

m_nSize = 200;

m_nRecvSize = recv(m_hSock, m_pBuff, m_nSize, 0);

if(m_nRecvSize == SOCKET_ERROR)

{

CloseConnect();

m_nRecvCode = FINS_SOCKET_CONNECT_ERR;

}

else

{

m_pRecvData.Append(m_pBuff, m_nRecvSize);

m_nRecvCode = 0;

OnDataRecv(m_pBuff, m_nRecvSize);

}

}

// 告诉通讯,数据接收完成

void CCommunication::SetRecvComplete(int nSize)

{

ResetEvent(m_hRecvStartData); // 复位接收

SetEvent(m_hRecvTimeoutEvent); // 接收成功

}

// 重写数据接收,开始接收数据,用于协议识别

void CCommunication::OnBeginRecv()

{

}

// 通讯关闭

void CCommunication::OnCloseConnect()

{

}

bool CCommunication::IsExitThread()

{

if(WaitForSingleObject(m_hRecvExit, 0) == WAIT_OBJECT_0)

{

return true;

}

return false;

}

// 开始接收数据

void CCommunication::StartRecvData()

{

OnBeginRecv();

SetEvent(m_hRecvStartData);

}

// 停止接收数据

void CCommunication::StopRecvData()

{

ResetEvent(m_hRecvStartData);

}

// 断开通讯

void CCommunication::Disconnect()

{

}

#include "stdafx.h"

#include "FinsReadWrite.h"

// 参数

CResult CFinsReadWrite::SetParament(const char* pName, const char* pValue)

{

if(pName == nullptr ||

pValue == nullptr)

{

return CResult(FINS_PARAM_POINT_ENTPY, "FINS 参数指针为空");

}

string pNameString = pName;

if (pNameString == "IP")

{

m_pHandle.SetTcpIP(pValue);

}

else if (pNameString == "PORT")

{

int nPort = ::atoi(pValue);

m_pHandle.SetTcpPort(nPort);

}

else if (pNameString == "TIMEOUT")

{

int nTimerOut = ::atoi(pValue);

m_pHandle.SetTimeout(nTimerOut);

}

return CResult(0);

}

// 初始化模块

CResult CFinsReadWrite::Connect()

{

return CResult(0);

}

CResult CFinsReadWrite::Disconnect()

{

return CResult(0);

}

// 释放

void CFinsReadWrite::Release()

{

delete this;

}

// 1字节

CResult CFinsReadWrite::Read(const char* pAddr, char* pData, __int32 nSize, char* pCtrlData)

{

if (pAddr == nullptr ||

pData == nullptr ||

pCtrlData == nullptr)

{

return CResult(FINS_PARAM_POINT_ENTPY, "FINS 参数指针为空");

}

int nDataType; // 数据类型

int nAddr; // 数据地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

long nCode = 0;

if(nSize % 2)

{

// 奇数处理

int nReadSize = nSize;

nReadSize++;

__int16* pReadData = (__int16*)malloc(nReadSize);

if (pReadData == nullptr)

{

return FINS_MALLOC_FAIL;

}

// 读取数据

nCode = ReadData(nAddr, pReadData, nReadSize / 2, nDataType);

if(nCode == 0)

{

memcpy(pData, pReadData, nSize);

}

free(pReadData);

}

else

{

nCode = ReadData(nAddr, (__int16*)pData, nSize / 2, nDataType);

}

return nCode;

}

// 2字节

CResult CFinsReadWrite::Read(const char* pAddr, __int16* pData, __int32 nSize, char* pCtrlData)

{

long nCode = 0;

int nDataType; // 数据类型

int nAddr; // 数据地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

nCode = ReadData(nAddr, pData, nSize, nDataType);

return CResult(nCode);

}

// 4字节

CResult CFinsReadWrite::Read(const char* pAddr, __int32* pData, __int32 nSize, char* pCtrlData)

{

long nCode = 0;

int nDataType; // 数据类型

int nAddr; // 数据地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

nCode = ReadData(nAddr, (__int16*)pData, nSize * 2, nDataType);

return CResult(nCode);

}

// 8字节

CResult CFinsReadWrite::Read(const char* pAddr, __int64* pData, __int32 nSize, char* pCtrlData)

{

long nCode = 0;

int nDataType; // 数据类型

int nAddr; // 数据地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

nCode = ReadData(nAddr, (__int16*)pData, nSize * 2, nDataType);

return CResult(nCode);

}

// 读取2字节一次

long CFinsReadWrite::ReadData(int nAddr, __int16* pData, int nSize, int nDataType)

{

FINS_DATA_TYPE::ENUM nType = (FINS_DATA_TYPE::ENUM)nDataType;

switch(nType)

{

case FINS_DATA_TYPE::DM:

{

return m_pHandle.ReadMemoryData(nAddr, nSize, nType, pData);

}

break;

}

return FINS_NOT_DATA_AREA;

}

// 1字节

CResult CFinsReadWrite::Write(const char* pAddr, char* pData, __int32 nSize, char* pCtrlData)

{

if (pAddr == nullptr ||

pData == nullptr ||

pCtrlData == nullptr)

{

return CResult(FINS_PARAM_POINT_ENTPY, "FINS 参数指针为空");

}

long nCode = 0;

int nDataType; // 数据类型

int nAddr; // 数据地址

// 获取PLC区域和地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

if(nSize % 2)

{

// 奇数处理

int nReadSize = nSize;

nReadSize++;

__int8* pReadData = (__int8*)malloc(nReadSize);

if (pReadData == nullptr)

{

return FINS_MALLOC_FAIL;

}

memset(pReadData, 0, nReadSize);

memcpy(pReadData, pData, nSize);

// 读取数据

nCode = WriteData(nAddr, (__int16*)pReadData, nReadSize / 2, nDataType);

free(pReadData);

}

else

{

nCode = WriteData(nAddr, (__int16*)pData, nSize / 2, nDataType);

}

return nCode;

}

// 2字节

CResult CFinsReadWrite::Write(const char* pAddr, __int16* pData, __int32 nSize, char* pCtrlData)

{

if (pAddr == nullptr ||

pData == nullptr ||

pCtrlData == nullptr)

{

return CResult(FINS_PARAM_POINT_ENTPY, "FINS 参数指针为空");

}

long nCode = 0;

int nDataType; // 数据类型

int nAddr; // 数据地址

// 获取PLC区域和地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

nCode = WriteData(nAddr, pData, nSize, nDataType);

return nCode;

}

// 4字节

CResult CFinsReadWrite::Write(const char* pAddr, __int32* pData, __int32 nSize, char* pCtrlData)

{

if (pAddr == nullptr ||

pData == nullptr ||

pCtrlData == nullptr)

{

return CResult(FINS_PARAM_POINT_ENTPY, "FINS 参数指针为空");

}

long nCode = 0;

int nDataType; // 数据类型

int nAddr; // 数据地址

// 获取PLC区域和地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

nCode = WriteData(nAddr, (__int16*)pData, nSize * 2, nDataType);

return nCode;

}

// 8字节

CResult CFinsReadWrite::Write(const char* pAddr, __int64* pData, __int32 nSize, char* pCtrlData)

{

if (pAddr == nullptr ||

pData == nullptr ||

pCtrlData == nullptr)

{

return CResult(FINS_PARAM_POINT_ENTPY, "FINS 参数指针为空");

}

long nCode = 0;

int nDataType; // 数据类型

int nAddr; // 数据地址

// 获取PLC区域和地址

GetDataTypeAndAddr(pAddr, nDataType, nAddr);

nCode = WriteData(nAddr, (__int16*)pData, nSize * 4, nDataType);

return nCode;

}

// 读取2字节一次

long CFinsReadWrite::WriteData(int nAddr, __int16* pData, int nSize, int nDataType)

{

FINS_DATA_TYPE::ENUM nType = (FINS_DATA_TYPE::ENUM)nDataType;

switch(nType)

{

case FINS_DATA_TYPE::DM:

{

return m_pHandle.WriteMemoryData(nAddr, nSize, nType, pData);

}

break;

}

return FINS_NOT_DATA_AREA;

}

// 获取数据地址

void CFinsReadWrite::GetDataTypeAndAddr(string pAddr, int& nDataType, int& nAddr)

{

unsigned int i = 0;

for (; i < pAddr.size(); i++)

{

if(pAddr[i] >= '0' && pAddr[i] <= '9')

{

break;

}

}

// 数据类型

string pType = pAddr.substr(0, i);

nDataType = GetDataArea(pType);

// 数据地址

string pStartAddr = pAddr.substr(i, pAddr.size() - i);

nAddr = ::atol(pStartAddr.c_str());

}

// 获取数据区

int CFinsReadWrite::GetDataArea(string pArea)

{

int nDataType = 0;

if (pArea == "DM") { nDataType = FINS_DATA_TYPE::DM; }

else if (pArea == "dm") { nDataType = FINS_DATA_TYPE::DM; }

else { nDataType = FINS_DATA_TYPE::ERR; }

return nDataType;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。