首页 > 其他分享 >Modbus_RTU和Modbus库

Modbus_RTU和Modbus库

时间:2024-09-19 19:24:22浏览次数:12  
标签:RTU int ctx Modbus modbus 寄存器

目录

一.Modbus_RTU

1.  与Modbus TCP的区别

2.  Modbus RTU特点

     3.  Modbus RTU协议格式

4.  报文详解

5.  代码实现RTU通信

1.  打开模拟的RTU从机

2.  linux端使用代码实现和串口连接

2.1.  框架搭建

          2.2 代码

二.Modbus库

1.库函数


一.Modbus_RTU

1.  与Modbus TCP的区别

在一般工业场景使用modbus RTU的场景还是更多一些,modbus RTU基于串行协议进行收发数据,包括RS232/485等工业总线协议。

与modbus TCP不同的是RTU没有报文头MBAP字段,保留从机地址,在尾部增加了两个CRC检验字节(CRC16),因为网络协议中自带校验,所以在 ModbusTCP协议中不需要使用CRC校验码。

RTU和TCP的总体使用方法基本一致,只是在创建modbus对象时有所不同,TCP需要传入网络socket信息;而RTU需要传入串口相关信息。

2.  Modbus RTU特点

Modbus RTU也是主从问答协议,由主机发起,一问一答

     3.  Modbus RTU协议格式

ModbusRTU数据帧包含:从站地址 功能码 数据 CRC校验码

地址码:从机ID

功能码:同TCP

数据:起始地址 数量 数据

校验码:2个字节,对 地址码 功能码 数据进行校验,可以通过函数自动生成

4.  报文详解

03功能码为例

主机--》从机

01 03 00 00 00 01 84 0A

01 : 从机地址

03:功能码,读取保持寄存器

00 00 :起始地址

00 01:读取的个数,1个。

84 0A:CRC校验码

从机---》主机

01 03 02 00 14 B4 44

01:从机地址

03:功能码

02:字节计数

00 14:数据

B4 44 :CRC校验码

5.  代码实现RTU通信

1.  打开模拟RTU从机

2.  linux使用代码实现串口连接

2.1.  框架搭建

1.  打开COM1口

打开串口文件( /dev/ttyS1)

2.  串口初始化

使用专用函数即可

3.  创建要发送的03功能数组

4.  根据所要实现的功能,拼接好数组

5.  加上CRC校验码

6.  串口发送----向串口文件写数据

7.  串口接收----读取串口文件

8.  打印收到的数据

          2.2 代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include "Crc_Calc.h"
#include <unistd.h>

int main(int argc, char const *argv[])
{
// 1.打开COM1口
// 打开串口文件( /dev/ttyS1)
    int fd=open("/dev/ttyS1",O_RDWR);
    if (fd < 0)
    {
        perror("open err");
        return -1;
    }
// 2.串口初始化
    uart_init(fd);// 使用专用函数即可
// 3.创建要发送的03功能数组
// 4.根据所要实现的功能,拼接好数组
    //RTU 01 03 00 00 00 01
    uint8_t req[12]={0x01,0x03,0x00,0x00,0x00,0x01};
    uint8_t buf[32]={0};
// 5.加上CRC校验码
    uint16_t Crc;
    Crc=GetCRC16(req,6);//CRC=5;
    req[6]=Crc >> 8;  // y=CRC+1; 
    req[7]=Crc; 
// 6.串口发送----向串口文件写数据
    write(fd,req,8);
// 7.串口接收----读取串口文件
    int ret=read(fd,buf,sizeof(buf));
// 8.打印收到的数据
    for (int i = 0; i < ret; i++)
    {
        printf("%02x ",buf[i]);
    }
    putchar(10);
    return 0;
}

二.Modbus库

1.库函数

modbus_t* ctx=  modbus_new_tcp(const char *ip, int port)
功能:以TCP方式创建Modbus实例,并初始化
参数:
    ip   :ip地址
    port:端口号
