基于MODBUS协议的读取寄存器内容的C++实现
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "modbus.h"
#include<stdio.h>
#include <iostream>
#include <fstream>
#include <streambuf>
using namespace std;
void write_to_excel(string filename, bool&flag,int nb,int addr,int *p)
{
//定义文件输出流
ofstream oFile;
//打开要输出的文件
oFile.open(filename, ios::out | ios::trunc);
oFile << "地址" << "\t" << "值" << endl;
for (int i = 0; i < nb; i++, addr++,p++) {
oFile << addr << "\t" << *p << endl;
}
oFile.close();
}//线圈状态
int * read_0x(modbus_t *ctx,int addr,int nb) {
uint8_t *tab_rp_bits;
int ADDRESS_END;
int rc;;
int *p = new int[nb];
tab_rp_bits = (uint8_t *)malloc((nb+1)* sizeof(uint8_t));
memset(tab_rp_bits, 0, (nb+1) * sizeof(uint8_t));
ADDRESS_END = addr + nb;
rc = modbus_read_bits(ctx, addr, nb, tab_rp_bits);
if (rc != nb )
{
printf("error modbus_read_bits single (%d) \n", rc);
printf("address =%d\n", addr);
}
else {
for (int i = 0; i <nb; i++,addr++) {
printf("addr=%d,value=%d\n", addr, tab_rp_bits[i]);
p[i] = tab_rp_bits[i];
}
}
//free(tab_rp_bits);
return p;
}
//离散输入状态
int * read_1x(modbus_t *ctx, int addr, int nb) {
uint8_t *tab_rp_bits;
int ADDRESS_END;
int rc;
int *p = new int[nb];
tab_rp_bits = (uint8_t *)malloc((nb + 1) * sizeof(uint8_t));
memset(tab_rp_bits, 0, (nb + 1) * sizeof(uint8_t));
ADDRESS_END = addr + nb;
rc = modbus_read_input_bits(ctx, addr, nb, tab_rp_bits);
if (rc != nb)
{
printf("error modbus_read_bits single (%d) \n", rc);
printf("address =%d\n", addr);
}
else {
for (int i = 0; i < nb; i++, addr++) {
printf("addr=%d,value=%d\n", addr, tab_rp_bits[i]);
p[i] = tab_rp_bits[i];
}
}
//free(tab_rp_bits);
return p;
}
//保持寄存器
int * read_2x(modbus_t *ctx, int addr, int nb) {
uint16_t *tab_rp_bits;
int ADDRESS_END;
int rc;
int *p = new int[nb];
tab_rp_bits = (uint16_t *)malloc((nb + 1) * sizeof(uint16_t));
memset(tab_rp_bits, 0, (nb + 1) * sizeof(uint16_t));
ADDRESS_END = addr + nb;
rc = modbus_read_registers(ctx, addr, nb, tab_rp_bits);
if (rc != nb)
{
printf("error modbus_read_bits single (%d) \n", rc);
printf("address =%d\n", addr);
}
else {
for (int i = 0; i < nb; i++, addr++) {
uint16_t n = tab_rp_bits[i] & 0x8000;
if (n == 0x8000) {
tab_rp_bits[i] = ~(tab_rp_bits[i]) + 1;
p[i] = tab_rp_bits[i] * (-1);
printf("addr=%d,value=-%d\n", addr, tab_rp_bits[i]);
}
else {
p[i] = tab_rp_bits[i];
printf("addr=%d,value=%d\n", addr, tab_rp_bits[i]);
}
}
}
//free(tab_rp_bits);
return p;
}
//输入寄存器
int * read_3x(modbus_t *ctx, int addr, int nb) {
uint16_t *tab_rp_bits;
int ADDRESS_END;
int rc;
int *p = new int[nb];
tab_rp_bits = (uint16_t *)malloc((nb + 1) * sizeof(uint16_t));
memset(tab_rp_bits, 0, (nb + 1) * sizeof(uint16_t));
ADDRESS_END = addr + nb;
rc = modbus_read_input_registers(ctx, addr, nb, tab_rp_bits);
if (rc != nb)
{
printf("error modbus_read_bits single (%d) \n", rc);
printf("address =%d\n", addr);
}
else {
for (int i = 0; i < nb; i++, addr++) {
uint16_t n = tab_rp_bits[i] & 0x8000;
if (n == 0x8000) {
tab_rp_bits[i] = ~(tab_rp_bits[i])+1;
p[i] = tab_rp_bits[i]*(-1);
printf("addr=%d,value=-%d\n", addr, tab_rp_bits[i]);
}
else {
printf("addr=%d,value=%d\n", addr, tab_rp_bits[i]);
p[i] = tab_rp_bits[i];
}
}
}
//free(tab_rp_bits);
return p;
}
int main() {
modbus_t *ctx;
int ID;
int ADDRESS_START;
int nb;
int reg;
bool flag = false;
cout << "要查看那类寄存器?\n线圈状态 1\n离散输入状态 2\n保持寄存器 3\n输入寄存器 4\n";
cin >> reg;
cout << "ID:";
cin >> ID;
cout << "起始地址:";
cin >> ADDRESS_START;
cout << "地址数量:";
cin >> nb;
ctx = modbus_new_rtu("COM3", 19200, 'N', 8, 1);
int *p=new int[nb];
modbus_set_slave(ctx, ID);
modbus_set_debug(ctx, TRUE);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
switch (reg)
{
case 1:{
p=read_0x(ctx, ADDRESS_START, nb);
break;
}
case 2: {
p=read_1x(ctx, ADDRESS_START, nb);
break;
}
case 3: {
p=read_2x(ctx, ADDRESS_START, nb);
break;
}
case 4: {
p=read_3x(ctx, ADDRESS_START, nb);
break;
}
}
/*for (int j = 0; j < 8; j++,p++) {
printf("%d\t%d", j, *p);
}*/
write_to_excel("C:\\Users\\DELL\\Desktop\\test.xls", flag,nb, ADDRESS_START,p);
delete[] p;
modbus_close(ctx);
modbus_free(ctx);
return 0;
}