485通讯与MODBUS的区别与联系

2023-11-06

最近做智能检测的项目,设备、串口之间的通讯比较多,一会儿485,一会儿modbus RTU,有点晕了,这里重新梳理一下RS485、485通讯协议、ModBus通讯协议、Modbus Rtu通讯这几个点的联系和区别。

先说RS485吧,RS485是一个工业常用的物理接口,是物理层的硬件设备(串口)。是在电脑设置上看得到的(windows系统-我的电脑-设备管理器)设备。

Modbus是一种国际标准的通讯协议,一般用于不同厂商设备之间进行数据交换,是应用层的软件协议,不能自己单独存在,必须要依赖于硬件设备作为实现平台。不同的硬件具有不同的电气特性和连接方式,比如RS232、RS485。可以把Modbus比作英语,RS232比作印度人,RS485比作美国人,印度人之间讲英语时,理解为基于RS232的modbus通信,美国人之间讲英语时,理解为基于RS485的modbus通信。

两台设备之间通过Modbus协议传输数据,需要硬件接口,于是就有了RS232\RS422\RS485等,其中RS485传输距离远,成为现在最主流的工业现场硬件接口。

Modbus按照一般维度分为Modbus Rtu、Modbus ASCII、Modbus TCP三种模式。

从接口类型维度来说,Modbus Rtu和ASCII基于串行链路,属于串行通讯口(serial port),Mobus tcp基于TCP/IP协议,属于网络(以太网)通讯口。

协议分为硬件协议和软件协议。而通讯协议属于软件协议,它包含报头包围的格式,MODBUS是应用层的通讯协议,主要用于传送和接收文件包的格式。而RS232,RS485是物理层的串行接口,它可以支持几十种通讯协议,MODBUS只是其中的一种。

Modbus的特征:(1) 主从协议方式(master/slave)

                           (2) 通讯规约:初始结构-地址码-功能码-数据区-校验码-结束结构

                           (3) modbus协议本质是对寄存器读写,通过指定寄存器地址,来交换数据

写了一大堆概念性的东西,现在在面对实际问题,以下是供应商给出来的一句话:

大概需求是我需要通过485串口,给供应商的设备发送一个速度信号,这个速度信号的格式要求,是485格式,波特率、奇偶校验、8个数据位这些就不用再说了,了解下串口基础就知道了,一般都是N81,即“无奇偶校验、8个数据位、1个停止位”,问题的关键在于这个“485格式”。RS485做为一个标准串口通讯,是有自己的标准通信格式的。

可以看到,跟modbus是有些相似的,除了自己的格式外,也可以选择遵循Modbus通讯规约,更多的是使用modbus RTU模式通讯格式。

上图是modbus rtu的通讯规约,接下里的任务,是搞懂485通讯规约和modbus rtu通讯规约的区别,两种格式到底区别在哪里。为什么供应商选择用485格式,而不是使用的更广泛的modbus rtu?这两者之间的优缺点又分别是什么?

补充1:

所谓rs485通讯协议,属于硬件层协议。硬件层管什么呢?决定数据如何传输,比如2进制的数只有0和1,那么如果1个字节现在是"0110 0011",现在这个字节里的0怎么传输和表达,1怎么传输和表达,比如rs232就规定了电压x伏就表示0,y伏表示1。再比如要选择多少条线来传输,选择什么材质的线来传输,这就是硬件层协议规定的事情。

同样RS485通讯协议也是个硬件层协议,实际上是关于电平、电压的约定。搞软件的不一定看得懂,特别是应用层软件。

比如这样,再比如这样,亦或是这样反正我是看不懂的

但是我弄清楚了什么叫所谓的RS485通讯协议,是硬件的、关于电平、电压的,一个规约,跟应用软件没半毛钱关系。

补充2(2020.12.14):

起始我纠结了半天,就是被串口通讯和modbus rtu搞晕了,一周之后回过头来看,就显得有点笨,但是还是硬着头皮补充完整吧。

串口通讯和Modbus rtu的有哪些区别,又有哪些共同点呢?

从概念上来说,都是串口,rtu起始就是基于串口的,所以共同点就是,rtu和串口通讯,都要设置波特率、数据位、停止位、奇偶校验等

    // 波特率常量
    private final static int  BAUD_RATE   = 9600;
    // 广播地址
    // private final static int broadcast_SLAVE_ADDRESS = 0;
    // 数据位
    private final static int  DATABITS_8  = 8;
    // 停止位
    private final static int  STOPBITS_1  = 1;
    // 奇偶校验
    private final static int  PARITY_NONE = 0;

不同点是,串口通讯需要串口对象,而modbus需要从机地址(设备地址),如果是广播模式就需要广播地址,一般是0。

