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);
相关推荐
Edingbrugh.南空1 小时前
Aerospike与Redis深度对比:从架构到性能的全方位解析
java·开发语言·spring
CodeCraft Studio1 小时前
借助Aspose.HTML控件,在 Python 中将 HTML 转换为 Markdown
开发语言·python·html·markdown·aspose·html转markdown·asposel.html
QQ_4376643141 小时前
C++11 右值引用 Lambda 表达式
java·开发语言·c++
aramae1 小时前
大话数据结构之<队列>
c语言·开发语言·数据结构·算法
封奚泽优2 小时前
使用Python实现单词记忆软件
开发语言·python·random·qpushbutton·qtwidgets·qtcore·qtgui
liulilittle3 小时前
C++/CLI与标准C++的语法差异(一)
开发语言·c++·.net·cli·clr·托管·原生
★YUI★3 小时前
学习游戏制作记录(剑投掷技能)7.26
学习·游戏·unity·c#
daixin88483 小时前
什么是缓存雪崩?缓存击穿?缓存穿透?分别如何解决?什么是缓存预热?
java·开发语言·redis·缓存
你我约定有三3 小时前
RabbitMQ--消息丢失问题及解决
java·开发语言·分布式·后端·rabbitmq·ruby
小乖兽技术3 小时前
C#与C++交互开发系列(二十四):WinForms 应用中嵌入C++ 原生窗体
c++·c#·交互