C# WPF编程-串口通信

news2024/11/8 20:00:34

C# WPF编程-串口通信

  • 串口通信
    • 1. NuGet安装System.IO.Ports
    • 2. 界面布局XAML
    • 3. C#代码
    • 4. 运行效果
    • 源码下载

串口通信

1. NuGet安装System.IO.Ports

在这里插入图片描述

2. 界面布局XAML

<Window x:Class="BlocksTools.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BlocksTools"
        mc:Ignorable="d"
        Title="串口工具" Height="450" Width="800">
    <Grid>
        <TabControl>
            <TabItem>
                <TabItem.Header>
                    <StackPanel>
                        <Label>串口设置</Label>
                    </StackPanel>
                </TabItem.Header>
                <StackPanel Orientation="Horizontal">
                    <GroupBox Header="串口" Width="200">
                        <StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label Margin="3" Height="25" Width="50">端口号</Label>
                                <ComboBox x:Name="comboBoxCOM" Margin="3" Height="20" Width="130" DragDrop.Drop="comboBoxCOM_Drop"/>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label Margin="3" Height="25" Width="50">波特率</Label>
                                <ComboBox x:Name="comboBoxBaudRate" Margin="3" Height="20" Width="130" SelectedIndex="0" >
                                    <ComboBoxItem>9600</ComboBoxItem>
                                    <ComboBoxItem>19200</ComboBoxItem>
                                    <ComboBoxItem>38400</ComboBoxItem>
                                    <ComboBoxItem>115200</ComboBoxItem>
                                    <ComboBoxItem>1000000</ComboBoxItem>
                                </ComboBox>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label Margin="3" Height="25" Width="50">数据位</Label>
                                <ComboBox x:Name="comboBoxDataBit" Margin="3" Height="20" Width="130" SelectedIndex="3">
                                    <ComboBoxItem>5</ComboBoxItem>
                                    <ComboBoxItem>6</ComboBoxItem>
                                    <ComboBoxItem>7</ComboBoxItem>
                                    <ComboBoxItem>8</ComboBoxItem>
                                </ComboBox>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label Margin="3" Height="25" Width="50">停止位</Label>
                                <ComboBox x:Name="comboBoxStopBit" Margin="3" Height="20" Width="130" SelectedIndex="0">
                                    <ComboBoxItem>1位</ComboBoxItem>
                                    <ComboBoxItem>1.5位</ComboBoxItem>
                                    <ComboBoxItem>2位</ComboBoxItem>
                                </ComboBox>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label Margin="3" Height="25" Width="50">校验位</Label>
                                <ComboBox x:Name="comboBoxSdd" Margin="3" Height="20" Width="130" SelectedIndex="0">
                                    <ComboBoxItem>无校验</ComboBoxItem>
                                    <ComboBoxItem>奇校验</ComboBoxItem>
                                    <ComboBoxItem>偶校验</ComboBoxItem>
                                    <ComboBoxItem>1 校验</ComboBoxItem>
                                    <ComboBoxItem>0 校验</ComboBoxItem>
                                </ComboBox>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label Margin="3" Height="25" Width="50">流控位</Label>
                                <ComboBox x:Name="comboBoxlik" Margin="3" Height="20" Width="130" SelectedIndex="0" >
                                    <ComboBoxItem>无流控</ComboBoxItem>
                                    <ComboBoxItem>RTS/CTS</ComboBoxItem>
                                    <ComboBoxItem>XON/XOFF</ComboBoxItem>
                                </ComboBox>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                <Button x:Name="btnOpenCloseCom" Margin="3" Width="80" Height="25" Click="btnOpenCloseCom_Click">打开串口</Button>
                                <Button x:Name="btnClearRecv" Margin="3" Width="80" Height="25" Click="btnClearRecv_Click">清空接收</Button>
                            </StackPanel>
                        </StackPanel>
                    </GroupBox>
                    <GroupBox Header="接收数据" MinWidth="590" MaxWidth="1000" Width="515">
                        <ScrollViewer>
                            <ScrollViewer.Content>
                                <TextBlock x:Name="textBlockRecv" MinWidth="300"></TextBlock>
                            </ScrollViewer.Content>
                        </ScrollViewer>

                    </GroupBox>
                </StackPanel>
            </TabItem>
            <TabItem>
                <TabItem.Header>
                    <StackPanel>
                        <Label>数据显示</Label>
                    </StackPanel>
                </TabItem.Header>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