// MODBUS的设备(从机)地址。 默认为254, 但由于本设备不支持254的地址,所以需要修改设备的地址为1.
    private final static int        SLAVE_ADDRESS = 1;
    // 广播地址
    private final static int        broadcast_SLAVE_ADDRESS = 0;

下面贴一段经典的,串口程序,第一段是打开串口,第二段是往串口发送数据的

public static final SerialPort openPort(String portName, int baudrate) throws PortInUseException {
        try {
            // 通过端口名识别端口
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            // 打开端口,并给端口名字和一个timeout(打开操作的超时时间)
            CommPort commPort = portIdentifier.open(portName, 2000);
            // 判断是不是串口
            if (commPort instanceof SerialPort) {
                SerialPort serialPort = (SerialPort) commPort;
                try {
                    // 设置一下串口的波特率等参数
                    // 数据位:8
                    // 停止位:1
                    // 校验位:None
                    serialPort.setSerialPortParams(baudrate, SerialPortManager.DATABITS_8, SerialPortManager.STOPBITS_1,
                            SerialPortManager.PARITY_NONE);
                } catch (UnsupportedCommOperationException e) {
                    e.printStackTrace();
                }
                return serialPort;
            }
        } catch (NoSuchPortException e1) {
            e1.printStackTrace();
        }
        return null;
    }

