C#开发串口通信实例及串口基础

一、串口通信简介

       串行接口(串口)是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。

       串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。

  1. 波特率:这是一个衡量符号传输速率的参数。指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数,如每秒钟传送960个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为960Bd,比特率为10位*960个/秒=9600bps。

  2. 数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。标准的ASCII码是0~127(7位),扩展的ASCII码是0~255(8位)。

  3. 停止位:用于表示单个包的最后几位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。

  4. 校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。

二、C#串口编程类

       从.NET Framework 2.0开始,C#提供了SerialPort类用于实现串口控制。命名空间:System.IO.Ports。其中详细成员介绍参看MSDN文档。下面介绍其常用的字段、方法和事件。

  1. 常用字段:

名称说明
PortName获取或设置通信端口
BaudRate获取或设置串行波特率
DataBits获取或设置每个字节的标准数据位长度
Parity获取或设置奇偶校验检查协议
StopBits获取或设置每个字节的标准停止位数

2. 常用方法:

名称说明
Close关闭端口连接,将 IsOpen 属性设置为 false,并释放内部 Stream 对象
GetPortNames获取当前计算机的串行端口名称数组
Open打开一个新的串行端口连接
Read从 SerialPort 输入缓冲区中读取
Write 将数据写入串行端口输出缓冲区

3. 常用事件:

名称说明
DataReceived表示将处理 SerialPort 对象的数据接收事件的方法

三、C#开发串口实例

前台页面:

84630f1daf677b62744a088123fe2e9e.png

 后台代码:

using System;

using System.IO.Ports;

using System.Text;

using System.Windows.Forms;

namespace SerialPort

{

    public partial class SerialPort : Form

    {

        String serialPortName;

        public SerialPort()

        {

            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)

        {

            string[] ports = System.IO.Ports.SerialPort.GetPortNames();//获取电脑上可用串口号

            comboBox1.Items.AddRange(ports);//给comboBox1添加数据

            comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//如果里面有数据,显示第0个

            comboBox2.Text = "115200";/*默认波特率:115200*/

            comboBox3.Text = "1";/*默认停止位:1*/

            comboBox4.Text = "8";/*默认数据位:8*/

            comboBox5.Text = "无";/*默认奇偶校验位:无*/

        }

        private void button1_Click(object sender, EventArgs e)

        {

            if (button1.Text == "打开串口"){//如果按钮显示的是打开

                try{//防止意外错误

                    serialPort1.PortName = comboBox1.Text;//获取comboBox1要打开的串口号

                    serialPortName = comboBox1.Text;

                    serialPort1.BaudRate = int.Parse(comboBox2.Text);//获取comboBox2选择的波特率

                    serialPort1.DataBits = int.Parse(comboBox4.Text);//设置数据位

                    /*设置停止位*/

                    if (comboBox3.Text == "1") { serialPort1.StopBits = StopBits.One; }

                    else if (comboBox3.Text == "1.5") { serialPort1.StopBits = StopBits.OnePointFive; }

                    else if (comboBox3.Text == "2") { serialPort1.StopBits = StopBits.Two; }

                    /*设置奇偶校验*/

                    if (comboBox5.Text == "无") { serialPort1.Parity = Parity.None; }

                    else if (comboBox5.Text == "奇校验") { serialPort1.Parity = Parity.Odd; }

                    else if (comboBox5.Text == "偶校验") { serialPort1.Parity = Parity.Even; }

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

                    button1.Text = "关闭串口";//按钮显示关闭串口

                }

                catch (Exception err)

                {

                    MessageBox.Show("打开失败"+ err.ToString(), "提示!");//对话框显示打开失败

                }

            }

            else{//要关闭串口

                try{//防止意外错误

                    serialPort1.Close();//关闭串口

                }

                catch (Exception){}

                button1.Text = "打开串口";//按钮显示打开

            }

        }

        protected override void WndProc(ref Message m)

