C#-串口通信入门及进阶扩展

news2024/11/27 10:31:31

目录

一、串口相关参数介绍

1、端口(COM口)

2、波特率(Baud rate)

3、起始位

4、停止位(StopBits)

5、数据位

6、校验位

7、缓存区

二、串口通信助手

三、虚拟串口工具

四、进阶扩展 

1、位运算

2、负数、浮点数存储方式 

3、数据校验算法

3.1、奇偶校验

3.2、LRC

3.3、累加和校验

3.4、CRC

介绍 

常用多项式表

CRC-8

CRC-16

CRC-32

CRC-USB

4、Modbus通信协议

4.1、介绍 

4.2、Modbus-RTU


串口通讯(Serial Communication),是指外设和计算机间,通过数据信号线、地线等,按位进行传输数据的一种双向通讯方式。

串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的通信协议,通信协议很多,可根据实际情况选择和自定义。

一、串口相关参数介绍

1、端口(COM口)

CMO口(Communication Module Outlet)是一种用于连接计算机和外部设备的接口,也称为串行端口,简称CMO口,常见串口通讯有一般电脑应用的RS-232(使用 25 针或 9 针连接器)和工业电脑应用的半双工RS-485与全双工RS-422。

电脑端口查看:设置->系统->关于->设备管理器->端口

2、波特率(Baud rate)

波特率是一个电子信号上的术语,用于描述信道的数据传输速度。

单位是bit/s,常见的9600波特率表示每秒传输9600个比特位,1个字节8位,9600/8=1200,代表每秒钟串口可传输1200个字节(不考虑起始位、停止位、校验位的情况下),注意:

  1. 波特率如果太高会导致传输数据不稳定,一般使用9600;
  2.  发送端与接收端波特率不一致会导致数据不一致;

3、起始位

起始位必须是持续一个比特时间的逻辑0电平,标志传输一个字符的开始,接收方可用起始位使自己的接收时钟与发送方的数据同步;

C#开发中一般不需要设置起始位。

4、停止位(StopBits)

停止位可以是是1位、1.5位或2位,可以由软件设定,它一定是逻辑1电平,标志着传输一个字符的结束;

C#开发中一般通过StopBits枚举类型设置停止位,枚举值包括None、One、Two、OnePointFive四种(通常若设备不指定,默认停止位为1位)。

5、数据位

数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定,一般可以是5位、7位或8位;

C#开发中若设备不指定,默认数据位为8位

6、校验位

校验位仅占一位,用于进行奇校验或偶校验,检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位;如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位;

C#开发中通常使用Parity枚举类型来设置校验位,有五种,日常开发中使用最多的是None无校验、Odd奇校验、Even偶校验。

7、缓存区

串口包括两个缓存区,发送缓存区和接收缓存区;

发送缓存区:(软件)发送数据时将数据先存在发送缓存区,再通过(硬件)串口发送出去;

接收缓存区:接收数据时先将数据存在接收缓存区,(软件)再从中读取数据;

二、串口通信助手

串口通信助手是用于测试和调试串口通信的工具,可通过串口与外部设备通信,提供界面来监视和控制串口数据的接收和发送,从而验证串口通信是否正常工作。

实现一个串口通信助手示例:C#Wpf-实现串口通信助手

分享一个串口通信助手,下载地址:友善串口通信助手

                                        提取码: h64y

三、虚拟串口工具

下载地址:VSPD

提取码:a2cp

破解说明:运行vspd.exe 安装,安装后先不运行,将 vspdctl.dll 文件放入工程目录中,覆盖原文件,即完成破解。

使用说明:点击Add Pair按钮添加虚拟COM口连接对,即可。

四、进阶扩展 

1、位运算

符号意义逻辑介绍示例
~逻辑非取反~a
&逻辑与清0a&b
|逻辑或置1a|b
<<按位左移,超出舍掉乘以2的n次方a<<n
>>按位右移,超出舍掉除以2的n次方a>>n
^异或不同置1,相同清0a^b

  三次异或,可使变量值互换,示例如下:

int a = 13;
int b = 20;
a ^= b;
b ^= a;
a ^= b;
Console.WriteLine($"a:{a}b:{b}");