3. C#代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BlocksTools
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        SerialPort mSerialPort = new SerialPort();
        private StringBuilder lineBuilder = new StringBuilder();    // 用于存放串口接收数据        

        public MainWindow()
        {
            InitializeComponent();

            // 获取所有可用串口端口,并添加到comboBoxCOM
            string[] ports = System.IO.Ports.SerialPort.GetPortNames();
            comboBoxCOM.ItemsSource = ports;
            comboBoxCOM.SelectedIndex = 0;  // 默认选择索引                      
        }

        /// <summary>
        /// 串口数据接收函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            System.Threading.Thread.Sleep(1); // 等待1S保证串口发送的一帧数据全部接收完成

            // 读取数据
            byte[] data = new byte[mSerialPort.BytesToRead];
            mSerialPort.Read(data, 0, data.Length);

            string str = Encoding.UTF8.GetString(data); // 字符串转码UTF-8格式
            lineBuilder.Append(str);

            this.Dispatcher.Invoke(new Action(() =>
            {
                string str2 = lineBuilder.ToString();
                textBlockRecv.Text = str2;  // 显示串口数据内容

                // 解析串口数据:
                // $$ADC:[228,246,247,253,828,348,262,260,316,275,297,320,291,343,837,]ADC$$ 

                int index_start = str2.IndexOf("$$ADC:[", StringComparison.Ordinal);
                int index_end = str2.IndexOf("]ADC$$", StringComparison.Ordinal);

                if ((index_start >= 0) && (index_end >= 0))
                {                 
                    string str3 = str2.Substring(index_start + "$$ADC:[".Length, index_end - index_start);  // 截取"$$ADC:["之后的数据
                    string[] array = str3.Split(new char[] { ',' }); // 以","分割数据,并存储到数组
                    double adc1 = Convert.ToDouble(array[0]);   // 字符串转数值

                }
            }));
        }

        /// <summary>
        /// 打开关闭串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpenCloseCom_Click(object sender, RoutedEventArgs e)
        {

            if (mSerialPort.IsOpen)
            {
                mSerialPort.Close();
                btnOpenCloseCom.Content = "打开串口";
                Console.WriteLine("关闭串口成功");
                Debug.WriteLine("关闭串口成功");
                comboBoxBaudRate.IsEnabled = true;
                comboBoxCOM.IsEnabled = true;
                comboBoxDataBit.IsEnabled = true;
                comboBoxStopBit.IsEnabled = true;
                comboBoxSdd.IsEnabled = true;
                comboBoxlik.IsEnabled = true;
            }
            else
            {
                mSerialPort.PortName = comboBoxCOM.SelectedItem.ToString();
                mSerialPort.BaudRate = 1000000; // 波特率
                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;

                switch (comboBoxBaudRate.SelectedIndex)
                {
                    case 0:
                        Console.WriteLine("baudrate: 9600");
                        mSerialPort.BaudRate = 9600;
                        break;
                    case 1:
                        mSerialPort.BaudRate = 19200;
                        Console.WriteLine("baudrate: 19200");
                        break;
                    case 2:
                        mSerialPort.BaudRate = 38400;
                        Console.WriteLine("baudrate: 38400");
                        break;
                    case 3:
                        Console.WriteLine("baudrate: 115200");
                        mSerialPort.BaudRate = 115200;
                        break;
                    case 4:
                        Console.WriteLine("baudrate: 1000000");
                        mSerialPort.BaudRate = 1000000;
                        break;
                    default:
                        Console.WriteLine("default baudrate!");
                        mSerialPort.BaudRate = 9600;
                        break;
                }
            
                // mSerialPort.Write("Hello world"); // 写字符串口
                // mSerialPort.Write(new byte[] { 0xA0, 0xB0, 0xC0}, 0, 3); // 写入3个字节数据

                //Debug.WriteLine("Hello world");
                //MessageBox.Show("端口名:" + mSerialPort.PortName);

                try
                {
                    mSerialPort.Open();
                    btnOpenCloseCom.Content = "关闭串口";                  
                    Console.WriteLine("打开串口成功");
                    Debug.WriteLine("打开串口成功");

                    comboBoxBaudRate.IsEnabled = false;
                    comboBoxCOM.IsEnabled = false;
                    comboBoxDataBit.IsEnabled = false;
                    comboBoxStopBit.IsEnabled = false;
                    comboBoxSdd.IsEnabled = false;
                    comboBoxlik.IsEnabled = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        /// <summary>
        /// 清空串口接收数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClearRecv_Click(object sender, RoutedEventArgs e)
        { 
            lineBuilder.Clear();
            textBlockRecv.Text = lineBuilder.ToString();  
        }

        /// <summary>
        /// 串口端口选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBoxCOM_Drop(object sender, DragEventArgs e)
        {
            string[] ports = System.IO.Ports.SerialPort.GetPortNames();
            comboBoxCOM.ItemsSource = ports;
            comboBoxCOM.SelectedIndex = 0;
        }
    }
}

4. 运行效果

在这里插入图片描述

源码下载

源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2129846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 从入门到实战15(字符串其它操作)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们通过举例学习了字符串一些操作说明。今天继续讨论字符…

Java数组08:ArrayList简介

本节内容视频链接&#xff1a; Java关于ArrayList的简单用法与介绍_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1CC4y177CW/?spm_id_from333.337.search-card.all.click&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5Java的ArrayList简介_哔哩哔哩_bilibilihttps:…

Leetcode面试经典150题-27.移除元素

解法都在代码里&#xff0c;不懂就留言或者私信 超级简单的题&#xff0c;一般出现在笔试里&#xff0c;但是不知道为啥字节高频题里会排的那么靠前 class Solution {public int removeElement(int[] nums, int val) {/**如果数组为空&#xff0c;没什么可操作的&#xff0c;…

产业园服务体系建设,是否已全面覆盖企业成长的每一个阶段?

在当今竞争激烈的商业环境中&#xff0c;产业园作为企业发展的重要载体&#xff0c;其服务体系的完善程度至关重要。那么&#xff0c;产业园服务体系建设&#xff0c;是否已全面覆盖企业成长的每一个阶段呢&#xff1f; 从企业的初创期来看&#xff0c;产业园可以提供办公场地的…

【JUC】15-ThreadLocal线程局部变量

1. ThreadLocal ThreadLocal提供线程局部变量。每个线程在访问ThreadLocal实例的时候都有自己的、独立的变量副本。ThreadLocal实例通常是类中的私有静态字段&#xff0c;使用它的目的是希望将状态(用户ID或事务ID)与线程关联起来。 class Saler {ThreadLocal<Integer> …

基于Boost库的搜索引擎开发实践

目录 1.项目相关背景2.宏观原理3.相关技术栈和环境4.正排、倒排索引原理5.去标签和数据清洗模块parser5.1.认识标签5.2.准备数据源5.3.编写数据清洗代码parser5.3.1.编写读取文件Readfile5.3.2.编写分析文件Anafile5.3.2.编写保存清洗后数据SaveHtml5.3.2.测试parser 6.编写索引…

HPM6E00:PWM V2使用指南

先楫推出的HPM6E00系列芯片&#xff0c;PWM功能升级到了V2版本。和V1版本不同的是&#xff0c;V2版本的每组PWM模块包含4个独立的PWM生成模块&#xff0c;每个PWM生成模块包含一个counter和4个比较器&#xff0c;可以生成4组频率不同的PWM波。每个PWM生成模块&#xff0c;对应生…

​​​​通过给定一个全屏的位置得到该位置处是哪一个控件、 遍历窗口中的每一个元素

通过给定一个全屏的位置得到该位置处是哪一个控件&#xff08;以下方法&#xff09; [static] QWidget *QApplication::widgetAt(const QPoint &point) 场景&#xff1a;通过位置获取该位置处的widget后&#xff0c;然后进行判断&#xff0c;是不是某个或某些控件&#x…

韩语中的多义词 (치다)柯桥学韩语到蓝天广场附近

치다 1. 表示用毛笔、铅笔等点点、划线或者绘图。 예: 밑줄을 치다. 划底线 중요한 부분에 동그라미를 쳤다. 在重要的部分画上圆圈。 2. 表示倾倒少量液体或者粉末之类的东西。 예: 싱거우니 소금을 쳐야겠다. 味道淡&#xff0c;得再撒点盐。 기계에 기름을 치다. 给机…

小众创新组合!LightGBM+BO-Transformer-LSTM多变量回归交通流量预测(Matlab)

小众创新组合&#xff01;LightGBMBO-Transformer-LSTM多变量回归交通流量预测(Matlab) 目录 小众创新组合&#xff01;LightGBMBO-Transformer-LSTM多变量回归交通流量预测(Matlab)效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现LightGBMBO-Transformer-L…

陈坤2024行走的力量 走向山野感受距离自然更近的地方

近日&#xff0c;由陈坤发起的心灵建设类项目“行走的力量”在西藏林芝圆满完成&#xff0c;今年陈坤和行者们重返西藏&#xff0c;在海拔3500-4700的高原行走了6天5夜&#xff0c;从城市走向山间&#xff0c;感受自然里的生活&#xff0c;用行走的方式&#xff0c;让自己慢下来…

【C++ Primer Plus习题】15.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream> #include "sales.h"…

第二期: 第三节 裸机代码如何烧写

这个 过程其实 需要在 编写了 驱动之后&#xff0c; 再进行。 因为 要烧写 代码&#xff0c; 你必须 要有一份&#xff0c; 可以烧写的代码。 这里比较重要的是 secureCRT 的安装流程。 这里忘记怎么安装的了。 大致就是 &#xff0c; 先安装 secureCRT , 然后 在破解。不破…

博弈论专题一(NIM游戏)

Nim游戏 重点结论&#xff1a;对于一个Nim游戏的局面(a1,a2,...,an)&#xff0c;它是P-position当且仅当a1^a2^...^an0&#xff0c;其中^表示位异或(xor)运算。 (本篇只做简单的结论描述,详细证明过程请看这篇博客) Nim和 堆物品&#xff0c;每堆 ai 个&#xff0c;两个玩家…

Linux系统:chown命令

1、命令详解&#xff1a; chown命令用于设置文件所有者和文件关联组的命令&#xff0c;全称为change directory。在Linux当中默认文件均有拥有者&#xff0c;可以利用 chown 将指定文件的拥有者改为指定的用户或组&#xff0c;输入参数时用户可以是用户名或者用户 ID&#xff0…

零基础如何学会Appium自动化测试?

前言 appium是一款移动自动化测试工具&#xff0c;经常被用于实现UI自动化测试&#xff0c;其可支持安卓和IOS两大平台&#xff0c;还支持多种编程&#xff0c;因而得到了广泛的应用。此处便是立足于安卓平台&#xff0c;借助appium工具&#xff0c;使用python语言实现简单的自…

GUI编程09:鼠标监听事件、模拟画图工具

视频链接&#xff1a;11、鼠标监听事件、模拟画图工具_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p11&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 模拟画图工具的实现逻辑图&#xff1a; 实现代码&#xff1a; package com.yundait.lesson03;impo…

大模型分离架构学习记录

GPU Direct GPU 网络的情况已经发生了很大变化。每个 GPU 都有自己的内部互联&#xff0c;例如 NVIDIA 的 A100 或 H800&#xff0c;它们内部的 NVLink 互联可以达到 600GB 甚至 900GB。这种内部互联与外部以太网网络集群设计之间存在耦合关系。GPU 是单机多网卡的&#xff0c…

Mini打印机复刻过程(外设绘制)

充电管理 充电管理模块采用ME4054BM5G-N 典型应用电路 ME4054B-N的典型应用电路中&#xff0c;输入为4.5V-6.5V&#xff0c;用于给4.2V的锂电池充电。关键元件包括&#xff1a; LED指示灯&#xff1a;通过1kΩ电阻限流&#xff0c;显示充电状态。2kΩ电阻&#xff08;PROG引脚…

视频孪生市场有望达千亿级

近日&#xff0c;中国互联网协会数字孪生技术工委会副主任委员、智汇云舟创始人兼总裁周舟对数字孪生技术的市场潜力与发展前景进行了深度剖析。她表示&#xff0c;在国家政策与全球数字化转型的双重推动下&#xff0c;数字孪生技术发展迅速&#xff0c;市场潜力巨大&#xff0…