| SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
@@ -483,15 +483,33 @@ return nRet; } // 计算需要读取的字节大小(按位对齐为字节数) if (nDevNo % 8 != 0) { nRet = -2; UpdateLastError(nRet); return nRet; } const short nDevType = CalculateDeviceType(station, enDevType); const auto nSize = static_cast<short>((nBitCount + 7) / 8); // 向上取整 std::vector<short> vecTempBuffer((nSize + 1) / 2, 0); // 临时缓冲区,字节对齐 const auto nSize = static_cast<short>((static_cast<int>(nBitCount) + 15) / 16); // 计算需要读取的字数量(向上取整) std::vector<short> vecTempBuffer(nSize, 0); nRet = ReadData(station, nDevType, nDevNo, nSize, vecTempBuffer); if (nRet == 0) { std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 ConvertShortToUint8(vecTempBuffer, vecData); vecData.clear(); // 将字数据解析为位数据 for (short nIdx = 0; nIdx < nSize; ++nIdx) { const short nCurrentValue = vecTempBuffer[nIdx]; // 遍历当前 short 中的每一位 for (int bitIdx = 0; bitIdx < 16; ++bitIdx) { bool bBit = (nCurrentValue & (1 << bitIdx)) != 0; vecData.push_back(bBit); if (vecData.size() >= nBitCount) { return nRet; // 如果已经读取完所需的位数,提前退出 } } } } return nRet; @@ -573,22 +591,35 @@ // 写位数据 int CPerformanceMelsec::WriteBitData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const BitContainer& vecData) { // 验证站点参数和数据有效性 const int nRet = ValidateStationAndData(station, vecData); int nRet = ValidateStationAndData(station, vecData); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // 计算需要写入的字节数(位数据需要按 8 位对齐为字节数) const short nDevType = CalculateDeviceType(station, enDevType); const auto nSize = static_cast<short>((vecData.size() + 7) / 8); std::vector<short> vecBuffer(vecData.size() / 2 + vecData.size() % 2, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 ConvertUint8ToShort(vecData, vecBuffer); if (nDevNo % 8 != 0) { nRet = -2; UpdateLastError(nRet); return nRet; } return WriteData(station, nDevType, nDevNo, nSize, vecBuffer.data()); const short nDevType = CalculateDeviceType(station, enDevType); const auto nSize = static_cast<short>((static_cast<int>(vecData.size()) + 15) / 16); // 计算需要写入的字数量(向上取整) // 准备临时缓冲区来存储转换后的 16 位数据 std::vector<short> vecTempBuffer(nSize, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 // 将位数据按字打包到临时缓冲区 for (int i = 0; i < vecData.size(); ++i) { if (vecData[i]) { // 使用 & 0xFFFF 保证不会超过 16 位,防止溢出 vecTempBuffer[i / 16] |= static_cast<short>((1 << (i % 16)) & 0xFFFF); } } } return WriteData(station, nDevType, nDevNo, nSize, vecTempBuffer.data()); } // 写字数据 SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h
@@ -28,7 +28,7 @@ #define CC_LINK_IE_FIELD_CHANNEL(x) (180 + (x)) // x 范围:1~4 #define CC_LINK_IE_TSN_CHANNEL(x) (280 + (x)) // x 范围:1~4 // 自定义错误码 // 自定义错误码 #define ERROR_CODE_UNKNOWN 0x00010000 // 未知 #define ERROR_CODE_NOT_CONNECTED 0x00020000 // 未连接 #define ERROR_CODE_INVALID_PARAM 0x00030000 // 参数无效 @@ -130,7 +130,7 @@ enum class DataType { BIT = 1, // 位 (1位) WORD = 2, // 字 (16位) DWORD =4 // 双字 (32位) DWORD = 4 // 双字 (32位) }; // 控制代码 @@ -180,22 +180,22 @@ * 1~239 表示普通网络号 **/ /* * [Station No.] * MELSECNET/H:1~64 表示其他站点,255 表示本站 * CC-Link 系列网络的范围类似,区别在于站号的取值范围 * MELSECNET/H : 1~64(Other stations),255(Own station) * CC-Link : 0~63(Other stations),255(Own station) * CC-Link IE Controller : 1~120(Other stations),255(Own station) * CC-Link IE Field : 0~120(Other stations),255(Own station) * CC-Link IE TSN : 0~120(Other stations),255(Own station) **/ /* * [Station No.] * MELSECNET/H:1~64 表示其他站点,255 表示本站 * CC-Link 系列网络的范围类似,区别在于站号的取值范围 * MELSECNET/H : 1~64(Other stations),255(Own station) * CC-Link : 0~63(Other stations),255(Own station) * CC-Link IE Controller : 1~120(Other stations),255(Own station) * CC-Link IE Field : 0~120(Other stations),255(Own station) * CC-Link IE TSN : 0~120(Other stations),255(Own station) **/ /* * 高 8 位(网络号): 指定设备所属的网络 * 低 8 位(站点号): 指定设备在网络中的编号 * 用一个参数传递设备的网络号和站点号时: nSt = station.nStNo | ((station.nNetNo << 8) & 0xFF00); **/ /* * 高 8 位(网络号): 指定设备所属的网络 * 低 8 位(站点号): 指定设备在网络中的编号 * 用一个参数传递设备的网络号和站点号时: nSt = station.nStNo | ((station.nNetNo << 8) & 0xFF00); **/ short nNetNo = 0; // 网络编号:PLC所连接的网络编号,0表示默认网络 short nStNo = 255; // 站点编号:指定与PLC连接的站点编号,255通常表示广播或所有站点 @@ -211,13 +211,13 @@ // 重载 < 运算符(用于排序或比较,通常用于 map 或 set 中作为 key) bool operator<(const StationIdentifier& other) const { return std::tie(nNetNo, nStNo) < std::tie(other.nNetNo, other.nStNo); std::tie(other.nNetNo, other.nStNo); } // 重载 == 运算符(用于相等比较) bool operator==(const StationIdentifier& other) const { return std::tie(nNetNo, nStNo) == std::tie(other.nNetNo, other.nStNo); std::tie(other.nNetNo, other.nStNo); } // 重载 = 运算符(用于赋值) @@ -330,7 +330,7 @@ } }; using BitContainer = std::vector<uint8_t>; // 每个元素存储 8 个位 using BitContainer = std::vector<bool>; // 每个元素存储 1 位 using WordContainer = std::vector<uint16_t>; // 每个元素存储 16 位 using DWordContainer = std::vector<uint32_t>; // 每个元素存储 32 位 @@ -435,7 +435,7 @@ // 容器转换 static void ConvertCharToShort(const std::vector<char>& vecChar, std::vector<short>& vecShort); static void ConvertShortToChar(const std::vector<short>& vecShort, std::vector<char>&vecChar); static void ConvertShortToChar(const std::vector<short>& vecShort, std::vector<char>& vecChar); static void ConvertUint8ToShort(const std::vector<uint8_t>& vecUint8, std::vector<short>& vecShort); static void ConvertShortToUint8(const std::vector<short>& vecShort, std::vector<uint8_t>& vecUint8); static void ConvertUint32ToShort(const std::vector<uint32_t>& vecUint32, std::vector<short>& vecShort);