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所示。
用法举例:
左右滑动查看完整内容
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()的调用依赖关系:
左右滑动查看完整内容
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小百科】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论