        {

            if (m.Msg == 0x0219){//设备改变

                if (m.WParam.ToInt32() == 0x8004){//usb串口拔出

                    string[] ports = System.IO.Ports.SerialPort.GetPortNames();//重新获取串口

                    comboBox1.Items.Clear();//清除comboBox里面的数据

                    comboBox1.Items.AddRange(ports);//给comboBox1添加数据

                    if (button1.Text == "关闭串口"){//用户打开过串口

                        if (!serialPort1.IsOpen){//用户打开的串口被关闭:说明热插拔是用户打开的串口

                            button1.Text = "打开串口";

                            serialPort1.Dispose();//释放掉原先的串口资源

                            comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//显示获取的第一个串口号

                        }

                        else{

                            comboBox1.Text = serialPortName;//显示用户打开的那个串口号

                        }

                    }

                    else{//用户没有打开过串口

                        comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//显示获取的第一个串口号

                    }

                }

                else if (m.WParam.ToInt32() == 0x8000){//usb串口连接上

                    string[] ports = System.IO.Ports.SerialPort.GetPortNames();//重新获取串口

                    comboBox1.Items.Clear();

                    comboBox1.Items.AddRange(ports);

                    if (button1.Text == "关闭串口"){//用户打开过一个串口

                        comboBox1.Text = serialPortName;//显示用户打开的那个串口号

                    }

                    else{

                        comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;//显示获取的第一个串口号

                    }

                }

            }

            base.WndProc(ref m);

        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)

        {

            int len = serialPort1.BytesToRead;//获取可以读取的字节数

            byte[] buff = new byte[len];//创建缓存数据数组

            serialPort1.Read(buff, 0, len);//把数据读取到buff数组

            Invoke((new Action(() =>{//C# 3.0以后代替委托的新方法

                    textBox1.AppendText(Encoding.Default.GetString(buff));//对话框追加显示数据

            })));

        }

        private void button2_Click(object sender, EventArgs e)

        {

            textBox1.Clear();//清除接收对话框显示的数据

        }

        private void button3_Click(object sender, EventArgs e)

        {

            String Str = textBox2.Text.ToString();//获取发送文本框里面的数据

            try

            {

                if (Str.Length > 0)

                {

                        serialPort1.Write(Str);//串口发送数据

                }

            }

            catch (Exception){ }

        }

        private void button4_Click(object sender, EventArgs e)

        {

            textBox2.Clear();//清除发送文本框里面的内容

        }

    }

}

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

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

相关文章

javascript权威指南--学习笔记

-一、JavaScript基本数据类型 1、数字--Number类 2、字符串--String类 3、布尔--Boolean类 4、函数Function 5、对象Object 6、数组Array 7、null 8、undefined 备注: 当一个未定义的值用于布尔环境,他就会转为false,用于数字环境就会转为…

Robot Framework 教程 (3) - Resource及关键字 的使用

From:http://www.cnblogs.com/buaawp/p/4754399.html Robot Framework 教程 (3) - Resource及关键字 的使用 在进行软件自动化测试时,我们设计并编写好一个测试脚本的业务逻辑之后,需要将其中的业务数据提取为变量,并对业务逻辑进行封装。在后…

Maven基础:Maven环境搭建及基本使用(1)

1. Maven环境搭建 1.1 Maven简介 1.2 Maven下载及环境设置 Maven下载地址:http://maven.apache.org/download.cgi 当前下载版本:apache-maven-3.5.0-bin.zip,解压之后路径 D:\Program Files\apache-maven-3.5.0 Maven环境变量设置&#xff1a…

解读微软开源MMLSpark:统一的大规模机器学习生态系统

AI前线导读:目前,有很多深度学习框架支持与Spark集成,如Tensorflow on Spark等。然而,微软开源的MMLSpark不仅集成了机器学习框架(CNTK深度学习计算框架、LightGBM机器学习框架),还可以将这些计…

floyd判环算法(龟兔赛跑算法)

floyd判环算法(龟兔赛跑算法) 注意,这个算法是用来判断一条链一条环的图,环的长度或者环与链的交界处的,所以此floyd非彼floyd(虽然都是一个人想出来的)。 (图不是我的) …

一个redis的连接库的实现

2019独角兽企业重金招聘Python工程师标准>>> import socketdef format_message( args):"""Create redis message:param args:Message data"""l u"*%d" % len(args)lines [l.encode(utf-8)]for arg in args:if not isinst…

实现CSS在线美化(格式化)、压缩、加密、解密、混淆工具-toolfk程序员工具网

本文要推荐的[ToolFk]是一款程序员经常使用的线上免费测试工具箱,ToolFk 特色是专注于程序员日常的开发工具,不用安装任何软件,只要把内容贴上按一个执行按钮,就能获取到想要的内容结果。ToolFk还支持 BarCode条形码在线生成、 QueryList采集…

[ci]jenkins server启动,通过jnlp的方式启动slave(容器模式)

jenkins server启动,通过jnlp的方式启动slave. java -jar jenkins.jar 配置jnlp端口--全局安全 配置云 配置项目 执行成功 转载于:https://www.cnblogs.com/iiiiher/p/7978831.html

php实现文件留言,PHP文件操作及实例:留言板