返回值:成功:Modbus实例
      失败:NULL
int modbus_set_slave(modbus_t *ctx, int slave)
功能:设置从机ID
参数:
    ctx   :Modbus实例
    slave:从机ID
返回值:成功:0
       失败:-1
int   modbus_connect(modbus_t *ctx)
功能:和从机(slave)建立连接
参数:
    ctx:Modbus实例
返回值:成功:0
       失败:-1
int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能:读取线圈状态,可读取多个连续线圈的状态(对应功能码为0x01)
参数:
    ctx   :Modbus实例
    addr :寄存器起始地址
    nb    :寄存器个数
    dest :得到的状态值
int  modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能:读取离散输入状态,可读取多个连续输入的状态(对应功能码为0x02)
参数:
    ctx   :Modbus实例
    addr :寄存器起始地址
    nb   :寄存器个数
    dest :得到的状态值
返回值:成功:返回nb的值
int  modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能:读取保持寄存器的值,可读取多个连续保持寄存器的值(对应功能码为0x03)
参数:
    ctx   :Modbus实例
    addr :寄存器起始地址
    nb    :寄存器个数
    dest :得到的寄存器的值
返回值:成功:读到寄存器的个数
       失败:-1
int   modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能:读输入寄存器的值,可读取多个连续输入寄存器的值(对应功能码为0x04)
参数:
    ctx   :Modbus实例
    addr :寄存器起始地址
    nb    :寄存器个数
    dest :得到的寄存器的值
返回值:成功:读到寄存器的个数
       失败:-1
int  modbus_write_bit(modbus_t *ctx, int addr, int status);
功能:写入单个线圈的状态(对应功能码为0x05)
参数:
    ctx     :Modbus实例
    addr  :线圈地址
    status:线圈状态
返回值:成功:0
      失败:-1
int  modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);
功能:写入多个连续线圈的状态(对应功能码为15)
参数:
    ctx     :Modbus实例
    addr  :线圈地址
    nb     :线圈个数
    src    :多个线圈状态 
返回值:成功:0
      失败:-1
int  modbus_write_register(modbus_t *ctx, int addr, int value);
功能:  写入单个寄存器(对应功能码为0x06)
参数: 
    ctx    :Modbus实例
    addr  :寄存器地址
    value :寄存器的值 
返回值:成功:0
       失败:-1
int  modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);
功能:写入多个连续寄存器(对应功能码为16)
参数:
    ctx    :Modbus实例
    addr  :寄存器地址
    nb     :寄存器的个数
    src    :多个寄存器的值 
返回值:成功:0
      失败:-1

void   modbus_free(modbus_t *ctx)
功能:释放Modbus实例
参数:ctx:Modbus实例
void   modbus_close(modbus_t *ctx)
功能:关闭套接字
参数:ctx:Modbus实例

练习:使用库函数实现03功能码

#include<modbus.h>
#include<modbus-tcp.h>
#include<stdio.h>

int main(int argc, char const *argv[])
{
    if (argc != 2)
    {
        printf("usage:<ip>\n");
        return -1;
    }
    //1.创建实例
    modbus_t * ctx=modbus_new_tcp(argv[1],502);
    //2.设置从机ID
    modbus_set_slave(ctx,1);
    //3.创建连接
    modbus_connect(ctx);
    //4.03功能码函数
    uint16_t dest[8]={0};
    modbus_read_registers(ctx, 0, 2, dest);
    //5.打印
    for (int i = 0; i < 2; i++)
    {
        printf("%d ",dest[i]);
    }
    putchar(10);
    return 0;
}

标签:RTU,int,ctx,Modbus,modbus,寄存器
From: https://blog.csdn.net/qq_64136247/article/details/142367098

