C# 串口通信

工具

虚拟串口工具:https://www.virtual-serial-port.org/

串口调试工具:https://github.com/SuperStudio/SuperCom

串口通信数据帧格式

串口通信中,数据以帧的形式发送,每一帧通常包括:起始位(Start Bit)、数据位(Data Bits)、可选的奇偶校验位(Parity Bit)以及停止位(Stop Bits)。

同步通信
using System.IO.Ports;

var port = new SerialPort
{
    // 设置串口名
    PortName = "COM2",
    // 设置波特率
    BaudRate = 9600,
    // 设置奇偶校验方式
    Parity = Parity.None,
    // 设置停止位
    StopBits = StopBits.One
};

port.Open();

try
{
    while (true)
    {
        Console.Write("Your Message: ");
        // 读取用户输入
        var msg = Console.ReadLine();
        if (msg == null || msg.Trim() == "") continue;
        // 发送消息
        port.WriteLine(msg);
        // 接收消息
        var receivedMsg = port.ReadLine();
        Console.WriteLine($"Received: {receivedMsg}");
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

port.Close();
异步通信
using System.IO.Ports;
using System.Text;

var port = new SerialPort
{
    // 设置串口名
    PortName = "COM2",
    // 设置波特率
    BaudRate = 9600,
    // 设置奇偶校验方式
    Parity = Parity.None,
    // 设置停止位
    StopBits = StopBits.One
};

port.DataReceived += (s, e) =>
{
    var receivedMsg = (s as SerialPort)!.ReadExisting();
    Console.WriteLine($"Received: {receivedMsg}");
};

port.Open();

Task<string> ReadLineAsync()
{

    return Task.Run(() =>
    {
        Console.Write("Your Message: ");
        return Console.ReadLine()!;
    });
}

async Task SendAsync(SerialPort sp, string msg)
{
    var bytes = Encoding.UTF8.GetBytes(msg);
    await sp.BaseStream.WriteAsync(bytes, 0, bytes.Length);
}

await Task.Run(async () =>
{
    while (true)
    {
        // 读取用户输入
        var msg = await ReadLineAsync()!;
        if (msg == null || msg.Trim() == "") continue;

        // 发送消息
        await SendAsync(port, msg);
    }
});

port.Close();
实现效果

粘包问题

多条数据在传输过程中,如果发送数据频率过快、接收方处理速度不够,消息数据会在接收方的缓冲区堆积,多条消息的数据会挤在一块。解决方法是在协议设计中加入数据帧的结束符或者定界符(如数据链路层的帧定界符)、或者固定消息头的长度,在消息头中标明消息体的长度。

串口模式下,Modbus RTU协议使用时间间隔作为帧定界的方法(蛋疼)。

Modbus ASCII 使用 CRLF (即 \r\n)作为数据帧的结束符(舒服)。

posted @ 2024-10-22 22:18  烟酒忆长安  阅读(38)  评论(0编辑  收藏  举报