一、文件操作函数1.创建文件:touch(./xxx.php);bool touch ( string $filename [, int $time time() [, int $atime ]] )2.复制文件:copy(./xxx.php,./yyy.php);3.移动或重命名:rename(./xxx.php,./yyy.php);4.删除文件:unlink(.…

个人总结的一个中高级Java开发工程师或架构师需要掌握的一些技能...

近三年,其实都是在做一个项目,项目是一个大型的多节点部署的项目,做了好几个版本,中间用到了很多技术和框架, 也用了一些管理工具和敏捷实践。我这里不是来说项目的,因为最近看了一些招聘信息,结…

Android 进程常驻(5)----开机广播的简单守护以及总结

这是一个轻量级的库,配置几行代码。就能够实如今android上实现进程常驻,也就是在系统强杀下,以及360获取root权限下。clean master获取root权限下都无法杀死进程 支持系统2.3到6.0 支持大部分设备,包含三星。华为。oppo&#xff0…

[k8s]metricbeat的kubernetes模块kube-metric模块

正确姿势启动metricbeat metricbeat.modules: - module: systemmetricsets:- cpu- filesystem- memory- network- processenabled: trueperiod: 10sprocesses: [.*]cpu_ticks: falseoutput.elasticsearch:hosts: ["http://192.168.x.x:9200"]setup.template.name: &q…

Animate与transform的使用

Animate是用css给前端加载动画的效果&#xff1a; 网址&#xff1a;https://daneden.github.io/animate.css/ <!DOCTYPE html> <html lang"en"> <head><link rel"stylesheet" href"static/css/Animate.css"><meta ch…

ASP.NET Core 6框架揭秘实例演示[29]:搭建文件服务器

通过HTTP请求获取的Web资源很多都来源于存储在服务器磁盘上的静态文件。对于ASP.NET应用来说&#xff0c;如果将静态文件存储到约定的目录下&#xff0c;绝大部分文件类型都是可以通过Web的形式对外发布的。“Microsoft.AspNetCore.StaticFiles” 这个NuGet包中提供了三个用来处…

【我们一起写框架】C#的AOP框架

原文:【我们一起写框架】C#的AOP框架前言 AOP&#xff0c;大家都是听过的&#xff0c;它是一种面向切面的设计模式。 不过AOP虽然是被称为设计模式&#xff0c;但我们应该很少能看到AOP设计的框架。为什么呢&#xff1f; 因为&#xff0c;AOP单独设计的框架几乎是无法使用的。普…

新浪微博授权认证过程

为什么80%的码农都做不了架构师&#xff1f;>>> 一、授权认证 1、请求用户授权Token URL&#xff1a; https://api.weibo.com/oauth2/authorize HTTP请求方式:GET/POST 请求参数 必选 类型及范围 说明 client_id true string 申请应用时分配的AppKey。 redire…

VisualStudio 使用 FastTunnel 辅助搭建远程调试环境

有时候需要远程调试一些用户问题&#xff0c;期望能使用本机的 Visual Studio 开发环境&#xff0c;调试远程的用户的设备上的应用。这时会遇到的一个问题是如何让本机的 Visual Studio 可以连接上远程的用户的设备&#xff0c;从而进行调试。本文将告诉大家如何采用 FastTunne…

Python1

python介绍python是一种解释型的&#xff0c;面对对象的。带有动态语义的高级程序设计语言python简史1989年,Guido(龟叔)为ABC 语言写的一个插件。因Monty Python的喜剧团体的原因,故给这个语言起名为python。linux也是1989年诞生的,1991年正式发布linux1.0内核;1990年, 发布py…

ncut算法matlab实现,ncut_multiscale_1_6 经典的图像分割算法 的Matlab代码。 238万源代码下载- www.pudn.com...

文件名称: ncut_multiscale_1_6下载收藏√ [5 4 3 2 1 ]开发工具: matlab文件大小: 587 KB上传时间: 2015-04-17下载次数: 4提 供 者: HH详细说明&#xff1a;经典的图像分割算法NCut的Matlab代码。-Matlab code of classic image segmentation algorithm NCut .文件列表(…

使用.NET从零实现基于用户角色的访问权限控制

使用.NET从零实现基于用户角色的访问权限控制本文将介绍如何实现一个基于.NET RBAC 权限管理系统&#xff0c;如果您不想了解原理&#xff0c;可查看推送的另一篇文章关于Sang.AspNetCore.RoleBasedAuthorization[1] 库是使用介绍&#xff0c;直接使用该库即可。背景在设计系统…