入参是串口名称和波特率。返回值是实体对象。

 public static void sendToPort(SerialPort serialPort, byte[] order) {
        OutputStream out = null;
        try {
            out = serialPort.getOutputStream();
            out.write(order);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                    out = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

入参是串口对象实体,即第一段打开串口代码的返回值。用的是outPutStream,输出流。

而modbus rtu是怎么实现串口打开和发送呢,起始modbus只是基于串口,本质上还是主从机之间的通讯。

// 实例化ModBus工厂
        ModbusFactory modbusFactory = new ModbusFactory();
        ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);

跟SerialPort实体类似,ModbusMaster是个主机对象,当你将其init()的时候,在modbus角度你开启了主机,其实就是打开了串口。

modbus的发送不用赘述,基本就是遵循modbus的格式,功能码、寄存器地址、寄存器数量、数据位等等。例如16功能码,代表写入多个连续保持寄存器,支持广播模式。

这是16码的格式:

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

485通讯与MODBUS的区别与联系 的相关文章

  • LabVIEW串口通信实际操作

    理论基础 LabVIEW串口通信基础知识 读取串口字节 我们新建一个空白 VI 借助串口调试助手和虚拟串口 在 LabVIEW 中编写的一个最简单的例子 写一个基本的读取串口字节的程序 在程序框图中编程如下 注意这里 串口配置放到循环外 不
  • STM32双串口

    STM32双串口的使用 最近老是需要stm32通过串口去跟WiFi模块 蓝牙模块 openmv进行数据交互 然后需要用到stm32的串口调试 就把这个程序整理成一个工程 方便调试 实验目的 外设模块 WiFi模块 蓝牙模块 openmv 发
  • 获取windows中活跃的Com口

    获取windows中活跃的Com口 记录于2021年11月9日 今天对我来说是个很特殊的一天 母胎SOLO二十一周年 无奈 Orz 闲暇之余写下此文章 记录一下我的日常 文章目录 获取windows中活跃的Com口 前言 一 如何寻找活跃C
  • qt5.10 串口通信 QSerialPort 的使用

    在qt5中 使用QSerialPort进行串口通信 主要用到的QSerialPort 使用步骤 步骤一 在 pro文件中进行声明 QT serialport 在 pro文件中添加这个声明 步骤二 实例化 QSrerialPort QSeri
  • Modbus常用功能码协议详解

    Modbus常用功能码协议详解 01H 读线圈状态 1 描述 读从机线圈寄存器 位操作 可读单个或者多个 2 发送指令 假设从机地址位0x01 寄存器开始地址0x0023 寄存器结束抵制0x0038 总共读取21个线圈 协议图如下 3 响应
  • Arduino基础篇(五)-- 如何快速上手串口通信(Serial)

    文章目录 1 基础篇 1 1 通信基础 2 串口通信 2 1 Arduino串口的硬件结构 2 2 串口工作原理 2 3 硬件串口通信 2 4 软件模拟串口通信 1 基础篇 1 1 通信基础 1 并行通信 通过输入 输出端口在 Arduin
  • Modbus驱动库—libmodbus驱动库的使用

    文章目录 为什么要使用驱动库 libmodbus简介 libmodbus常用函数 Windows平台libmodbus 使用 1 获取源代码 2 生成config h配置文件 3 编写测试代码 4 编译测试代码 Linux平台下libmod
  • 蓝桥杯51单片机之数码管从点亮到动态时钟的实现【单片机开发初学者必掌握】

    文章目录 一 点亮数码管 二 八位数码管同时从0到F 三 显示学号 指定数字 四 中断机制的引入 五 利用中断实现动态时钟 一 点亮数码管 首先看一下案例源码 include
  • STM32菜鸟成长记录——移植FreeModbusRTU

    本文章用于记录学习RS485及配置Modbus协议 参考博文 FreeModbus移植文章1 FreeModbus移植文章2
  • 51单片机之串口通讯应用实例(逻辑分析仪调试)

    硬件 STC89C52RC 开发工具 Keil uVision4 前言 8051是一款很经典的 历史悠久的单片机 作为一款入门级的单片机8051受到很多初学者的欢迎 89c52是8051系列的成员之一 拥有8K字节程序存储空间 512字节随
  • 小记stm32实现串口接收的四种方法(hal库)

    开发环境 STM32CUBMX 正点原子STM32F407ZGT6探索者开发板 MDK ARM 5 31 第一种方式 直接接收 配置外部时钟源 2 配置时钟树 3 配置串口一 生产代码后进入工程 重定向printf到串口1 建议在usart
  • 奇偶校验位

    在串行通信中 奇偶校验位通常是由UART这样的接口硬件生成 校验的 在接收方 通过接口硬件中的寄存器的状态位传给 CPU 以及操作系统 错误数据的恢复通常是通过重新发送数据 这个过程通常由如操作系统输入输出程序这样的软件处理的
  • QT开发遇到的问题(1)——程序循环执行的问题

    我之前一直直接用C 开发工程 有需求需要跨平台开发 前期使用时候感觉还可以 转到工程应用时候 就遇到好多坑 今天就遇到个大坑 在开发时候需要不断循环一块代码来实现某种功能 QT不像C 那种 这个更加专业 下面我对这个问题进行详细说明分析 问
  • 数字电路的时钟(1)-- 时钟抖动和分类

    时钟抖动通常分为时间间隔误差 Time Interval Error 简称TIE 又叫相位抖动 周期抖动 Period Jitter 和相邻周期抖动 cycle to cycle jitter 三种抖动 TIE又称为phase jitter
  • HMI智能串口屏——在STM32开发板上的实战应用及其详解

    HMI智能串口屏 在STM32开发板上的实战应用及其详解 一 HMI智能串口屏使用步骤 二 附录 一 HMI智能串口屏使用步骤 安装USART HMI软件 一般买的串口屏里面 商家送的资料里面都有改该软件 打开软件 并点击左上角的 新建 选
  • Modbus 错误:[输入/输出] 未收到来自远程设备的响应

    我尝试从 Mac 笔记本电脑连接到 Modbus 设备 MR SI4 使用串行连接 使用 USB RS485 转换器 安装 到 dev cu SLAB USBtoUART 这是我的代码 import logging logging basi
  • 计算 Modbus RTU CRC 16

    我正在实现一个软件 可以通过串行方式读取和写入 Modbus RTU 协议中的数据 为此 我需要计算字节字符串末尾的两个 CRC 字节 但我无法执行此操作 在网上搜索 我发现两个函数似乎可以正确计算 CRC WORD CRC16 const
  • 将两个原始值转换为 32 位 IEEE 浮点数

    我正在尝试通过 TCP modbus 解码来自 Shark 100 功率计的一些数据 我已经成功地拉下了我需要的寄存器 并从寄存器中留下了两个原始值 如下所示 17138 59381 从手册中 我知道我需要将这两个数字转换为32位IEEE浮
  • 计算 modbus RTU 3.5 字符时间

    我是 Modbus 新手 正在使用 Modbus RTU 开发应用程序 我想知道如何找出RTU消息帧分离时间 在Modbus RTU规范中 它提到了3 5个字符时间 但是没有更多关于如何决定这个间隔的数据 计算分离时间的步骤是什么 看看第1
  • 我可以在输入寄存器中写入吗? MODBUS

    我已经在一家公司工作了两个月MODBUS项目现在我发现了一个问题 我的客户要求我写入输入寄存器 地址 30001 到 40000 我认为这对我来说不是什么问题 因为每个modbus文档说 30001 到 40000 寄存器是只读的 甚至可以

随机推荐

  • Windows11 文件选择打开方式时卡死 解决

    发生的现象 在 打开方式 窗口的地址栏粘贴应用的地址 gt 打开方式界面卡死 完整步骤 左键点击打开epub文件 gt 跳出 寻找一个应用以打开此 epub文件 gt 选择 在电脑上选择应用 gt 弹出 打开方式 窗口 gt 在 打开方式
  • ❤ 15个基于Vue3.0全家桶的优秀开源项目

    15个基于Vue3 0全家桶的优秀开源项目 Vue Admin Better github https github com chuzhixin vue admin better vue admin better 对比其他来源 admin
  • 雨停了,我将雨伞收起

    天空中已有阳光从厚重的云层间隙射向大地 我将手中的雨伞收起 伞面上留存着的雨滴正沿着伞面的褶皱流下打在地上 我望向远方 一辆汽车沿着自己的轨迹行驶 路边小坑中的积水在车轮的驱赶下纷纷跳上灌木丛的绿叶寻找庇护 一阵清脆的自行车铃在身后响起 一
  • Android BaseQuickAdapter万能适配器

    RecycleView万能适配器 一导入 implementation com github CymChad BaseRecyclerViewAdapterHelper 2 9 24 implementation com android s
  • spring-kafka并行度concurrency在应用集群部署(多个节点)正确设置,附上Kafka Manager监控效果

    我们都知道kafka有topic的概念 为了能够更好的支持水平扩容 topic又分了很多的Partition 消费者负责消费Partition中的消息 一个Partition只能被一个消费者消费 但是一个消费者可以消费多个partition
  • zotero与Obsidian联动笔记(二):zotero拖拽highlights的格式修改

    文章目录 zotero拖拽highlights的格式修改 zotero拖拽highlights的格式修改 方法 两种格式的文本 p highlight quotes true citation comment p blockquote hi
  • unity 3D RPG教程(一)

    目录 声明 1 Create Project 2 Build Level 3 PolyBrush 发挥创意构建场景 4 Navigation 智能导航地图烘焙 5 MouseManager 鼠标控制人物移动 声明 本教程学习均来自U3D中文
  • mysql中ddl语句有哪些_什么是 DDL 语言?其中包括哪些语句?

    展开全部 DDL一般指数据定义语32313133353236313431303231363533e4b893e5b19e31333431373937言 数据库模式定义语言DDL Data Definition Language 是用于描述数
  • 华为OD机试 - 跳格子游戏(Java)

    题目描述 地上共有N个格子 你需要跳完地上所有的格子 但是格子间是有强依赖关系的 跳完前一个格子后 后续的格子才会被开启 格子间的依赖关系由多组steps数组给出 steps 0 表示前一个格子 steps 1 表示steps 0 可以开启
  • C++(14):函数返回类型auto推导

    C 11可以通过结合auto和decltype来动态的声明函数的返回值类型 include
  • plt.style.use设置背景样式

    利用matplotlib绘图设置背景 使用到plt style use 时 对这个参数做一下小结 matplotlib 使用某种样式 plt style use 参数可以是一个 URL 或者路径 指向自己定义的 mplstyle 文件 可以
  • 翁凯c语言作业8-3

    include
  • Vue初始化在HBuilderx中快速搭建

    HBuilderx快速新建VUE项目 一 安装HBuilderx开发工具 官网 HBuilderx HBuilderXH是HTML的第一个字母 Builder是builder X是HBuilder的下一个版本 我们也被称为HX HBuild
  • 01.minio基本介绍搭建使用

    MinIO 是一款基于 Go 语言的高性能 可扩展 云原生支持 操作简单 开源的分布式对象存储产品 官网 https min io 特点 高性能 作为高性能对象存储 在标准硬件条件下它能达到55GB s的读 35GG s的写速率 可扩容 不
  • 随机生成6位随机数(字母+数字)

    package com test public class test public static void main String args String randomcode 用字符数组的方式随机 String model 0123456
  • 人生应该接受的教育

    以下三段话 或许会让你的人生发生一些变化 如果有心改变 一切都不晚 一 比尔 盖茨告诉我们 1 社会充满不公平现象 你先不要想去改造它 只能先适应它 因为你管不了它 2 世界不会在意你的自尊 人们看的只是你的成就 在你没有成就以前 切勿过分
  • openssl基本原理及生成证书

    openssl基本原理及生成证书 openssl基本原理及生成证书 1 基本原理 2 生成证书 一 生成CA证书 1 创建私钥 2 创建证书请求 3 自签署证书 4 将证书导出成浏览器支持的 p12格式 二 生成server证书 1 创建私
  • 6套粒子群算法(内含matlab代码)

    粒子群算法 1 粒子群算法简介 一 粒子群算法的历史 粒子群算法源于复杂适应系统 Complex Adaptive System CAS CAS理论于1994年正式提出 CAS中的成员称为主体 比如研究鸟群系统 每个鸟在这个系统中就称为主体
  • 【C#】如何比较两个对象是否相等(重写Equals方法)

    问题 写单元测试时 需要对比两个对象是否相等 如果使用Assert AreEqual mockclass1 class1 永远无法通过 原因 这里使用了object默认的Equals方法 必须要引用同一个对象 才会返回true 默认的Equ
  • 485通讯与MODBUS的区别与联系

    最近做智能检测的项目 设备 串口之间的通讯比较多 一会儿485 一会儿modbus RTU 有点晕了 这里重新梳理一下RS485 485通讯协议 ModBus通讯协议 Modbus Rtu通讯这几个点的联系和区别 先说RS485吧 RS48