C# WPF 串口通信

C# WPF 串口通信

安装依赖库

  • System.IO.Ports

csharp 复制代码
using System.Diagnostics;
using System.IO.Ports;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup.Localizer;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace GasAlarmFactoryTools
{
    struct TestInfoData {
        public string dev_uuid;
        public string dev_simcard;
        public string private_data;
        public string datetime;
    };

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // TODO: 串口相关
        SerialPort mSerialPort = new SerialPort();
        private Thread recvThread;
        long recvTimems = 0;    // 用于计算串口接收完一帧数据
        int rxLen = 0;  // 串口接收到的数据长度
        byte[] rxBuff = new byte[128];  // 串口数据接收缓存
        private List<string> baudrateList = new List<string> {
            "4800",
            "9600",
            "19200",
            "38400",
            "57600",
            "115200",
            "256000",
            "1000000",
            "2000000",
            "3000000"
        };

        public MainWindow()
        {
            InitializeComponent();


            // 获取所有可用串口端口,并添加到comboBoxCOM
            string[] ports = System.IO.Ports.SerialPort.GetPortNames();
            comboBoxComName.ItemsSource = ports;
            comboBoxComName.SelectedIndex = 0;  // 默认选择索引
            comboBoxBaudrate.ItemsSource = baudrateList;    // 波特率设置combobox数据源
        }

        /// <summary>
        /// 窗口关闭处理
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if (MessageBox.Show("确定要退出吗?", "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
            {
                // 用户选择"否",取消关闭
                e.Cancel = true;
            }

            mSerialPort.Close();
            //mTimer.Dispose();

            if (recvThread != null)
            {                
                recvThread.Abort();
            }

            base.OnClosing(e);
        }


        private void recvTimerCalback(object obj)
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                // TODO: 处理接收到的数据

            }));
        }

        private void recvThreadTask()
        {
            Thread.Sleep(200);
            try
            {
                while (true)
                {
                    Thread.Sleep(1);

                    if (mSerialPort.IsOpen)
                    {
                        int datalength = mSerialPort.BytesToRead;
                        if (datalength >= 1)
                        {
                            //Console.WriteLine("BytesToRead:" + datalength);
                            for (int i = 0; i < datalength; i++)
                            {
                                recvTimems = Environment.TickCount; // 更新串口数据接收时间
                                byte data = (byte)mSerialPort.ReadByte();
                                rxBuff[rxLen++] = data;

                                if (rxBuff.Length == rxLen)
                                {
                                    rxLen = 0;
                                    Array.Clear(rxBuff, 0, rxBuff.Length);
                                    Console.WriteLine("Error================" + rxBuff.Length + "\n");
                                }

                                //Console.WriteLine(data.ToString("X2"));
                            }
                        }

                        recvTimerCalback(null);
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(" ----------异常------------");
            }
        }

        private void btnOpenCloseCom_Click(object sender, RoutedEventArgs e)
        {
            if (mSerialPort.IsOpen)
            {
                mSerialPort.Close();
                btnOpenCloseCom.Content = "打开串口";
                btnOpenCloseCom.Background = Brushes.Red;
                Console.WriteLine("关闭串口成功");
                Debug.WriteLine("关闭串口成功");
                comboBoxComName.IsEnabled = true;
                comboBoxBaudrate.IsEnabled = true;
                comboBoxDataBits.IsEnabled = true;
                comboBoxStopBits.IsEnabled = true;
                comboBoxParity.IsEnabled = true;
                comboBoxHandshake.IsEnabled = true;
            }
            else
            {
                // TODO: 串口默认设置
                mSerialPort.BaudRate = 4800; // 波特率
                mSerialPort.DataBits = 8;   // 数据位
                mSerialPort.StopBits = StopBits.One;    // 停止位
                mSerialPort.Parity = Parity.None;   // 校验位
                mSerialPort.Handshake = Handshake.None; // 流控位
                // mSerialPort.ReadTimeout = 1500; // 读超时
                // mSerialPort.Encoding = Encoding.UTF8; // 编码方式
                // mSerialPort.RtsEnable = true;
                // mSerialPort.DataReceived += SerialPort_DataReceived;

                Console.WriteLine("baudrate SelectedIndex:" + comboBoxBaudrate.SelectedIndex);
                Console.WriteLine("baudrate SelectedValue:" + comboBoxBaudrate.SelectedValue);
                Console.WriteLine("baudrate Text:" + comboBoxBaudrate.Text);

                // TODO: 串口端口选择
                mSerialPort.PortName = comboBoxComName.SelectedItem.ToString();

                // TODO: 设置串口波特率
                if (comboBoxBaudrate.SelectedIndex < 0)
                {
                    mSerialPort.BaudRate = Convert.ToInt32(comboBoxBaudrate.Text);
                }
                else
                {
                    switch (comboBoxBaudrate.SelectedValue)
                    {
                        case "4800":
                            mSerialPort.BaudRate = 4800;
                            break;
                        case "9600":
                            mSerialPort.BaudRate = 9600;
                            break;
                        case "19200":
                            mSerialPort.BaudRate = 19200;
                            break;
                        case "38400":
                            mSerialPort.BaudRate = 38400;
                            break;
                        case "57600":
                            mSerialPort.BaudRate = 57600;
                            break;
                        case "115200":
                            mSerialPort.BaudRate = 115200;
                            break;
                        case "256000":
                            mSerialPort.BaudRate = 256000;
                            break;
                        case "1000000":
                            mSerialPort.BaudRate = 1000000;
                            break;
                        case "2000000":
                            mSerialPort.BaudRate = 2000000;
                            break;
                        case "3000000":
                            mSerialPort.BaudRate = 3000000;
                            break;
                        default:
                            MessageBox.Show("波特率设置有误!");
                            break;
                    }
                }

                // TODO: 串口数据位设置
                switch (comboBoxDataBits.SelectedIndex)
                {
                    case 0:
                        mSerialPort.DataBits = 5;
                        break;
                    case 1:
                        mSerialPort.DataBits = 6;
                        break;
                    case 2:
                        mSerialPort.DataBits = 7;
                        break;
                    case 3:
                        mSerialPort.DataBits = 8;
                        break;
                    default:
                        mSerialPort.DataBits = 8;
                        break;
                }

                // TODO: 串口停止位设置
                switch (comboBoxStopBits.SelectedIndex)
                {
                    case 0:
                        mSerialPort.StopBits = StopBits.One;
                        break;
                    case 1:
                        mSerialPort.StopBits = StopBits.OnePointFive;
                        break;
                    case 2:
                        mSerialPort.StopBits = StopBits.Two;
                        break;
                    default:
                        mSerialPort.StopBits = StopBits.One;
                        break;
                }

                // TODO: 串口校验位设置
                switch (comboBoxParity.SelectedIndex)
                {
                    case 0:
                        mSerialPort.Parity = Parity.None;   // 无校验
                        Console.WriteLine("无校验");
                        break;
                    case 1:
                        mSerialPort.Parity = Parity.Odd;   // 奇校验
                        Console.WriteLine("奇校验");
                        break;
                    case 2:
                        mSerialPort.Parity = Parity.Even;   // 偶校验
                        Console.WriteLine("偶校验");
                        break;
                    case 3:
                        mSerialPort.Parity = Parity.Mark;   // 校验位1
                        Console.WriteLine("校验位1");
                        break;
                    case 4:
                        mSerialPort.Parity = Parity.Space;   // 校验位0
                        Console.WriteLine("校验位0");
                        break;
                    default:
                        mSerialPort.Parity = Parity.None;   // 无校验
                        break;
                }

                // TODO: 串口流控位设置
                switch (comboBoxHandshake.SelectedIndex)
                {
                    case 0:
                        mSerialPort.Handshake = Handshake.None;
                        break;
                    case 1:
                        mSerialPort.Handshake = Handshake.XOnXOff;                        
                        break;
                    case 2:
                        mSerialPort.Handshake = Handshake.RequestToSend;
                        break;
                    case 3:
                        mSerialPort.Handshake = Handshake.RequestToSendXOnXOff;
                        break;
                    default:
                        mSerialPort.Handshake = Handshake.None;
                        break;
                }

                // TODO: 尝试打开串口
                try 
                {
                    mSerialPort.Open();
                    btnOpenCloseCom.Content = "关闭串口";
                    btnOpenCloseCom.Background = Brushes.Green;
                }
                catch (Exception ex) 
                {
                    MessageBox.Show(ex.Message.ToString());
                }
            }
        }
    }
}
csharp 复制代码
// TODO: 串口写入数据  3个参数(buf, offset, len);
mSerialPort.Write(new byte[] { 0xAA, 0x00, 0x08, 0x00, 0xB2, 0x55 }, 0, 6);
相关推荐
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧几秒前
C语言_数据结构总结4:不带头结点的单链表
c语言·开发语言·数据结构·算法·链表·visualstudio·visual studio
极客代码15 分钟前
Linux IPC:System V共享内存汇总整理
linux·c语言·开发语言·并发·共享内存·通信·system v
orangapple21 分钟前
一个差劲的软件设计
开发语言·c#
算法与编程之美23 分钟前
冒泡排序
java·开发语言·数据结构·算法·排序算法
Aphelios38025 分钟前
Java 学习记录:基础到进阶之路(一)
java·开发语言·学习·idea
白总Server26 分钟前
Bash和Zsh在处理大文件时优化方法
开发语言·网络·ide·stm32·安全·udp·bash
苦逼的老王1 小时前
java之uniapp实现门店地图
java·开发语言·uni-app
一条晒干的咸魚1 小时前
【C#学习笔记03】进制转换与反码、补码、原码
开发语言·笔记·学习·c#
十年之少1 小时前
内存检测工具——Qt Creator
开发语言·qt
网络安全(king)2 小时前
基于java社交网络安全的知识图谱的构建与实现
开发语言·网络·深度学习·安全·web安全·php