0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

各类Modbus功能接口函数详解

瑞萨MCU小百科 来源:瑞萨MCU小百科 2024-12-11 17:12 次阅读

2. 各类Modbus功能接口函数

左右滑动查看完整内容

MODBUS_API int modbus_read_bits(modbus t * ctx,int addr,int nb,uint8_t * dest):

此函数对应于功能码01(0x01)读取线圈/离散量输出状态(Read CoilStatus/DOs),其中,所读取的值存放于参数uint8_t * dest指向的数组空间因此dest指向的空间必须足够大,其大小至少为nb * sizeof(uint8_t)个字节。

用法举例:

左右滑动查看完整内容

#define SERVER ID 1
#define ADDRESS START 0
#define ADDRESS END 99
modbus_t * ctx;
uint8_t * tab_rp_bits;
int rc;
int nb;
ctx=modbus_new_tcp("127.0.0.1",502);
modbus_set_debug(ctx,TRUE);
if (modbus_connect(ctx)==-1)
{
 fprintf(stderr,"Connection failed:%s
", modbus_strerror(errno));
 modbus free(ctx);
 return -1;
}
//申请存储空间并初始化
int nb = ADDRESS_END - ADDRESS_START;
tab_rp_bits = (uint8_t * ) malloc (nb * sizeof(uint8_t));
memset(tab_rp_bits, 0, nb * sizeof(uint8_t));
//读取一个线圈
int addr =1;
rc =modbus_read_bits(ctx,addr,1,tab_rp_bits);
if (rc !=1)
{
 printf("ERROR modbus_read_bits_single (%d)
", rc);
 printf("address =%d
", addr);
}
//读取多个线圈
rc =modbus_read_bits(ctx,addr,nb,tab_rp_bits);
if (rc !=nb)
{
 printf("ERROR modbus_read_bits
");
 printf("Address =%d,nb =%d
", addr, nb);
}
//释放空间关闭连接
free(tab_rp_bits);
modbus_close(ctx);
modbus_free(ctx);

左右滑动查看完整内容

MODBUS_API int modbus_read_input_bits (modbus_t * ctx, intaddr, int nb,uint8_t * dest):

此函数对应于功能码02(0x02)读取离散量输入值(Read InputStatus/DIs),各参数的意义与用法,类似于函数modbus_read_bits()。

左右滑动查看完整内容

MODBUS_API int modbus_read_registers (modbus_t * ctx, intaddr, int nb,uint16_t * dest):

此函数对应于功能码03(0x03)读取保持寄存器(Read HoldingRegister),其中,所读取的值存放于参数uint16_t * dest指向的数组空间,因此dest指向的空间必须足够大,其大小至少为nb * sizeof(uint16_t)个字节。

当读取成功后,返回值为读取的寄存器个数;若读取失败,则返回-1。此函数调用依赖关系如下图6-5所示。

用法举例:

d0954586-b775-11ef-93f3-92fbcf53809c.png

左右滑动查看完整内容

modbust * ctx;
uint16_t tab_reg[64];
int rc;
int i;
ctx=modbus_new_tcp("127.0.0.1",502);
if (modbusconnect(ctx)==-1)
{
 fprintf(stderr,"Connection failed:%s
", modbus_strerror(errno));
 modbus_free(ctx);
 return -1;
}
//从地址0开始连续读取10个
rc =modbus_read_registers(ctx,0,10,tab_reg);
if (rc ==-1)
{
 fprintf(stderr,"%s
",modbus_strerror(errno));
 return -1;
}
for (i=0;i

左右滑动查看完整内容

MODBUS_API int modbus_read_input_registers (modbus_t * ctx,int addr, int nb, uint16_t * dest ):

此函数对应于功能码04(0x04)读取输人寄存器(Read Iput Register),各参数的意义与用法,类似于函数 modbus_read_registers()。

此函数的调用依赖关系如下图6-6所示。

图6-6函数modbus_read input_registers()的调用依赖关系:

d0b219a4-b775-11ef-93f3-92fbcf53809c.png

左右滑动查看完整内容

MODBUS_API int modbus_write_bit(modbus_t * ctx,intcoil_addr,int status):

该函数对应于功能码05(0x05)写单个线圈或单个离散输出(ForceSingleCoil)。其中参数coil_addr代表线圈地址;参数status代表写值取值只能是TRUE(1)或 FALSE(0)。

左右滑动查看完整内容

MODBUS_API int modbus_write_register(modbus_t * ctx,intreg_addr,int value):

该函数对应于功能码06(0x06)写单个保持寄存器(Preset SingleRegister)。

左右滑动查看完整内容

MODBUS_API int modbus_write_bits(modbus_t * ctx, int addr,int nb,const uint8_t * data):

该函数对应于功能码15(0x0F)写多个线圈(Force Multiple Coils)

参数addr代表寄存器起始地址,参数nb表示线圈个数,而参数constuint8_t * data表示待写入的数据块。一般情况下,可以使用数组存储写入数据,数组的各元素取值范围只能是TRUE(1)或FALSE(0)。

左右滑动查看完整内容

MODBUS_API int modbus_write_registers(modbus_t * ctx, intaddr,int nb,const uint16_t * data):

该函数对应于功能码16(0x10)写多个保持存器 (PresetMultipleRegisters)

参数addr代表寄存器起始地址,参数nb表示存器的个数而参数constuint16_t * data表示待写人的数据块。一般情况下,可以使用数组存储写入数据数组的各元素取值范围是0~0xFFFF即数据类型uint16_t的取值范围。

左右滑动查看完整内容

MODBUS_API int modbus_mask_registers(modbus_t * ctx, intaddr, uint16_t and_mask,uint16_t or_mask ):

modbus_mask_write_register()函数应使用以下算法修改远程设备地址“addr”处的保持寄存器的值:

新值=(current value AND ‘and’)OR(‘or’ AND(NOT ‘and’))。

该功能使用Modbus功能代码0x16(掩码单个寄存器)。

左右滑动查看完整内容

MODBUS_API int modbus_write_and_read_registers (mobus_t *ctx ,
int writer_addr,
int writer_nb,
const uint16_t * src,
int read_addr,
int read_nb,
uint16_t * dest);

modbus_write_and_read_registers()函数应将write_nb保持寄存器的内容从数组“src”写入远程设备的地址 write_addr,然后将read_nb保持寄存器的内容读取到远程设备的地址read_addr。读取结果作为字值(16位)存储在dest数组中。

必须注意分配足够的内存来存储结果dest(至少nb *sizeof(uint16_t))。该功能使用Modbus功能代码0x17(写/读寄存器)。

左右滑动查看完整内容

MODBUS_API int modbus_report_slave_id(modbus_t * ctx, intmax_dest, uint8_t * dest):

该函数对应于功能码17(0x11)报告从站ID。参数max_dest代表最大的存储空间,参数dest用于存储返回数据。返回数据可以包括如下内容:从站ID状态值(0x00=OFF状态,0xFF=ON状态)以及其他附加信息,具体的各参数意义由开发者指定。

用法举例:

左右滑动查看完整内容

uint8_t tab_bytes[MODBUS_MAX_PDU_LENGTH];
...
 
rc =modbus_report_slave_id(ctx, MODBUS_MAX_PDU_LENGTH, tab_bytes);
if (rc>1)
{
 printf("Run Status Indicator: %s
",tab_bytes[1] ?"ON":"OFF");
}

3.数据处理的相关函数或宏定义

在libmodbus开发库中,为了方便数据处理在modbus.h 文件中定义了一系列数据处理宏。

例如获取数据的高低字节序宏定义:

左右滑动查看完整内容

#define MODBUS_GET_HIGH_BYTE (data) (((data) >>8)&0xFF)

左右滑动查看完整内容

#define MODBUS_GET_LOW_BYTE (data) ((data)&0xFF)

对于浮点数等多字节数据而言,由于存在字节序与大小端处理等的问题,所以辅助定义了一些特殊函数:

左右滑动查看完整内容

MODBUS_API float modbus_get_float (const uint16_t * src);
MODBUS_API float modbus_get_float_abcd (const uint16_t * src);
MODBUS_API float modbus_get_float_dcba (const uint16_t * src);
MODBUS_API float modbus_get_float_badc (const uint16_t * src);
MODBUS_API float modbus_get_float_cdab (const uint16_t * src);
MODBUS_API void modbus_set_float (float f,uint16_t * dest);
MODBUS_API void modbus_set_float_abcd (float f,uint16_t * dest);
MODBUS_API void modbus_set_float_dcba (float f,uint16_t * dest);
MODBUS_API void modbus_set_float_badc (float f,uint16_t * dest);
MODBUS_API void modbus_set_float_cdab (float f,uint16_t * dest);

当然,可以参照float类型的处理方法,继续定义其他多字节类型的数据例如int32_t、uint32_t、int64_t、uint64_t以及double类型的读写函数。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8575

    浏览量

    151023
  • MODBUS
    +关注

    关注

    28

    文章

    1799

    浏览量

    76954
  • 函数
    +关注

    关注

    3

    文章

    4327

    浏览量

    62573

原文标题:Modbus接口与数据处理 - RZ MPU工业控制教程连载(41)

文章出处:【微信号:瑞萨MCU小百科,微信公众号:瑞萨MCU小百科】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    用于LabVIEW的NI Modbus

    NI LabVIEW实时模块主控和伺服功能用于NI LabVIEW的NI Modbus程序库作为一套可免费下载的VI函数模块,提供源自各类标准以太网或串口的
    发表于 12-18 17:14

    modbus详解

    工控机和工业控制器等;典型的从设备如PLC可编程控制器等。Modbus通讯物理接口可以选用串口(包括RS232和RS485),也可以选择以太网口。
    发表于 11-25 23:49

    modbus协议讲解modbus-rtu以及modbus-tcp协议详解

    modbus协议讲解modbus-rtu以及modbus-tcp协议详解,见附件。
    发表于 03-01 10:14

    Modbus详解(全书+PDF)

    Modbus详解,有需要的看看
    发表于 11-01 15:47

    Modbus功能码的回调函数如何编写呢

    FreeModbus从站设计(10)-Modbus功能码的回调函数如何编写关键词:FreeModbus CubeMX HAL库 串口 功能码此系列的前面几篇文章,主要是阐述了用HAL库
    发表于 02-16 07:31

    PICC库函数详解

    PICC库函数详解
    发表于 04-18 20:13 132次下载

    嵌入式多功能接口转换器的设计与实现

    本文研究如何在嵌入式开发平台上构建一台多功能接口转换器。使得不同接口的智能设备能通过该接口转换器实现数据统一由网络接口传送到计算机。并在ARMSYS44BO—P嵌入式开发
    发表于 07-01 17:04 24次下载

    Modbus通信协议详解

    关于Modbus通信协议的详解和应用分析
    发表于 10-12 16:54 150次下载
    <b class='flag-5'>Modbus</b>通信协议<b class='flag-5'>详解</b>

    Modbus_通讯协议详解

    Modbus_通讯协议详解Modbus_通讯协议详解
    发表于 12-08 14:13 0次下载

    Android开发手册—API函数详解

    Android开发手册—API函数详解
    发表于 10-17 09:01 13次下载
    Android开发手册—API<b class='flag-5'>函数</b><b class='flag-5'>详解</b>

    基于Android开发手册—API函数详解

    基于Android开发手册—API函数详解
    发表于 10-24 09:06 18次下载
    基于Android开发手册—API<b class='flag-5'>函数</b><b class='flag-5'>详解</b>

    单片机程序中,Modbus功能码的回调函数如何编写--FreeModbus从站设计(10)

    FreeModbus从站设计(10)-Modbus功能码的回调函数如何编写关键词:FreeModbus CubeMX HAL库 串口 功能码此系列的前面几篇文章,主要是阐述了用HAL库
    发表于 12-20 18:49 9次下载
    单片机程序中,<b class='flag-5'>Modbus</b><b class='flag-5'>功能</b>码的回调<b class='flag-5'>函数</b>如何编写--FreeModbus从站设计(10)

    什么是type-c全功能接口 Type-C充电接口和type-c全功能接口有什么不同

    Type-C全功能接口,也被称为USB-C全功能接口,是一种多功能的连接接口标准。它是由USB Implementers Forum(USB-IF)制定的一种标准,并在现代设备中被广泛
    的头像 发表于 08-03 14:32 4.7w次阅读

    STM32库函数SystemInit()详解

    STM32库函数SystemInit()详解
    的头像 发表于 09-18 15:45 4019次阅读
    STM32库<b class='flag-5'>函数</b>SystemInit()<b class='flag-5'>详解</b>

    Modbus功能详解

    Modbus标准在协议中规定了以下3类Modbus功能码。
    的头像 发表于 10-29 14:35 915次阅读