2、负数、浮点数存储方式 

负数在计算机中是以补码的形式存储,补码计算方式:

  1. 最高位为符号位,负数符号位为1,正数为0;
  2. 除符号位,所有位取反得到反码;
  3. 反码+1得到补码;

浮点数一般分为单精度与双精度两种,在计算机中的存储方式通常分为三部分:

  1. 符号位:正数为0,负数为1;
  2. 指数位:用于存储科学计数法中的指数部分;
  3. 小数位:用于表示小数部分,不足补0

单精度float格式:

符号位指数位小数位
1bit8bits23bits

双精度double格式:

符号位指数位小数位
1bit11bits52bits

float示例:

8.25转化为二进制表示为:整数部分除2取余,小数部分乘2取整,得到1000.01

科学计数法表示为1.00001*2的3次方,指数为3(指数范围为-126-127),为消除负数影响,得到的指数+127,得130,即指数1000 0010,小数:00001,存储格式如下: 

符号位指数位小数位
01000 0010000 0100 0000 0000 0000 0000

3、数据校验算法

由于数据传输距离的因素影响,计算机和受控设备间的通信数据常常出现不可预知的错误,为了避免错误带来的影响,通常会在通信时对数据进行校验。

3.1、奇偶校验

每8位加一个奇偶校验位,

奇校验:若数据位中1的数量为偶数,则校验位置1凑齐奇数个1,反之置0;

偶校验:若数据为中1的数量为奇数,则校验位置1凑齐偶数个1,反之置0;

缺点:减慢传输速率,偶数个错误时检测不出(出错率五五开);

3.2、LRC

纵向冗余校验(Longitudinal Redundancy Check,LRC),又称逐字节奇偶校验,将数据依字节为单位纵向排列,所有字节相同位全部异或(奇数个1为1,反之为0),计算出一个字节的结果。

缺点:纵向偶数个错误时检测不出;

3.3、累加和校验

将数据的每个字节的值相加,其结果减去255的倍数(控制在0-255区间),然后放在数据最后,接收方接收数据后累加和后与校验值比对;

单个字符出错率1/256

3.4、CRC
介绍 

CRC,循环冗余校验,使用的算法思想为除法,将余数作为校验值放在数据末尾;

模二除法(二进制的除法),CRC实际就是模二除法的升级版,通过借位(位移),将余数补在原数据末尾,以此来消掉余数。(接收端将修改后的数据与生成项模二相除没有余数即代表数据无误)

CRC除数叫生成多项式,又称生成项,不同的生成项有不同的CRC,如:CRC8、CRC16、CRC-USB、CRC32……。(二进制转多项式:数字中多少位1代表的是x的多少次方)

模二除法举例: 

模二借位举例:

常用多项式表

CRC-8

CRC-8,8位校验码,适用于对数据简单校验的场景,常见的应用领域包括遥控器、智能家居等,示例如下:

    public static byte CalcCrc8(byte[] data)
    {
        byte crc = 0x00;
        byte polynomial = 0x8C; // CRC-8 多项式
        foreach (byte b in data)
        {
            crc ^= b;
            for (int i = 0; i < 8; i++)
            {
                if ((crc & 0x80) != 0)
                {
                    crc = (byte)((crc << 1) ^ polynomial);
                }
                else
                {
                    crc <<= 1;
                }
            }
        }
        return crc;
    }
CRC-16

CRC-16,16位校验码,适用于中等程度校验场景,常见的应用领域包括Modbus通信协议、SD卡存储等,示例如下:

    public static ushort CalcCrc16(byte[] data)
    {
        ushort crc = 0xFFFF;
        ushort polynomial = 0xA001; // CRC-16 多项式
        foreach (byte b in data)
        {
            crc ^= (ushort)(b << 8);
            for (int i = 0; i < 8; i++)
            {
                if ((crc & 0x01) == 0x01)
                {
                    crc >>= 1;
                    crc ^= polynomial;
                }
                else
                {
                    crc >>= 1;
                }
            }
        }
        return crc;
    }
CRC-32

