63 lines
2.2 KiB
C#
63 lines
2.2 KiB
C#
using LFP_Manager.Utils;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace LFP_Manager.Function
|
||
{
|
||
internal class CsModbusFunction
|
||
{
|
||
static public byte[] MakeWriteRegisterData(ushort devId, ushort writeAddr, short[] writeData)
|
||
{
|
||
if (writeData == null || writeData.Length == 0)
|
||
return Array.Empty<byte>();
|
||
|
||
// 부호 확장 없이 캐스팅 (2’s complement 그대로 0..65535 범위로 들어갑니다)
|
||
Span<ushort> regs = writeData.Length <= 16
|
||
? stackalloc ushort[writeData.Length]
|
||
: new ushort[writeData.Length]; // 길면 힙 사용
|
||
|
||
for (int k = 0; k < writeData.Length; k++)
|
||
regs[k] = unchecked((ushort)writeData[k]);
|
||
|
||
return MakeWriteRegisterData(devId, writeAddr, regs);
|
||
}
|
||
static private byte[] MakeWriteRegisterData(ushort devId, ushort writeAddr, ReadOnlySpan<ushort> writeData)
|
||
{
|
||
if (writeData.Length <= 0)
|
||
return Array.Empty<byte>();
|
||
|
||
const byte Func = 0x10; // PRESET_MULTI_REG
|
||
int regCount = writeData.Length;
|
||
int payloadLen = 7 + regCount * 2; // CRC 제외 길이
|
||
byte[] frame = new byte[payloadLen + 2];
|
||
|
||
int i = 0;
|
||
frame[i++] = (byte)devId; // Device ID
|
||
frame[i++] = Func; // Function Code (0x10)
|
||
frame[i++] = (byte)(writeAddr >> 8); // Addr Hi
|
||
frame[i++] = (byte)writeAddr; // Addr Lo
|
||
frame[i++] = (byte)(regCount >> 8); // Count Hi
|
||
frame[i++] = (byte)regCount; // Count Lo
|
||
frame[i++] = (byte)(regCount * 2); // ByteCount
|
||
|
||
// 데이터: 각 레지스터를 Hi → Lo 바이트로
|
||
for (int j = 0; j < regCount; j++)
|
||
{
|
||
ushort v = writeData[j];
|
||
frame[i++] = (byte)(v >> 8);
|
||
frame[i++] = (byte)v;
|
||
}
|
||
|
||
// CRC (CRCL → CRCH) 부착
|
||
if (!CsCRC16.TryAppendCrcLowHigh(frame, payloadLen, 0))
|
||
return Array.Empty<byte>();
|
||
|
||
return frame;
|
||
}
|
||
|
||
}
|
||
}
|