C#串口通信,清除缓存区数据,发送区接收区

本文介绍了C#中的串口通信,包括串口通信的基本概念、.NET Framework中的SerialPort类的使用以及如何配置串口参数。重点讲述了如何清除串口通信的数据缓冲区,以避免长时间运行导致的效率下降问题,确保数据的准确传输。示例代码展示了如何打开、关闭串口以及发送和接收数据。

前言:C#串口通信

今天这篇文章带大家学习下C#中的串口通讯。在日常的开发工作中,如果工作内容是CS方向的同学应该很容易接触到串口通讯方面的业务需求。那么也就很容易想到C#中SerialPort类,它就是专门来处理串口通讯相关的。

1、什么是串口通信

串口通讯是指外设和计算机间通过数据信号线,地线,控制线等,按位进行传输数据的一种通讯方式。

这种通讯方式使用的数据线少,在远距离通信中可以节约成本,但其传输速度比并行通讯慢。

串口是计算机上一种非常通用的设备通讯协议。大多数计算机包含两个基于RS-232的串口。

串口也是仪器仪表设备通用的通讯协议,很多GPIB兼容的设备也带有RS-232口,同时串口通信协议也可以用于获取远程设备采集的数据。

串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时也可将接受的串行数据流转换为并行的数据字符供给CPU的器件。

一般完成这种功能的电路,我们称为串行接口电路。

串行按位(bit)发送和接收字节,尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。
串口通信示意图这里提一句,我们笔记本的USB口,它不是串口,它是所谓的U口,我们的串口如果需要插入到USB口,那么就需要一个RS-232转U口的转换器才可以。

这里需要注意下,一般我们的硬件工程师都会在自己的硬件设备都内置这个小转换设备,很方便。

2、C#中封装的serialPort

从.NET Framework 2.0开始,微软就默认提供了System.IO.Ports.SerialPort类,根据SerialPort类提供的简单操作步骤,可以很容易的完成串口的信息收发程序,从特定的串口中接收到数据也可以进行数据的发送。

关于SerialPort类的应用也很容易,可以根据微软官方的介绍进行使用。

配置SerialPort的名称,端口号,波特率等。
打开/关闭串口
接收/发送数据

SerialPort mySerialPort = new SerialPort("COM2");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity=Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.Non;

mySerialPort.DataReceived += new SerialDataReceivedEvenHandler(DataReceive_Method);

mySerialPort.Open();

mySerialPort.Close();

发送数据

using System.IO.Ports;
private static void SendSampleData()
{
    SerialPort port = new SerialPort(
        "COM1", 9600, Parity.None, 8, StopBits.One);
    port.Open();
    port.Write("Hello World");
    port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
    port.Close();
}

namespace SerialPortExample
{
    class SerialPortProgram
    {        
        private SerialPort port = new SerialPort("COM1",
          9600, Parity.None, 8, StopBits.One);

        [STAThread]
        static void Main(string[] args)
        {            
            new SerialPortProgram();
        }

