C#实现串口通信

2023-11-14

背景

在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。串口通信方便易行,应用广泛。一般情况下,工控机和各智能仪表通过RS485总线进行通信。RS485的通信方式是半双工的。在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活。其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。

串口通信的步骤:

       (1) 打开串口
       (2) 配置串口
       (3) 读写串口
       (4) 关闭串口

所用的技术:

从Microsoft .Net 2.0版本以后,就默认提供了System.IO.Ports.SerialPort类,用户可以非常简单地编写少量代码就完成串口的信息收发程序

串口端口号搜索

           //检查是否含有串口
            string[] str = SerialPort.GetPortNames();
            if (str == null)
            {
                MessageBox.Show("本机没有串口!", "Error");
                return;
            }
            //添加串口
            foreach (string s in str)
            {
                comboBoxCom.Items.Add(s);
            }

初始化

Control.CheckForIllegalCrossThreadCalls = false;
            serialPort.DataReceived += new SerialDataReceivedEventHandler(dataReceived);


            //准备就绪              
            serialPort.DtrEnable = true;
            serialPort.RtsEnable = true;
            //设置数据读取超时为1秒
            serialPort.ReadTimeout = 1000;

            serialPort.Close();

 

打开串口

 if (!serialPort.IsOpen)//串口处于关闭状态
            {
                
                try
                {
                    
                    if (comboBoxCom.SelectedIndex == -1)
                    {
                        MessageBox.Show("Error: 无效的端口,请重新选择", "Error");
                        return;
                    }
                    string strSerialName    = comboBoxCom.SelectedItem.ToString();
                    string strBaudRate      = comboBoxBaudRate.SelectedItem.ToString();
                    string strDataBit       = comboBoxDataBit.SelectedItem.ToString();
                    string strCheckBit      = comboBoxCheckBit.SelectedItem.ToString();
                    string strStopBit       = comboBoxStopBit.SelectedItem.ToString();

                    Int32 iBaudRate = Convert.ToInt32(strBaudRate);
                    Int32 iDataBit  = Convert.ToInt32(strDataBit);

                    serialPort.PortName = strSerialName;//串口号
                    serialPort.BaudRate = iBaudRate;//波特率
                    serialPort.DataBits = iDataBit;//数据位                    
                   serialPort.StopBits = StopBits.One; //停止位
                        
                  serialPort.Parity = Parity.Odd;//校验位
                

                    if (saveDataFile != null)
                    {
                        saveDataFS = File.Create(saveDataFile);
                    }

                    //打开串口
                    serialPort.Open();

                    //打开串口后设置将不再有效
                    comboBoxCom.Enabled = false;
                    comboBoxBaudRate.Enabled = false;
                    comboBoxDataBit.Enabled = false;
                    comboBoxCheckBit.Enabled = false;
                    comboBoxStopBit.Enabled = false;
                    radioButtonSendDataASCII.Enabled = false;
                    radioButtonSendDataHex.Enabled = false;
                    radioButtonReceiveDataASCII.Enabled = false;
                    radioButtonReceiveDataHEX.Enabled = false;
                    buttonSendData.Enabled = true;
                    Button_Refresh.Enabled = false;

                    buttonOpenCloseCom.Text = "关闭串口";

                }
                catch(System.Exception ex)
                {
                    MessageBox.Show("Error:" + ex.Message, "Error");
                    return;
                }

 

关闭串口

 else //串口处于打开状态
            {
                
                serialPort.Close();//关闭串口
                //串口关闭时设置有效
                comboBoxCom.Enabled = true;
                comboBoxBaudRate.Enabled = true;
                comboBoxDataBit.Enabled = true;
                comboBoxCheckBit.Enabled = true;
                comboBoxStopBit.Enabled = true;
                radioButtonSendDataASCII.Enabled = true;
                radioButtonSendDataHex.Enabled = true;
                radioButtonReceiveDataASCII.Enabled = true;
                radioButtonReceiveDataHEX.Enabled = true;
                buttonSendData.Enabled = false;
                Button_Refresh.Enabled = true;

                buttonOpenCloseCom.Text = "打开串口";

                if (saveDataFS != null)
                {
                    saveDataFS.Close(); // 关闭文件
                    saveDataFS = null;//释放文件句柄
                }

            }

接收数据

if (radioButtonReceiveDataASCII.Checked == true) //接收格式为ASCII
                {
                    try
                    {
                        String input = serialPort.ReadLine();
                        textBoxReceive.Text += input + "\r\n";
                        // save data to file
                        if (saveDataFS != null)
                        {
                            byte[] info = new UTF8Encoding(true).GetBytes(input + "\r\n");
                            saveDataFS.Write(info, 0, info.Length);
                        }
                    }
                    catch(System.Exception ex)
                    {
                        MessageBox.Show(ex.Message, "你波特率是不是有问题???");
                        return;
                    }

发送数据

 if (!serialPort.IsOpen)
            {
                MessageBox.Show("请先打开串口", "Error");
                return;
            }

            String strSend = textBoxSend.Text;//发送框数据
            if (radioButtonSendDataASCII.Checked == true)//以字符串 ASCII 发送
            {
                serialPort.WriteLine(strSend);//发送一行数据 

            }
            else
            {
                //16进制数据格式 HXE 发送
                 
                char[] values = strSend.ToCharArray();
                foreach (char letter in values)
                {
                    // Get the integral value of the character.
                    int value = Convert.ToInt32(letter);
                    // Convert the decimal value to a hexadecimal value in string form.
                    string hexIutput = String.Format("{0:X}", value);
                    serialPort.WriteLine(hexIutput);

                }



            }

工程地址:


https://github.com/naihaishy/SerialPort-Communication

参考:

https://blog.csdn.net/newbie_xymt/article/details/80600721

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#实现串口通信 的相关文章

  • 基层技术管理工作思考?

    从动机和方法两方面谈谈我的看法 动机 要做好基层技术管理工作 首先要确保自己有良好的动机 即明白自己为何要走上技术管理岗位 做管理的根本是为了获得权力 但获得权力的动机却存在很大的差别 第一种单纯是为了利己 有相当数量的人往技术管理岗位 挤
  • Electron-vue脚手架改造vue项目(2018.11.13更新)

    文章中涉及vue项目都是基于vu cli快速构建 展示的目录结构是vue cli快速构建之后的目录 Electron vue也是基于vue cli的脚手架工具 小伙伴们自己构建的vue项目想要改造成桌面应用 还请移步 Electron将We
  • 《大型网站技术架构》第二篇 架构-高可用

    高可用在公司中的重要性 对公司而言 可用性关系网站的生死存亡 对个人而言 可用性关系到自己的绩效升迁 工程师对架构做了许多优化 对代码做了很多重构 对性能 扩展性 伸缩性做了很多改善 但别人未必能直观地感受到 也许你的直接领导都不知道你做的
  • GPS采集设备命令

    经纬度简介 经度 具体来说就是地球上一个地点距离一根被称为本初子午线的南北方向走线以东或以西的度数 按国际规定英国首都伦敦格林尼治天文台原址的那一条经线定为0 经线 从0 经线算起 向东 向西各分作180 以东的180 属于东经 用 E 作
  • cURL简单使用、libcurl编程, curl_easy_setopt

    更多关于curl的信息可以参考官网http curl haxx se http curl haxx se libcurl c curl easy setopt html CURLcodecurl easy setopt CURL handl
  • Java-集合(LinkedList类)

    简单介绍 1 LinkedList底层实现了双向链表和双端队列特点 2 可以添加任意元素 元素可重复 包括null 3 线程不安全 没有实现同步 底层操作机制 1 LinkedList底层维护了一个双向链表 2 LinkedList中维护了

随机推荐

  • java字符串判空失败

    那你就快放弃使用 equals lkm 或 lkm isEmpty 进行判空吧 最牛逼判空方法 StringUtils isEmpty lkm 判空失败还有一种可能 基本用什么方法判空都会失败 使用String value 进行转换的判空
  • Python调用ImageMagick生成PDF文件缩略图

    使用Python调用ImageMagick生成PDF文件缩略图 Imagemagick使用Ghostscript作为其依赖项之一 以便能够处理和转换PDF相关的图像 准备 安装Ghostscript 网站 安装ImageMagick 网站
  • 计算机上开发和运行应用程序与操作系统无关,计算机期中测验理论部分和答案-C.doc...

    计算机期中测验理论部分和答案 C 一 判断题 共10分 正确填写T 反之填写F 1 Cache和主存储器虽然都是用半导体芯片作为存储介质 但前者使用SRAM 后者使用DRAM 前者比后者的存取速度快 正确答案 T 2 当一个应用程序窗口被最
  • Spring中比较常用的工具类

    清单 1 BeanDefinitionReaderUtils registerBeanDefinition 往spring容器注册一个beanDefinition 2 PropertiesLoaderUtils loadAllPropert
  • timm库(CV利器)的入门教程(1)

    省流 使用timm加载CNN进行图像分类 调整CNN使之更适合你的任务 问 使用timm搭建一个可以使用的CNN或ViT拢共需要几步 答 4步 0 安装 timm 1 import timm 2 创建model 3 运行model 这一节很
  • 二叉搜索树(树状数组)

    计数函数 程序 int lowbit int k return k k 功能 可视为每个节点的编号函数 加和函数 程序 int sum int x int ret 0 while x gt 0 ret c x x lowbit x retu
  • jmeter提取token后只能使用一次的鬼问题

    今天在测试一个内部接口时 需要先登录传入token 按照正常步骤作对应参数化和参数传递 过程略 提取token的方法有很多 这里我是用的是正则表达式 提了就正常用嘛 可发现不管下边添加了多少请求 同一线程组下 永远只有登录请求的下一个可以获
  • linux常用函数和知识点博文合集

    signal SIGCHLD SIG IGN 和signal SIGPIPE SIG IGN 中断产生EINTR错误 linux中sigaction函数详解 标准I O函数库提供了popen函数 它启动另外一个进程去执行一个shell命令行
  • 2023秋招算法题每日学习(4)

    DAY 4 1 AcWing 850 Dijkstra求最短路 ii 考察点 堆优化Dijkstra 求最短路问题 适合于稀疏图 利用邻接表来存储 邻接表不需要对重边做特殊的处理 1 基础知识 时间复杂度分析 堆优化Dijkstra 堆优化
  • JUST技术:利用迁移学习生成新城市的轨迹

    市民的出行轨迹数据无论是对于城市管理 规划 还是商业活动 都是重要的参考信息 然而 获取一个城市的人群轨迹数据却非常困难 在今年4月份召开的国际顶级互联网会议WWW 2020 CCF A类 上 京东城市报告了被会议收录的论文 What is
  • 解决安装强化学习库gymnasium,box2d安装报错的问题

    gymnasium是强化学习的库 比较难安装 一 安装方法 安装Gymnasium 一定要all 这样可以安装所有依赖 pip install gymnasium all pip install gymnasium all 二 报错信息一
  • Docker安装记录

    1 卸载旧版本 yum remove docker docker client docker client latest docker common docker latest docker latest logrotate docker
  • Git版本控制

    Git 版本控制 什么是版本控制 版本控制是一种开发的过程中用于管理我们对文件 目录或工程等内容的修改历史 方便查看更改历史记录 备份以便恢复以前的版本的软件工程技术 实现跨区域多人协同开发 追踪和机载一个或者多个文件的历史记录 组织和保护
  • 成功解决VMware安装操作系统出现分辨率的问题

    文章目录 问题重现 问题原因 问题解决 方法一 拓展 1 电脑分辨率 2 xrandr命令 3 查询后如果没有合适的分辨率解决方案 参考资料 问题重现 如下图 在VMware16上安装ubuntu操作系统的时候 出现分辨率问题 导致底部的按
  • < 面试知识点:什么是 Node.js ?有哪些优缺点?应用场景? >

    文章目录 一 什么是 Node js 二 Node js 有哪些优缺点 三 Node js 能做什么 四 Node js 的 模块系统 五 Node js 应用场景 参考文献 往期内容 一 什么是 Node js Node js 是一个开源
  • 微信小程序如何获取微信昵称和头像

  • MySQL 高可用:mysql+mycat实现数据库分片(分库分表)

    什么是MYCAT 一个彻底开源的 面向企业应用开发的大数据库集群 支持事务 ACID 可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库 用来替代昂贵的Oracle集群 一个融合内存缓存技术 NoSQL技术 HDFS
  • Docker入门命令详解

    目录 一 Docker 简介 1 Docker引擎 2 Docker客户端 3 Docker镜像 4 Docker容器 5 Docker镜像注册中心 二 Docker的特点 1 快速运行 2 节省资源 3 便于交付 4 容易管理 三 Doc
  • C语言有小数乘法,十道小数乘小数的乘法竖式计算并有答案

    十道小数乘小数的乘法竖式计算并有答案以下文字资料是由 历史新知网www lishixinzhi com 小编为大家搜集整理后发布的内容 让我们赶快一起来看一下吧 十道小数乘小数的乘法竖式计算并有答案 6 5 8 4 56 1 3 3 2 2
  • C#实现串口通信

    背景 在工业控制中 工控机 一般都基于Windows平台 经常需要与智能仪表通过串口进行通信 串口通信方便易行 应用广泛 一般情况下 工控机和各智能仪表通过RS485总线进行通信 RS485的通信方式是半双工的 在Win32下 可以使用两种