【自动化】C#中串口接收数据,以及主动接收和被动接收的区别
串口通信在各种应用场景中都是非常常见和重要的,比如工业控制、数据采集、医疗设备等。在C#中,我们可以使用System.IO.Ports.SerialPort类来轻松地实现串口通信。本文将详细介绍C#中串口接收数据,以及主动接收和被动接收的区别,并提供一些实用的示例。
1. 串口接收数据的基本概念和用途
串口接收数据指的是计算机通过串口接收外部设备发送的数据。串口通信通常用于工业控制、数据采集、远程监控等领域。通过串口接收数据,我们可以实现计算机与外部设备之间的数据交互,从而控制外部设备或获取外部设备的数据。
2. 主动接收和被动接收的概念及其差异
在串口通信中,数据的接收方式主要有两种:主动接收和被动接收。
2.1 主动接收
主动接收是指计算机主动向外部设备发送请求,要求外部设备发送数据。主动接收通常需要调用外部设备的API或发送特定的指令来触发。
- 创建SerialPort对象并配置串口参数,如波特率、数据位、停止位等。
SerialPort serialPort = new SerialPort(); serialPort.PortName = "COM1"; serialPort.BaudRate = 9600; serialPort.DataBits = 8; serialPort.Parity = Parity.None; serialPort.StopBits = StopBits.One; serialPort.Handshake = Handshake.None;
- 打开串口。
serialPort.Open();
- 设置串口数据接收事件。
serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
- 在DataReceived事件处理函数中接收数据。
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { string data = serialPort.ReadExisting(); Console.WriteLine(data); }
- 关闭串口。
serialPort.Close();
2.2被动接收
被动接收是指外部设备主动向计算机发送数据,计算机被动地接收这些数据。被动接收不需要计算机主动请求数据,而是外部设备在数据准备好后自动发送给计算机。
- 创建SerialPort对象并配置串口参数,同上。
- 打开串口。
serialPort.Open();
- 在循环中不断读取串口数据。
while (true) { string data = serialPort.ReadExisting(); Console.WriteLine(data); }
- 关闭串口。
serialPort.Close();
3. 主动接收和被动接收的利弊
主动接收的利弊
- 利:主动接收可以确保计算机在需要数据时及时获取,适用于实时性要求较高的场景。
- 弊:主动接收需要计算机不断查询外部设备是否有数据发送,可能会占用较多的CPU资源。
被动接收的利弊
- 利:被动接收减少了计算机的资源消耗,适用于实时性要求不高的场景。
- 弊:被动接收可能需要等待外部设备主动发送数据,实时性较差。
4. 主动接收与被动接收的区别
- 工作方式不同:主动接收是计算机主动向外部设备请求数据,而被动接收是外部设备主动向计算机发送数据。
- 资源占用不同:主动接收时,计算机需要不断查询外部设备是否有数据发送,可能会占用较多的CPU资源;而被动接收时,计算机只需在数据到达时读取数据,CPU资源占用较少。
- 实时性不同:主动接收可以在第一时间获取外部设备的数据,实时性较好;被动接收可能需要等待外部设备主动发送数据,实时性较差。
- 应用场景不同:主动接收适用于需要实时监控外部设备数据的场景,如数据采集、远程监控等;被动接收适用于外部设备主动向计算机发送数据的场景,如传感器数据传输、串口调试等。
5. 不同场景下选择使用主动接收或被动接收的建议
主动接收的建议
- 当实时性要求较高,需要计算机主动控制外部设备时,选择主动接收。
被动接收的建议
- 当实时性要求不高,外部设备会主动发送数据时,选择被动接收。
-
示例
下面我们将通过一个简单的示例来演示如何在C#中实现主动接收和被动接收。
主动接收示例
using System; using System.IO.Ports; namespace SerialPortExample { class Program { static void Main(string[] args) { SerialPort serialPort = new SerialPort(); serialPort.PortName = "COM1"; serialPort.BaudRate = 9600; serialPort.DataBits = 8; serialPort.Parity = Parity.None; serialPort.StopBits = StopBits.One; serialPort.Handshake = Handshake.None; try { serialPort.Open(); Console.WriteLine("串口已打开,开始主动接收数据..."); // 设置数据接收事件 serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived); // 进入主循环 Console.ReadLine(); } catch (Exception ex) { Console.WriteLine("发生错误: " + ex.Message); } finally { if (serialPort.IsOpen) { serialPort.Close(); } } } private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { string data = ((SerialPort)sender).ReadExisting(); Console.WriteLine("主动接收到的数据: " + data); } } }
被动接收示例
using System; using System.IO.Ports; namespace SerialPortExample { class Program { static void Main(string[] args) { SerialPort serialPort = new SerialPort(); serialPort.PortName = "COM1"; serialPort.BaudRate = 9600; serialPort.DataBits = 8; serialPort.Parity = Parity.None; serialPort.StopBits = StopBits.One; serialPort.Handshake = Handshake.None; try { serialPort.Open(); Console.WriteLine("串口已打开,开始被动接收数据..."); // 不需要设置数据接收事件,因为我们是被动接收 // 进入主循环,不断读取串口数据 while (true) { string data = serialPort.ReadExisting(); if (!string.IsNullOrEmpty(data)) { Console.WriteLine("被动接收到的数据: " + data); } } } catch (Exception ex) { Console.WriteLine("发生错误: " + ex.Message); } finally { if (serialPort.IsOpen) { serialPort.Close(); } }
在这个示例中,我们创建了一个SerialPort实例并配置了串口参数。在主动接收示例中,我们设置了DataReceived事件处理函数来主动接收数据。而在被动接收示例中,我们没有设置DataReceived事件,而是使用ReadExisting方法在一个无限循环中被动地接收数据。
总结
在C#中实现串口通信时,根据实际需求选择合适的接收方式,可以提高程序的性能和稳定性。主动接收适用于需要实时监控外部设备数据的场景,而被动接收适用于外部设备主动向计算机发送数据的场景。了解主动接收和被动接收的区别,并根据不同场景选择合适的方式,将有助于提高串口通信的效率。
- 关闭串口。
- 在循环中不断读取串口数据。
- 关闭串口。
- 在DataReceived事件处理函数中接收数据。
- 设置串口数据接收事件。
- 打开串口。