        private SerialPortProgram()
        {
            Console.WriteLine("Incoming Data:");            
            port.DataReceived += new
              SerialDataReceivedEventHandler(port_DataReceived);            
            port.Open();         
            Application.Run();
        }

        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {            
            Console.WriteLine(port.ReadExisting());
        }
    }

日常串口的使用多数情况是和线程进行的,一般都是在子线程中做这些耗时和重复的工作,在主线程或者界面只进行数据的展示处理即可。

在子线程的处理过程中需要特别处理串口的打开和关闭,要及时关闭串口的状态,防止出现无法捕获的异常错误。

3、C#串口通信数据缓冲区的清除

在实际的应用过程中需要上位机向下位机循环发送某些指令,经过长时间循环之后,会导致缓冲区填满,触发自动清除功能,但会随着时间的推移使得指令的发送越来越慢,因此最后在一次循环指令发送完之后且下位机完成响应之后对发送区进行清空,待接收区拿到相应的数据之后,再做一次接收区的缓冲清理。

(1)调用SerialPort.DiscardInBuffer 方法可以清空串行驱动程序的接收缓冲区的数据。
此方法等效于 Visual Basic 6.0 代码:MSComm1.InBufferCount = 0
(2)调用SerialPort.DiscardOutBuffer 方法可以清空串行驱动程序的发送缓冲区的数据。
此方法等效于 Visual Basic 6.0 代码:MSComm1.OutBufferCount = 0

### C#清除串口缓存区的方法 在 C# 的 `System.IO.Ports.SerialPort` 类中,提供了两种主要的方式来管理和清除串口缓冲区数据。这些方法分别是用于清空接收缓冲区的 `DiscardInBuffer()` 和用于清空发送缓冲区的 `DiscardOutBuffer()`。 #### 1. 清除接收缓冲区 当需要丢弃当前存在于串行驱动程序接收缓冲区中的所有数据时,可以使用 `DiscardInBuffer()` 方法。这通常适用于以下场景: - 当前接收到的数据已损坏或不再需要。 - 准备重新同步通信协议。 示例代码如下所示: ```csharp using System.IO.Ports; // 声明并初始化 SerialPort 对象 SerialPort serialPort = new SerialPort("COM1", 9600); // 打开串口连接 if (!serialPort.IsOpen) { serialPort.Open(); } // 清空接收缓冲区 serialPort.DiscardInBuffer(); // 这里调用了 DiscardInBuffer() 来清理接收缓冲区[^2] // 关闭串口连接 if (serialPort.IsOpen) { serialPort.Close(); } ``` #### 2. 清除发送缓冲区 对于尚未完全写入到物理端口但存储在内部发送队列中的数据,则可以通过调用 `DiscardOutBuffer()` 方法将其移除掉。这种方法特别适合于取消正在进行的大批量传输操作。 同样提供一段简单的演示代码片段: ```csharp using System.IO.Ports; // 创建一个新的 SerialPort 实例 var sp = new SerialPort(); sp.PortName = "COM3"; sp.BaudRate = 115200; sp.Parity = Parity.None; sp.DataBits = 8; sp.StopBits = StopBits.One; sp.Handshake = Handshake.XOnXOff; try { if (!sp.IsOpen) { sp.Open(); } // 向远程设备发送一些测试字符串... sp.Write("Test Message"); Thread.Sleep(10); // 模拟延迟让部分数据进入输出缓冲器 // 然后立即放弃剩余未完成的部分 sp.DiscardOutBuffer(); // 调用此函数抛弃还未送出的信息[^4] } finally { if(sp != null && sp.IsOpen){ sp.Close();} } ``` #### 3. 自定义缓冲大小调整 值得注意的是,默认情况下,Windows 平台上的 .NET Framework 提供了有限容量的输入/输出缓冲空间(通常是 4KB)。如果应用程序涉及较大规模的数据交换过程,那么建议适当增加这两个参数值——即通过修改 `ReadBufferSize` 和 `WriteBufferSize` 属性来扩展可用内存域范围。例如: ```csharp serialPort.ReadBufferSize = 16 * 1024; // 将读取缓冲区扩大至 16 KB[^3] serialPort.WriteBufferSize = 16 * 1024; // 同样也增大写出缓冲区尺寸为 16 KB ``` 这样做的好处是可以减少因为频繁溢出而导致的数据截断风险;然而缺点则是消耗更多的系统资源,因此应当权衡利弊后再做决定。 --- ### 总结 综上所述,在实际开发过程中遇到类似问题时可考虑采取上述措施之一解决问题。无论是直接利用现成 API 功能还是间接改变相关配置选项都能达到预期效果。不过需要注意的一点是务必确保每次访问硬件设施前后都妥善处理好异常状况以免造成不必要的麻烦。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值