CRC-32,32位校验码,适用于对数据需高强度校验的场景,常见的应用领域包括网络通信、文件传输、数据库存储等,示例如下:

    public static uint CalcCrc32(byte[] data)
    {
        uint crc = 0xFFFFFFFF;
        uint polynomial = 0xEDB88320; // CRC-32 多项式
        foreach (byte b in data)
        {
            crc ^= b;
            for (int i = 0; i < 8; i++)
            {
                if ((crc & 0x00000001) != 0)
                {
                    crc = (crc >> 1) ^ polynomial;
                }
                else
                {
                    crc >>= 1;
                }
            }
        }
        return ~crc;
    }
CRC-USB

CRC-USB,CRC特殊算法之一,适用于USB接口,例如USB 1.1、USB 2.0等协议中的数据校验,示例如下: 

    public static uint CalcCrcUsb(byte[] data)
    {
        uint crc = 0xFFFFFFFF;
        uint polynomial = 0x04C11DB7; // USB 多项式
        foreach (byte b in data)
        {
            crc ^= (uint)(b << 24);
            for (int i = 0; i < 8; i++)
            {
                if ((crc & 0x80000000) != 0)
                {
                    crc = (crc << 1) ^ polynomial;
                }
                else
                {
                    crc <<= 1;
                }
            }
        }
        return ~crc;
    }

4、Modbus通信协议

4.1、介绍 

Modbus,串行通信协议,属于OSI七层模型中的应用层,最初设计用于可编程逻辑控制器(PLC),Modbus是一种开放式协议,物理层支持使用RS232/RS485/RS422协议的串行设备,同时还支持调制解调器;

Modbus通过设备之间的串行线进行数据传输最简单的设置是使用一根串行电缆连接两个设备(主设备和从设备)上的串行端口;

Modbus遵循主从模式通信,实现主站与一个(单播)或多个(广播)从站交换报文数据,通信由主机发起,一问一答式,从设备无法主动向主机发送数据。

常用类别有Modbus-RTU、Modbus-ASCII、Modbus-TCP,这里主要介绍Modbus-RTU;

4.2、Modbus-RTU

报文格式:

地址码功能码数据CRC-16
1字节1字节n字节2字节

地址码:0为主机广播地址,1-247为从机地址,248-255保留;

功能码:常用功能码如下表:

代码

名称

作用

01

读取线圈状态

取得一组逻辑线圈的当前状态(ON/OFF)

02

读取输入状态

取得一组开关输入的当前状态(ON/OFF)

03

读取保持寄存器

在一个或多个保持寄存器中取得当前的二进制值

04

读取输入寄存器

在一个或多个输入寄存器中取得当前的二进制值

05

强置(写)单线圈

强置一个逻辑线圈的通断状态

06

预置(写)单寄存器

放置一个特定的二进制值到一个单寄存器中

07

读取异常状态

取得8个内部线圈的通断状态

15

强置(写)多线圈

强置一串连续逻辑线圈的通断

16

预置(写)多寄存器

放置一系列特定的二进制值到一系列多寄存器中

17

报告从机标识

可使主机判断编址从机的类型及该从机运行指示灯的状态

数据:通常包括起始地址、数据长度或数据,都为大端模式(低位存于高地址);

CRC校验:通常使用16位校验码,采用小端模式(低位存于低地址);

Modbus-Rtu报文封装示例(仅供参考)

        /// <summary>
        /// MODEBUS_RTU通信数据
        /// </summary>
        /// <param name="devadress">地址码</param>
        /// <param name="funccode">功能码</param>
        /// <param name="paraadress">读/写参数代号地址(起始地址)</param>
        /// <param name="value">读取数据长度或写数据值</param>
        /// <returns></returns>
        public static List<byte> GetModbusData(byte devadress, byte funccode, int paraadress, int value)
        {
            List<byte> data = new List<byte>()
            {
                devadress,
                funccode,
            };

            var high = (paraadress & 0xFF00) >> 8;//高8位
            var low = paraadress & 0xFF;//低8位
            data.Add(Convert.ToByte(high));
            data.Add(Convert.ToByte(low));

            high = (value & 0xFF00) >> 8;
            low = value & 0xFF;
            data.Add(Convert.ToByte(high));
            data.Add(Convert.ToByte(low));

            var res = Crc16.CRC16(data.ToArray());//16位校验
            high = (res & 0xFF00) >> 8;
            low = res & 0xFF;
            data.Add(Convert.ToByte(low));
            data.Add(Convert.ToByte(high));

            return data;
        }

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

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

