C#中的通信(写单线圈和写多线圈)

写单线圈

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

请求

响应

相关推荐
dotent·3 小时前
C#基于WPF UI框架的通用基础上位机测试WPF框架
ui·c#·wpf
合作小小程序员小小店4 小时前
桌面开发,超市管理系统开发,基于C#,winform,sql server数据库
开发语言·数据库·sql·microsoft·sqlserver·c#
合作小小程序员小小店5 小时前
桌面开发,在线%超市销售管理%系统,基于vs2022,c#,winform,sql server数据
开发语言·数据库·microsoft·c#
p***32357 小时前
如何使用C#与SQL Server数据库进行交互
数据库·c#·交互
2501_941807269 小时前
Java高性能消息队列与Kafka实战分享:大规模消息处理、异步通信与性能优化经验
c#·linq
周杰伦fans9 小时前
C# 中的**享元工厂**模式
开发语言·数据库·c#
鹿衔`10 小时前
通过Flink 1.19 客户端实现Flink集群连接 Kafka 基础测试报告
c#·linq
玩泥巴的12 小时前
.NET 8+ 飞书API实战:自动化群组管理与消息推送
c#·.net·二次开发·飞书
烛阴12 小时前
从`new`关键字开始:精通C#类与对象
前端·c#