| | |
| | | return nRet; |
| | | } |
| | | |
| | | if (nDevNo % 8 != 0) { |
| | | UpdateLastError(ERROR_CODE_INVALID_PARAM); |
| | | return ERROR_CODE_INVALID_PARAM; |
| | | } |
| | | |
| | | const short nDevType = CalculateDeviceType(station, enDevType); |
| | | const long nWordCount = (nBitCount + 15) / 16; |
| | | const long nByteSize = nWordCount * sizeof(short); |
| | | |
| | | // === 自动对齐到起始字 === |
| | | long nWordAlignedStartBit = nDevNo / 16 * 16; |
| | | long nBitOffset = nDevNo - nWordAlignedStartBit; |
| | | long nTotalBits = nBitOffset + nBitCount; |
| | | long nWordCount = (nTotalBits + 15) / 16; |
| | | long nByteSize = nWordCount * sizeof(short); |
| | | |
| | | std::vector<char> vecRaw; |
| | | nRet = ReadDataEx(station, nDevType, nDevNo, nByteSize, vecRaw); |
| | | nRet = ReadDataEx(station, nDevType, nWordAlignedStartBit, nByteSize, vecRaw); |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | | return nRet; |
| | | } |
| | | |
| | |
| | | for (long i = 0; i < nWordCount; ++i) { |
| | | short word = static_cast<unsigned char>(vecRaw[i * 2]) | |
| | | (static_cast<unsigned char>(vecRaw[i * 2 + 1]) << 8); |
| | | |
| | | for (int j = 0; j < 16; ++j) { |
| | | long bitIndex = i * 16 + j; |
| | | if (bitIndex >= nBitOffset && vecData.size() < static_cast<size_t>(nBitCount)) { |
| | | vecData.push_back((word & (1 << j)) != 0); |
| | | if (vecData.size() >= static_cast<size_t>(nBitCount)) { |
| | | return 0; |
| | | } |
| | | } |
| | | } |
| | |
| | | return nRet; |
| | | } |
| | | |
| | | if (nDevNo % 8 != 0) { |
| | | UpdateLastError(ERROR_CODE_INVALID_PARAM); |
| | | return ERROR_CODE_INVALID_PARAM; |
| | | } |
| | | |
| | | const short nDevType = CalculateDeviceType(station, enDevType); |
| | | const size_t nWordCount = (vecData.size() + 15) / 16; |
| | | |
| | | // === 1. 自动对齐起始地址 === |
| | | long nWordAlignedStartBit = nDevNo / 16 * 16; |
| | | long nBitOffset = nDevNo - nWordAlignedStartBit; |
| | | long nTotalBits = nBitOffset + static_cast<long>(vecData.size()); |
| | | size_t nWordCount = (nTotalBits + 15) / 16; |
| | | |
| | | // === 2. 先读取原始值以支持非对齐覆盖 === |
| | | std::vector<char> vecRaw; |
| | | nRet = ReadDataEx(station, nDevType, nWordAlignedStartBit, static_cast<long>(nWordCount * sizeof(short)), vecRaw); |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | | return nRet; |
| | | } |
| | | |
| | | // === 3. 合并新数据 === |
| | | std::vector<short> vecWordBuffer(nWordCount, 0); |
| | | for (size_t i = 0; i < nWordCount; ++i) { |
| | | vecWordBuffer[i] = static_cast<unsigned char>(vecRaw[i * 2]) | (static_cast<unsigned char>(vecRaw[i * 2 + 1]) << 8); |
| | | } |
| | | |
| | | for (size_t i = 0; i < vecData.size(); ++i) { |
| | | size_t bitIndex = nBitOffset + i; |
| | | size_t wordIdx = bitIndex / 16; |
| | | size_t bitPos = bitIndex % 16; |
| | | if (vecData[i]) { |
| | | vecWordBuffer[i / 16] |= (1 << (i % 16)); |
| | | vecWordBuffer[wordIdx] |= (1 << bitPos); |
| | | } |
| | | else { |
| | | vecWordBuffer[wordIdx] &= ~(1 << bitPos); |
| | | } |
| | | } |
| | | |
| | | // 转换 short -> char |
| | | std::vector<char> vecByteBuffer; |
| | | vecByteBuffer.resize(nWordCount * sizeof(short)); |
| | | // === 4. 转为字节流写入 === |
| | | std::vector<char> vecByteBuffer(nWordCount * 2); |
| | | for (size_t i = 0; i < nWordCount; ++i) { |
| | | vecByteBuffer[i * 2] = static_cast<char>(vecWordBuffer[i] & 0xFF); |
| | | vecByteBuffer[i * 2 + 1] = static_cast<char>((vecWordBuffer[i] >> 8) & 0xFF); |
| | | } |
| | | |
| | | return WriteDataEx(station, nDevType, nDevNo, vecByteBuffer); |
| | | return WriteDataEx(station, nDevType, nWordAlignedStartBit, vecByteBuffer); |
| | | } |
| | | |
| | | // 扩展写字数据 |
| | |
| | | } |
| | | |
| | | // 扩展位软元件设置 |
| | | long CPerformanceMelsec::SetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) { |
| | | long CPerformanceMelsec::SetBitDeviceEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo) { |
| | | std::lock_guard<std::mutex> lock(m_mtx); |
| | | |
| | | // 检查参数有效性 |
| | |
| | | return nRet; |
| | | } |
| | | |
| | | long nDevType = static_cast<long>(enDevType); |
| | | nRet = mdDevSetEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo); |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | |
| | | } |
| | | |
| | | // 扩展位软元件复位 |
| | | long CPerformanceMelsec::ResetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) { |
| | | long CPerformanceMelsec::ResetBitDeviceEx(const StationIdentifier& station, DeviceType enDevType, long nDevNo) { |
| | | std::lock_guard<std::mutex> lock(m_mtx); |
| | | |
| | | // 检查参数有效性 |
| | |
| | | return nRet; |
| | | } |
| | | |
| | | long nDevType = static_cast<long>(enDevType); |
| | | nRet = mdDevRstEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo); |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |