最近工作中要对接第三方的设备,该设备基于标准的Modbus协议,由于是第一次接触,也是一头雾水,但是作为一个工作多年的老鸟,肯定难不倒我,鄙人还是很喜欢学习新知识的,所以抱着一定能解决的态度,学习了一下。其实、我们做一件事,如果时间比较紧急的话,我们可以先简单了解下理论,然后明确终极目标:读数据、写数据并为之实现即可,然后复盘的时候可以再好好复习一下,本文就做简单的介绍,希望对你有所帮助。
Modbus协议由Modicon公司(现在的施耐德电气Schneider Electric)于1979年为可编程逻辑控制(即PLC)通信而发表。目前,Modbus已经成为工业领域通信协议的业界标准,并且现在是工业电子设备之间常用的连接方式。
Modbus簇主要有三种协议:Modbus-RTU、Modbus-ASCII、Modbus-TCP
一、地址介绍
- 寄存器分类
- 功能码介绍
二、libmodbus介绍
2.1 初始化与释放
/*
以TCP的方式创建libmobus实例
char *ip:连接的IP地址
int port: 连接的IP端口
*/
modbus_t *modbus_new_tcp(const char *ip, int port);
/*
以串口的方式创建libmobus实例
onst char *device:连接的串口号,类似是这样'\\\\.\\COM10'
int baud: 波特率
char parity:奇偶校验
int data_bit:数据位
int stop_bit:停止位
*/
modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit);
/*
释放libmodbus实例,使用完libmodbus需要释放掉
modbus_t *ctx:libmodbus实例
*/
void modbus_free(modbus_t *ctx);
2.2 读取
/*
读取线圈状态,可读取多个连续线圈的状态
modbus_t *ctx:Modbus实例
int addr: 线圈地址
int nb:读取线圈的个数
uint8_t *dest: 传出的状态值
*/
int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
/*
读取输入状态,可读取多个连续输入的状态
modbus_t *ctx:Modbus实例
int addr:输入地址
int nb:读取输入的个数
uint8_t *dest:传出的状态值
*/
int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);
/*
读取输入寄存器的值,可读取多个连续输入输入寄存器
modbus_t *ctx:Modbus实例
int addr:输入地址
int nb:读取输入寄存器的个数
uint8_t *dest:传出的寄存器值
*/
int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
/*
读取保持寄存器的值,可读取多个连续输入保持寄存器
modbus_t *ctx:Modbus实例
int addr:输入地址
int nb:读取保持寄存器的个数
uint8_t *dest:传出的寄存器值
*/
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
2.3 写入
/*
写入单个线圈的状态
modbus_t *ctx:Modbus实例
int addr:线圈地址
int status:线圈状态
*/
int modbus_write_bit(modbus_t *ctx, int addr, int status);
/*
写入多个连续线圈的状态
modbus_t *ctx:Modbus实例
int addr:线圈地址
int nb:线圈个数
const uint8_t *src:多个线圈状态
*/
int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);
/*
写入单个寄存器
modbus_t *ctx:Modbus实例
int addr:寄存器地址
int value:寄存器的值
*/
int modbus_write_register(modbus_t *ctx, int addr, int value);
/*
写入多个连续寄存器
int addr:寄存器地址
int nb:寄存器的个数
const uint16_t *src:多个寄存器的值
*/
int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);
三、实验
鄙人在某宝买了一套基于Modbus-RTU协议的设备,用于学习Modbus,长相如下:
1.接线,如下:
2.编写代码,最终效果如下:
温湿度采集demo