欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用C#串口通訊實(shí)現(xiàn)數(shù)據(jù)的發(fā)送和接收

 更新時(shí)間:2025年03月17日 11:02:34   作者:妮妮學(xué)代碼  
本文詳細(xì)介紹了如何使用C#實(shí)現(xiàn)基于串口通訊的數(shù)據(jù)發(fā)送和接收,通過SerialPort類,我們可以輕松實(shí)現(xiàn)串口通訊,并結(jié)合事件機(jī)制實(shí)現(xiàn)數(shù)據(jù)的傳遞和處理,感興趣的朋友一起看看吧

串口通訊(Serial Communication)是一種常見的硬件設(shè)備與計(jì)算機(jī)之間的數(shù)據(jù)傳輸方式,廣泛應(yīng)用于工業(yè)控制、嵌入式系統(tǒng)、傳感器數(shù)據(jù)采集等領(lǐng)域。本文將詳細(xì)介紹如何使用C#實(shí)現(xiàn)基于串口通訊的數(shù)據(jù)發(fā)送和接收,并結(jié)合代碼示例解析其實(shí)現(xiàn)過程。

1. 概述

串口通訊的核心是System.IO.Ports.SerialPort類,它封裝了串口操作的底層細(xì)節(jié),提供了簡(jiǎn)單易用的接口。以下是串口通訊的基本流程:

1.初始化串口:設(shè)置串口參數(shù)(如波特率、數(shù)據(jù)位、停止位等)。

2.打開串口:通過SerialPort.Open方法打開串口。

3.發(fā)送數(shù)據(jù):通過SerialPort.Write方法向串口發(fā)送數(shù)據(jù)。

4.接收數(shù)據(jù):通過SerialPort.DataReceived事件異步接收數(shù)據(jù)。

5.處理數(shù)據(jù):對(duì)接收到的數(shù)據(jù)進(jìn)行解析和處理。

2. 關(guān)鍵技術(shù)點(diǎn)

2.1 SerialPort類

SerialPort是C#中用于實(shí)現(xiàn)串口通訊的核心類,提供了發(fā)送和接收數(shù)據(jù)的方法。

2.2 異步接收數(shù)據(jù)

通過SerialPort.DataReceived事件異步接收數(shù)據(jù),避免阻塞主線程。

2.3 數(shù)據(jù)解析

接收到的數(shù)據(jù)通常是字節(jié)數(shù)組(byte[]),需要根據(jù)協(xié)議格式進(jìn)行解析。

2.4 事件機(jī)制

通過事件機(jī)制將接收到的數(shù)據(jù)傳遞給其他模塊處理。

3. 代碼實(shí)現(xiàn)

以下是基于串口通訊實(shí)現(xiàn)數(shù)據(jù)發(fā)送和接收的代碼示例。

3.1 SerialPortHelper類

SerialPortHelper類負(fù)責(zé)初始化串口、發(fā)送數(shù)據(jù)、接收數(shù)據(jù)以及處理數(shù)據(jù)。