相关文章

  • Modbus RTU
    一、与ModbusTCP的区别在一般工业场景使用modbusRTU的场景还是更多一些,modbusRTU基于串行协议进行收发数据,包括RS232/485等工业总线协议。与modbusTCP不同的是RTU没有报文头MBAP字段,保留从机地址,在尾部增加了两个CRC检验字节(CRC16),因为网络协议中自带校验,所以在ModbusTC......
  • MET AD688 SQL for E-Commerce Startups
    METAD688Assignment2SQLforE-CommerceStartupsAssignmentObjective:Youhaverecentlyjoinedane-commercestartup,"ShopSmart,"whichsellsvariousproductsonline.Thecompanyhasbeengrowing,buttheyarefacingchallengeswithundersta......
  • ModbusTCP报文详解
    ModbusTCP与ModbusRtu(ASCI)数据帧的区别总结:ModbusTCP就是在ModbusRtu(ASCI)基础上去掉CRC,再加上六个0一个6ModbusTCPMBAP报文头域长度描述客户机服务器事务处理标识符2字节Modbus请求/响应事务处理的识别客户机启动服务器从接收的请求中重新复制协议标识符2字节0=M......
  • modbus
    一、起源Modbus由Modicon公司于1979年开发,是一种工业现场总线协议标准。Modbus通信协议具有多个变种,其中有支持串口,以太网多个版本,其中最著名的是ModbusRTU、ModbusASCII和ModbusTCP三种其中ModbusTCP是在施耐德收购Modicon后1997年发布的。二、分类1)ModbusRTU......
  • 手车投屏三:VirtualDisplay
    手机端app投屏到车机端,并接收触摸事件处理的方案:一、手机端实现1.创建VirtualDisplay步骤:使用DisplayManager的createVirtualDisplay方法创建一个VirtualDisplay实例。在创建时,需要指定显示名称、尺寸、密度DPI以及一个Surface对象。Surface选择:通常,这个Surface可以是一......
  • VirtualBox 7.1.0 发布下载 - 开源跨平台虚拟化软件
    VirtualBox7.1.0发布下载-开源跨平台虚拟化软件VirtualBox7.1.0(macOS,Linux,Windows)-开源跨平台虚拟化软件OracleVMVirtualBox7请访问原文链接:https://sysin.org/blog/virtualbox-7/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2024年9月11......
  • 【YashanDB知识库】YAS-02025 no free space in virtual memory pool
    本文转自YashanDB官网,具体内容请见[https://www.yashandb.com/newsinfo/7304719.html?templateId=1718516]【标题】YAS-02025nofreespaceinvirtualmemorypool【问题分类】业务SQL执行【关键字】YAS-02025【问题描述】在崖山环境查询数据提示报错YAS-02025nofreespa......
  • modbus调试助手/mqtt调试工具/超轻巧物联网组件/多线程实时采集/各种协议支持
    一、前言说明搞物联网开发很多年,用的最多的当属modbus协议,一个稳定好用的物联网组件是物联网平台持续运行多年的基石,所以这个物联网组件从一开始就定位于自研,为了满足各种场景的需求,当然最重要的一点就是大大提升了自己对该协议的深度理解和应用,尤其是面对各种场景需求,逐步调整迭......
  • 终于有人把Modbus讲明白了5i
    合集-上位机开发(2)1.终于有人把Modbus讲明白了09-132.RS485与ModbusRTU09-10:westworld加速收起大家好!我是付工。2012年开始接触Modbus协议,至今已经有10多年了,从开始的懵懂,到后来的顿悟,再到现在的开悟,它始终岿然不动,变化的是我对它的认知和理解。今天跟大家聊聊关于Modbus协......
  • 终于有人把Modbus讲明白了
    大家好!我是付工。2012年开始接触Modbus协议,至今已经有10多年了,从开始的懵懂,到后来的顿悟,再到现在的开悟,它始终岿然不动,变化的是我对它的认知和理解。今天跟大家聊聊关于Modbus协议的那些事。发展历史Modbus于1979年诞生,已经历经了40多年。Modbus诞生在一个特定的时期。1969年......