From 46996b55fed671525f1aaf01a29c8aa73662be9e Mon Sep 17 00:00:00 2001
From: darker <mr.darker@163.com>
Date: 星期六, 15 二月 2025 17:13:17 +0800
Subject: [PATCH] 1. 修复位读写,位读写的起始地址需要是8的倍数

---
 SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h   |   42 ++++++++++----------
 SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp |   59 ++++++++++++++++++++++-------
 2 files changed, 66 insertions(+), 35 deletions(-)

diff --git a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp b/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
index 23c31e8..61f9245 100644
--- a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
+++ b/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();
+
+        // 灏嗗瓧鏁版嵁瑙f瀽涓轰綅鏁版嵁
+        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());
 }
 
 // 鍐欏瓧鏁版嵁
diff --git a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h b/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h
index 903ca41..60dea51 100644
--- a/SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h
+++ b/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浣�)
 };
 
 // 鎺у埗浠g爜
@@ -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;    // 缃戠粶缂栧彿锛歅LC鎵�杩炴帴鐨勭綉缁滅紪鍙凤紝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);

--
Gitblit v1.9.3