写单线圈
cs
if (flag == 5)
{
List<byte> datas = new List<byte>();
datas.Add(0x01);
datas.Add(0x05);
ushort addr = 11;// 起始地址
datas.Add((byte)(addr / 256));
datas.Add((byte)(addr % 256));
datas.Add(0x00);// 表示置为off
datas.Add(0x00);
datas = CRC16(datas);// Modbus
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
// 发送读取请求报文
serialPort.Write(datas.ToArray(), 0, datas.Count);
}
static List<byte> CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
if (value == null || !value.Any())
throw new ArgumentException("");
//运算
ushort crc = crcInit;
for (int i = 0; i < value.Count; i++)
{
crc = (ushort)(crc ^ (value[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
List<byte> buffer = new List<byte>();
buffer.AddRange(value);
buffer.Add(lo);
buffer.Add(hi);
return buffer;
}
写多线圈
cs
if (flag == 6)
{
List<byte> datas = new List<byte>();
datas.Add(0x01);
datas.Add(0x0F);// 十进制 15
ushort addr = 10;// 起始地址
datas.Add((byte)(addr / 256));
datas.Add((byte)(addr % 256));
// 写入数量:写入多个个寄存器
//
List<bool> status = new List<bool>() {
true, false, true, true, true, false, true, false, true, true
};
// C#设备中已有的状态
// 逻辑
// 写了入寄存器数量
datas.Add((byte)(status.Count / 256));
datas.Add((byte)(status.Count % 256));
// 0101 1101 0x5D
// 0000 0011 0x03
// 0001 1101 0x1D
// 0000 0000 数据初始值
// 0000 0001 temp <<0
// 0000 0001 第一次或运算结果
// 第二次没有结果 因为为false不用管
// 0000 0100 temp <<2
// 0000 0101 第三次或运算结果
// 0000 1000 temp <<3
// 0000 1101 第四次或运算结果
// 0001 0000 temp <<4
// 0001 1101 第五次或运算结果
List<byte> vbs = new List<byte>();
//byte data = 0;
int index = 0;
for (int i = 0; i < status.Count; i++)
{
//status.Count =10 每8个一个字节
if (i % 8 == 0)
vbs.Add(0x00);// 初始值
index = vbs.Count - 1;
if (status[i])
{
// True
byte temp = (byte)(1 << (i % 8));
vbs[index] |= temp;
}
else
{
// False 取反操作
}
}
datas.Add((byte)vbs.Count);// 写入字节数
datas.AddRange(vbs);
datas = CRC16(datas);// Modbus
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
// 发送读取请求报文
serialPort.Write(datas.ToArray(), 0, datas.Count);
// 连续写
}
static List<byte> CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
if (value == null || !value.Any())
throw new ArgumentException("");
//运算
ushort crc = crcInit;
for (int i = 0; i < value.Count; i++)
{
crc = (ushort)(crc ^ (value[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
List<byte> buffer = new List<byte>();
buffer.AddRange(value);
buffer.Add(lo);
buffer.Add(hi);
return buffer;
}
读线圈消息帧格式 - 0x01、0x02
请求
响应
写单线圈消息帧 - 0x05
请求 响应
写多线圈消息帧 -- 0x0F
请求
响应