ModbusRtu从站接⼝说明
一、使用示例
创建⼀条ModbusRtu从站通讯通道,在通道上创建1个Modbus从站站点(RTU模式下一条从站通道只能接一个设备),循环获取站点的值或写⼊站点的值
#include "modbus_slave/modbusrtu_slave_ch.h"
#include "modbus_slave/modbus_slave_dev.h"
#include <stdio.h>
#include <unistd.h>
// 写数据回调函数(参数,站地址,命令,地址,值)
void DataRenewCallback(void *arg,
const int slaveid, const int code, const int addr, const int value)
{
printf("[%s][%d][%s] slaveid=%d, code=%d, addr=[%04X]%d, value=%d\r\n",
__FILE__, __LINE__, __FUNCTION__, slaveid, code, addr, addr, value);
}
int main(int argc, char *argv[])
{
for(int i = 0; i < 10; i++) {
printf("\r\n[%s][%d][%s] i=%d\r\n", __FILE__, __LINE__, __FUNCTION__, i);
ModbusRtuSlaveCh *pch = new ModbusRtuSlaveCh("/dev/ttysWK2", 115200, 'N', 8, 1);
printf("创建通讯通道 [%08X]\r\n", pch);
ModbusSlaveDev *pmsd = new ModbusSlaveDev(pch, 2, 0x0000, 10, 0x0000, 11, 0x0000, 12, 0x0000, 13);
printf("创建站点 [%08X]\r\n", pmsd);
pch->SetDataRenewCallback(DataRenewCallback);
pch->Run();
printf("启动通讯通道 [%08X]\r\n", pch);
for(int j = 0; j < 20; j++) {
sleep(5);
printf("\r\n[%s][%d][%s] i=%d, j=%d\r\n", __FILE__, __LINE__, __FUNCTION__, i, j);
uint16_t bits[11] = { 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000 };
uint16_t regs[13] = { 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D };
pmsd->SetDataValues(ModbusSlave::kCode01H, 0x0000, bits, 10);
pmsd->SetDataValues(ModbusSlave::kCode02H, 0x0000, bits, 11);
pmsd->SetDataValues(ModbusSlave::kCode03H, 0x0000, regs, 12);
pmsd->SetDataValues(ModbusSlave::kCode04H, 0x0000, regs, 13);
printf("------------------------------------------------------------------------\r\n");
}
printf("释放通讯通道 [%08X]\r\n", pch);
delete pch;
pch = nullptr;
printf("释放站点 [%08X]\r\n", pmsd);
delete pmsd;
pmsd = nullptr;
printf("[%s][%d][%s] i=%d\r\n\r\n", __FILE__, __LINE__, __FUNCTION__, i);
sleep(5);
}
return 0;
}
二、ModbusSlaveCh类
ModbusSlaveCh类为ModbusRtuSlaveCh类、 ModbusTcpSlaveCh类的基类,提供Modbus从站通道的通⽤属性
1. 构造函数
2. 析构函数
3. 获取数据区指针
-
参数
-
无;
-
返回值
-
返回数据区指针;
4. 设置是否打印报文
/**
* @brief 设置是否打印报文(通过printf输出到命令行中)
*
* @param debug 是否开启,0-关闭;1-开启;
*
* @return 无
*/
void SetDebug(int debug);
- 参数
- debug :是否开启, 0-关闭; 1-开启;
- 返回值
- ⽆
5. 设置收发报文内容回调函数
/**
* @brief 设置收发报文内容回调函数
*
* @param *s_callback 发送报文回调函数(参数,报文内容,报文长度);
* @param *r_callback 接收报文回调函数(参数,报文内容,报文长度);
* @param arg 回调参数;
*
* @return 无
*/
void SetMessageCallback(
void (*s_callback)(void *, const uint8_t *, int),
void (*r_callback)(void *, const uint8_t *, int),
void *arg = NULL);
- 参数
- *s_callback:发送报⽂回调函数(参数,报⽂内容,报⽂⻓度);
- *r_callback:接收报⽂回调函数(参数,报⽂内容,报⽂⻓度);
- *arg:回调参数;
- 返回值
- ⽆
6. 设置收发报⽂内容回调使能
/**
* @brief 设置收发报文内容回调使能
*
* @param en 是否使能:0-未使能;1-使能;
*
* @return 无
*/
void SetMessagrCallbackEn(int en);
- 参数
- en:是否使能: 0-未使能; 1-使能;
- 返回值
- ⽆
7. 设置收发报⽂内容回调使能
/**
* @brief 设置写数据回调函数
*
* @param *callback 写数据回调函数(参数,站地址,命令,地址,值)
* @param arg 回调参数
*
* @return 无
*/
void SetDataRenewCallback(fpMscDataRenewCallback callback, void *arg = NULL);
// 写数据回调函数(参数,站地址,命令,地址,值)
typedef void (*fpMscDataRenewCallback)(void *arg,
const int slaveid, const int code, const int addr, const int value);
- 参数
- callback:写数据回调函数(参数,站地址,命令,地址,值);
- *arg:回调参数;
- 返回值
- ⽆
三、ModbusRtuSlaveCh类
ModbusRtuSlaveCh类,继承⾃ModbusSlaveCh类,⽤于创建ModbusRtu从站通讯通道
1. 构造函数
/**
* @brief 构造函数
*
* @param *device 串口的文件描述符;
* @param baud 波特率;
* @param parity 校验位,可选'N'(无校验)、'O'(奇校验)、'E'(偶校验);
* @param data_bit 数据位,可选5、6、7、8;
* @param stop_bit 停止位,可选1、2;
*/
ModbusRtuSlaveCh(const char *device, int baud = 115200,
char parity = 'N', int data_bit = 8, int stop_bit = 1);
- 参数
- *device:串⼝的⽂件描述符;
- baud:波特率;
- parity:校验位,可选'N'(⽆校验)、 'O'(奇校验)、 'E'(偶校验);
- data_bit:数据位,可选5、 6、 7、 8;
- stop_bit:停⽌位,可选1、 2;
- 返回值
- 返回值
2. 析构函数
3. 启动函数
- 参数
- ⽆
- 返回值
- ⽆
四、ModbusSlaveDev类
Modbus从站模式下的站点类
1. 构造函数
/**
* @brief 构造函数
*
* @param ch ModbusSlaveCh通道
* @param slave 站地址;
* @param nb_bits 线圈点数量;
* @param start_bits 线圈点起始地址;
* @param nb_input_bits 离散输入点数量;
* @param start_input_bits 离散输入点起始地址;
* @param nb_input_registers 输入寄存器点数量;
* @param start_input_registers 输入寄存器点起始地址;
* @param nb_registers 保持寄存器点数量;
* @param start_registers 保持寄存器点起始地址;
*/
ModbusSlaveDev(
ModbusSlaveCh *pch,
int slave,
int nb_bits,
int start_bits,
int nb_input_bits,
int start_input_bits,
int nb_input_registers,
int start_input_registers,
int nb_registers,
int start_registers
);
-
参数
-
ch:ModbusSlaveCh通道;
- slave:站地址;
- nb_bits:线圈点数量;
- start_bits:线圈点起始地址;
- nb_input_bits:离散输入点数量;
- start_input_bits:离散输入点起始地址;
- nb_input_registers:输入寄存器点数量;
- start_input_registers:输入寄存器点起始地址;
- nb_registers:保持寄存器点数量;
- start_registers:保持寄存器点起始地址;
-
返回值
-
返回值
2. 析构函数
3. 获取站点ID
获取站点ID(站地址)
-
参数
-
无
-
返回值
-
站地址
4. 设置连续多个数据点的数值
/**
* @brief 设置连续多个数据点的数值
*
* @param code 数据点类型
* @param startaddr 数据点地址;
* @param *value 点的值;
* @param nb 数据点个数;
*
* @return 是否设置成功 :
* 1-设置成功;
* -1-失败:未找到对应站点ID的数据区;
* -2-失败:未知功能码
* -3-失败:点地址越界;
*/
int SetDataValues(ModbusSlave::CodeSet_E code, int startaddr, uint16_t *value, int nb = 1);
-
参数
-
code:数据点类型;
- addr:数据点起始地址;
- *value:点的值;
- nb:数据点个数
-
返回值
-
是否设置成功 :
1-设置成功;
-1-失败:未找到对应站点ID的数据区;
-2-失败:未知功能码
-3-失败:点地址越界;
5. 获取连续多个数据点的数值
/**
* @brief 获取连续多个数据点的数值
*
* @param code 数据点类型
* @param startaddr 数据点地址;
* @param *value 点的值;
* @param nb 数据点个数;
*
* @return 是否获取成功 :
* 1-获取成功;
* -1-失败:未找到对应站点ID的数据区;
* -2-失败:未知功能码
* -3-失败:点地址越界;
*/
int GetDataValues(ModbusSlave::CodeGet_E code, int startaddr, uint16_t *value, int nb = 1);
-
参数
-
code:数据点类型;
- addr:点地址;
- *value:输出参数,返回点的值;
- nb:数据点个数
-
返回值
-
是否获取成功 :
1-获取成功;
-1-失败:未找到对应站点ID的数据区;
-2-失败:未知功能码
-3-失败:点地址越界;