public class SerialPortHelper
{
    private SerialPort serialPort; // 串口對(duì)象
    private List<byte> _buffer = new List<byte>(); // 數(shù)據(jù)緩沖區(qū)
    /// <summary>
    /// 自定義串口消息接收事件
    /// </summary>
    public event ReceiveDataEventHandler ReceiveDataEvent;
    public SerialPortHelper()
    {
        serialPort = new SerialPort();
    }
    /// <summary>
    /// 獲取當(dāng)前計(jì)算機(jī)所有的串行端口名
    /// </summary>
    public static string[] GetPortArray()
    {
        return SerialPort.GetPortNames(); // 獲取所有可用串口
    }
    /// <summary>
    /// 設(shè)置串口參數(shù)
    /// </summary>
    public void SetSerialPort(string portName, int baudrate, Parity parity, int databits, StopBits stopBits)
    {
        serialPort.PortName = portName; // 端口名
        serialPort.BaudRate = baudrate; // 波特率
        serialPort.Parity = parity; // 奇偶校驗(yàn)
        serialPort.DataBits = databits; // 數(shù)據(jù)位
        serialPort.StopBits = stopBits; // 停止位
        serialPort.DataReceived += ReceiveDataMethod; // 訂閱數(shù)據(jù)接收事件
    }
    /// <summary>
    /// 打開串口
    /// </summary>
    public void Open()
    {
        try
        {
            serialPort.Open(); // 打開串口
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error opening serial port: " + ex.Message);
        }
    }
    /// <summary>
    /// 關(guān)閉串口
    /// </summary>
    public void Close()
    {
        serialPort.Close(); // 關(guān)閉串口
    }
    /// <summary>
    /// 發(fā)送數(shù)據(jù)(字節(jié)數(shù)組)
    /// </summary>
    public void SendDataMethod(byte[] data)
    {
        if (!serialPort.IsOpen)
        {
            Open(); // 如果串口未打開,則先打開
        }
        serialPort.Write(data, 0, data.Length); // 發(fā)送數(shù)據(jù)
    }
    /// <summary>
    /// 發(fā)送數(shù)據(jù)(字符串)
    /// </summary>
    public void SendDataMethod(string data)
    {
        if (!serialPort.IsOpen)
        {
            Open(); // 如果串口未打開,則先打開
        }
        serialPort.Write(data); // 發(fā)送字符串
    }
    /// <summary>
    /// 數(shù)據(jù)接收事件處理方法
    /// </summary>
    private void ReceiveDataMethod(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            byte[] dataChunk = new byte[serialPort.BytesToRead]; // 讀取緩沖區(qū)中的數(shù)據(jù)
            serialPort.Read(dataChunk, 0, dataChunk.Length);
            _buffer.AddRange(dataChunk); // 將數(shù)據(jù)添加到緩沖區(qū)
            while (_buffer.Count >= 3) // 確保緩沖區(qū)中有足夠的數(shù)據(jù)
            {
                byte thirdByte = _buffer[1]; // 獲取第三個(gè)字節(jié)(功能碼)
                if (thirdByte == 0x03) // 功能碼0x03
                {
                    if (_buffer.Count >= 19) // 檢查是否有完整的數(shù)據(jù)包
                    {
                        byte[] completePacket = _buffer.GetRange(0, 19).ToArray(); // 提取完整數(shù)據(jù)包
                        TriggerReceiveDataEvent(completePacket); // 觸發(fā)接收事件
                        _buffer.RemoveRange(0, 19); // 移除已處理的數(shù)據(jù)
                    }
                    else
                    {
                        break; // 數(shù)據(jù)不足,等待更多數(shù)據(jù)
                    }
                }
                else if (thirdByte == 0x10 || thirdByte == 0x06) // 功能碼0x10或0x06
                {
                    byte[] dataToProcess = _buffer.ToArray(); // 處理整個(gè)緩沖區(qū)
                    TriggerReceiveDataEvent(dataToProcess); // 觸發(fā)接收事件
                    _buffer.Clear(); // 清空緩沖區(qū)
                }
                else
                {
                    _buffer.RemoveRange(0, 3); // 移除無法識(shí)別的數(shù)據(jù)
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error processing serial port data: " + ex.Message);
        }
    }
    /// <summary>
    /// 觸發(fā)接收數(shù)據(jù)事件
    /// </summary>
    private void TriggerReceiveDataEvent(byte[] data)
    {
        if (ReceiveDataEvent != null)
        {
            ReceiveDataEventArg arg = new ReceiveDataEventArg(data); // 創(chuàng)建事件參數(shù)
            ReceiveDataEvent.Invoke(this, arg); // 觸發(fā)事件
        }
    }
}

3.2 ReceiveDataEventArg類

ReceiveDataEventArg類用于封裝接收到的數(shù)據(jù),并作為事件參數(shù)傳遞。

public class ReceiveDataEventArg : EventArgs
{
    public byte[] Data { get; set; } // 接收到的數(shù)據(jù)
    public ReceiveDataEventArg(byte[] data)
    {
        Data = data; // 初始化數(shù)據(jù)
    }
}

3.3 主窗體(MainWindow)

主窗體負(fù)責(zé)初始化SerialPortHelper并處理接收到的數(shù)據(jù)。

public partial class MainWindow : Window
{
    private SerialPortHelper serialPortHelper;
    public MainWindow()
    {
        InitializeComponent();
        SettingComPorts(); // 初始化串口
    }
    private void SettingComPorts()
    {
        string portName = "COM8"; // 串口名稱
        int baudRate = 115200; // 波特率
        Parity parity = Parity.None; // 奇偶校驗(yàn)
        int dataBits = 8; // 數(shù)據(jù)位
        StopBits stopBits = StopBits.One; // 停止位
        serialPortHelper = new SerialPortHelper();
        serialPortHelper.SetSerialPort(portName, baudRate, parity, dataBits, stopBits); // 設(shè)置串口參數(shù)
        serialPortHelper.Open(); // 打開串口
        serialPortHelper.ReceiveDataEvent += ReceiveDataEvent; // 訂閱接收數(shù)據(jù)事件
    }
    /// <summary>
    /// 接收數(shù)據(jù)事件處理方法
    /// </summary>
    private void ReceiveDataEvent(object sender, ReceiveDataEventArg e)
    {
        byte[] receivedData = e.Data; // 獲取接收到的數(shù)據(jù)
        if (receivedData[1] == 0x03) // 功能碼0x03
        {
            int receiveDataLength = receivedData[2]; // 獲取有效數(shù)據(jù)長(zhǎng)度
            byte[] receiveDataBuffer = new byte[receiveDataLength];
            Array.Copy(receivedData, 3, receiveDataBuffer, 0, receiveDataLength); // 提取有效數(shù)據(jù)
            ushort[] units = messageData.GetUnitsFromByteArray(receiveDataBuffer); // 解析數(shù)據(jù)
            if (units != null)
            {
                List<ChannelData> channelDatas = databaseHelper.GetUUTInfo(units); // 獲取設(shè)備信息
                UpdateDeviceInfo(channelDatas); // 更新UI
            }
        }
    }
}

4. 數(shù)據(jù)傳遞流程詳解

4.1 初始化串口

在SettingComPorts方法中,設(shè)置串口參數(shù)并打開串口。

訂閱ReceiveDataEvent事件以接收數(shù)據(jù)。

4.2 發(fā)送數(shù)據(jù)

通過SendDataMethod方法向串口發(fā)送數(shù)據(jù)。

4.3 接收數(shù)據(jù)

串口接收到數(shù)據(jù)后,觸發(fā)ReceiveDataMethod方法。

將接收到的數(shù)據(jù)添加到緩沖區(qū),并根據(jù)功能碼解析數(shù)據(jù)。

4.4 處理數(shù)據(jù)

在ReceiveDataEvent方法中,解析接收到的數(shù)據(jù)并更新UI。

5. 關(guān)鍵技術(shù)解析

5.1 異步接收數(shù)據(jù)

通過SerialPort.DataReceived事件異步接收數(shù)據(jù),避免阻塞主線程。

5.2 數(shù)據(jù)解析

根據(jù)功能碼(如0x03、0x06)解析接收到的字節(jié)數(shù)組,提取有效數(shù)據(jù)。

5.3 事件機(jī)制

通過事件將接收到的數(shù)據(jù)傳遞給主窗體或其他模塊處理。

6. 總結(jié)

本文詳細(xì)介紹了如何使用C#實(shí)現(xiàn)基于串口通訊的數(shù)據(jù)發(fā)送和接收。通過SerialPort類,我們可以輕松實(shí)現(xiàn)串口通訊,并結(jié)合事件機(jī)制實(shí)現(xiàn)數(shù)據(jù)的傳遞和處理。串口通訊適用于硬件設(shè)備與計(jì)算機(jī)之間的數(shù)據(jù)傳輸,是工業(yè)控制和嵌入式系統(tǒng)開發(fā)中的重要技術(shù)。

希望這篇文章對(duì)您有所幫助!如果有任何問題,歡迎在評(píng)論區(qū)留言討論。

到此這篇關(guān)于如何使用C#串口通訊實(shí)現(xiàn)數(shù)據(jù)的發(fā)送和接收的文章就介紹到這了,更多相關(guān)c#數(shù)據(jù)的發(fā)送和接收內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論