相关文章

Sui根据资源使用情况,使gas费计量更公平

Sui的大规模并行处理需要新的方式思考gas费&#xff0c;即网络上处理交易的成本。在我们的工作中&#xff0c;我们研究计算成本和指令处理&#xff0c;以设计一种最佳的gas费机制。准确评估gas费不仅可以提供公平的网络分摊成本和健康的运营业务模型&#xff0c;还鼓励开发人员…

算法通关第十七关黄金挑战——透析跳跃问题

大家好&#xff0c;我是怒码少年小码。 本篇是贪心思想的跳跃问题专题&#xff0c;跳跃问题出现的频率很高。 跳跃游戏 LeetCode 55&#xff1a;给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。 …

java第20章节

一.线程简介 二.创建线程 1.继承Thread类 Thread类中常用的两个构造方法如下&#xff1a; public Thread():创建一个新的线程对象。 public Thread(String threadName):创建一个名称为threadName的线程对象。 继承Thread类创建一个新的线程的语法如下&#xff1a; public c…

网关路由器双栈配置中的IPv6相关选项解析

1、引言 讲知识往往是枯燥无味的&#xff0c;我们先从问题入手。家庭网关&#xff08;光猫&#xff09;、路由器是我们每个人或多或少都有所接触的2种设备。现在一般都是光纤入户&#xff0c;通常每个家庭配备一个光猫和一台家用路由器。 目前有许多网络服务已经提供了IPv6支…

视频监控管理平台/智能监测/检测系统EasyCVR设备列表显示不全是什么原因?该如何解决?

GB28181视频监控国标平台/视频云存储/安防监控EasyCVR视频汇聚平台&#xff0c;基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。智慧安防视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视…

java中反射知识点概念

这里写自定义目录标题 1.什么是反射--动态注入&#xff1f;2.反射的诞生背景3.反射的意义4.反射后可以做些什么5.反射相关的主要API6.反射的优缺点7.反射和不反射基础使用8.工厂模式使用反射8.1首先我们来看看不使用反射的情况&#xff1a;8.2使用反射的情况&#xff1a; 9.Jav…

【springboot】idea项目启动端口被占用

问题 idea本地启动springboot项目端口老是被占用 解决 关闭被占用的端口进程 步骤: 1. winR打开程序框 2. 查出被占用端口的进程id netstat -ano | finderstr 端口号 例如 netstat -ano | finderstr 81013.杀死进程 taskkill /pid 进程id -t -f 例如 taskkill /pid 2…

1688 API接口的介绍丨商品详情页接口丨搜索商品列表接口

1688&#xff0c;作为中国领先的B2B电子商务平台&#xff0c;为全球的买家和卖家提供了一站式的采购和销售服务。而它的API接口&#xff0c;更是开放了1688平台的核心功能&#xff0c;让开发者能够根据自己的需求来定制和扩展商业应用。 1688 API接口的介绍 1688 API接口提供…

使用影刀指令+python实现简单的长文本乱序加密

本文意在利用影刀指令python代码&#xff0c;实现一种较为简单的长文本加密和解密&#xff0c;流程结构分为两步&#xff1a; 加密原理–是把字符转为列表&#xff0c;利用列表random模块中的shuffle函数做随机乱序。解密原理–是利用了列表的索引追踪&#xff0c;先前创建字典…

Vue3-目录调整

默认生成的目录结构不满足我们的开发需求&#xff0c;所以这里需要做一些自定义改动。 主要是以下工作&#xff1a; 1.删除一些初始化的默认文件 2.修改剩余代码内容 3.新增调整我们需要的目录结构 在src文件夹下创建两个新文件夹&#xff0c;一个叫api&#xff08;请求模…

re:Invent 2023:PingCAP 荣获亚马逊云科技 2023 年度合作伙伴奖项

2023 年 11 月 27 日 – 12 月 1 日&#xff0c; 2023 亚马逊云科技 re:Invent 在拉斯维加斯举办&#xff0c;亚马逊云科技合作伙伴奖项在合作伙伴颁奖晚会上颁布&#xff0c; PingCAP 荣获亚马逊云科技大中华区 “2023 年度 ISV 合作伙伴” 和 “2023 年度亚马逊云科技 Market…

dockerfile文件:copy和add 异同

相同点&#xff1a; 复制文件或目录&#xff1a; 无论是 COPY 还是 ADD 都可以将文件或目录从构建上下文复制到容器中。支持源路径和目标路径&#xff1a; 两者都需要指定源路径和目标路径&#xff0c;用于指定要复制的文件或目录在主机上的位置以及在容器中的目标路径。 不同…

Re0: 从零实现一个置顶任意窗口的小工具

前言 话不多说&#xff0c;先上效果&#xff1a; 这里展示的是通过下拉框选择窗口&#xff0c;让窗口显示并置顶&#xff0c;其实还可以直接通过快捷键&#xff08;先鼠标点击要置顶的窗口&#xff0c;再使用CTRLSHIFTT&#xff09;&#xff0c;本文涉及到的完整代码已上传到G…

【开源】基于Vue+SpringBoot的智能教学资源库系统

项目编号&#xff1a; S 050 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S050&#xff0c;文末获取源码。} 项目编号&#xff1a;S050&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

现代风客餐阳台开放式一体布局,设计亮点。福州中宅装饰,福州装修

在现代家居设计中&#xff0c;开放式布局越来越受到欢迎。它不仅可以提升家居的空间感&#xff0c;还可以促进家人之间的交流和互动。这个客厅、餐厅、阳台一体化的设计&#xff0c;更是充分利用了空间&#xff0c;具有多重亮点。 01.玄关到客厅嵌入式一体式收纳柜 玄关是进入…

全国高校走进深算院:共话国产数据库产教融合生态建设

近日&#xff0c;由教育部高等学校计算机类专业教学指导委员会、全国高等学校计算机教育研究会主办&#xff0c;清华大学出版社、深圳市信息技术应用创新联盟承办的“2023全国高校走进信创企业研学活动”顺利举办。来自全国各地30余家高校的近80位院校领导、教师代表走进了深圳…

windows启动后直接进入指定程序并且不显示欢迎界面和windows桌面

windows启动后直接进入指定程序并且不显示欢迎界面和windows桌面 前言开机进入指定程序方法问题 浅尝GINA和Credential Providers关闭欢迎屏幕 前言 由于系统需求需要做到电脑开机后显示完windows加载页面就直接进入自己系统的界面&#xff0c;并且不显示登录欢迎页面&#xf…

【收藏】SNMP介绍及使用

热门IT课程-视频教程&#xff1a;文章浏览阅读49次。认证课程介绍&#xff1a;华为HCIA试听课程 &#xff1a; 华为HCIA试听课程&#xff1a;华为HCIA试听课程&#xff1a;华为HCIP试听课程&#xff1a;思科CCNA试听课程&#xff1a;思科CCNA试听课程&#xff1a;思科CCNA试听课…

0x00000709一键修复的解决办法,0x00000709错误的原因

在使用打印机时&#xff0c;你可能会遇到一些错误代码&#xff0c;其中之一是0x00000709。这个错误代码表示无法设置默认打印机。如果你遇到这样的问题不用担心&#xff01;这篇文章将为你提供0x00000709一键修复的解决办法&#xff0c;帮助你解决0x00000709错误&#xff0c;并…

京东API接口的接入(京东工业)

在技术交流群&#xff0c;大家有探讨稳定获取京东商品主图、价格、标题&#xff0c;及sku的完整解决方案。这个引起了我技术挑战的兴趣。 目前&#xff0c;自己做了压测&#xff0c;QPS高、出滑块概率极低&#xff0c;API整体稳定&#xff0c;可满足业务场景的性能需求。 公共…