#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<Windows.h>
#include "MODBUS_SHARE.h"
#include "MODBUS_SERVER.h"
#include "PORT.h"
#include<iostream>
unsigned char buff[256];
using namespace std;
////////////////////////////////////////////////////////////////////////////////////////////////////
/*1.对单个PLC操作*/
/*读一个或多个模拟量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/
/*40000*/
int MODBUS_S_ReadMultiRegD(unsigned char rtu, short int *list, int len)
{
unsigned short int crc16;
unsigned short int crctmp;
short int vartmp;
//1 word = 2 byte ,一个寄存器存一个word,即 16 bit, 若一次读了32bits,则表示一次连续读了两个寄存器
memset(buff, 0x00, 255);
//发送数据
unsigned long strlen;
if (IsOpen())
{
//接受x03查询请求 8 bytes,
strlen = ReadChar(8, (char *)buff, 1000);
if (strlen == 8 && buff[0] == rtu && buff[1] == 0x03)
{
cout << "成功接收请求并处理" << endl;
//发送响应报文3+reg_count*2+2(打包)
memset(buff, 0x00, 255);
Sleep(10);
//响应帧
buff[0] = rtu; //从设备地址
buff[1] = 0x03;//功能码
buff[2] = (unsigned char)(2*len);//数据域字节数
for ( int i = 0;i < len; i++)
{
buff[3 + i * 2] = (unsigned char)list[i] >> 8;
buff[4 + i * 2] = (unsigned char)list[i];
}
crc16 = CRC16(buff, 3+len*2);
buff[len*2+3] = (unsigned char)(crc16 >> 8);//差错校验
buff[len*2+4] = (unsigned char)crc16;
strlen = WriteChar(len*2+5, (char *)buff);
cout <<"发送"<< strlen<< "字节" << endl;
}
else
{
cout << "未接到请求" << endl;
}
}
return 0;
}
/*读一个或多个开关量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/
/*00000*/
char MODBUS_S_ReadMultiRegM(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, bool *list)
{
unsigned short int crc16;
unsigned short int crctmp;
memset(buff, 0x00, 255);
buff[0] = rtu;
buff[1] = 0x01;
buff[2] = (unsigned char)(RegAdd >> 8);
buff[3] = (unsigned char)RegAdd;
buff[4] = (unsigned char)(RegCount >> 8);
buff[5] = (unsigned char)RegCount;
crc16 = CRC16(buff, 6);
buff[6] = (unsigned char)(crc16 >> 8);
buff[7] = (unsigned char)crc16;
//发送数据
unsigned long strlen;
if (IsOpen())
{
//发送数据
strlen = WriteChar(8, (char *)buff);
if (strlen == 8)
{
//读数据
memset(buff, 0x00, 255);
Sleep(50);
strlen = ReadChar(255, (char *)buff, 1000);
if (strlen == 0)
{
//无返回
return(-2);
}
else
{
//返回长度有效,解析接收缓冲区
if (strlen == (3 + ((RegCount + 7) / 8) + 2) && buff[0] == rtu && buff[1] == 0x01)
{
crc16 = CRC16(buff, 3 + ((RegCount + 7) / 8));
crctmp = buff[strlen - 2];
crctmp = crctmp << 8 | buff[strlen - 1];
if (crc16 == crctmp)
{
unsigned char row = 0, col = 0;
for (int i = 0; i<RegCount; i++)
{
row = i / 8;
col = i % 8;
list[i] = buff[3 + row] >> col & 0x01;
}
}
else
{
return(-1);
}
}
else
{
return(-1);
}
}
}
else
{
return(-2);
}
}
else
{
return(-2);
}
return(1);
}
/*读一个或多个开关量 参数:站号,开始地址, 读的数量, 返回数据变量指针 返回:-1表示CRC校验失败,-2表示无应答, 大于零表示接收数据成功*/
/*10000*/
char MODBUS_S_ReadMultiRegM_1x(unsigned char rtu, unsigned short int RegAdd, unsigned short int RegCount, bool *list)
{
unsigned short int crc16;
unsigned short int crctmp;
memset(buff, 0x00, 255);
buff[0] = rtu;
buff[1] = 0x02;
buff[2] = (unsigned char)((RegAdd - 10001) >> 8);
buff[3] = (unsigned char)(RegAdd - 10001);
buff[4] = (unsigned char)(RegCount >> 8);
buff[5] = (unsigned char)RegCount;
crc16 = CRC16(buff, 6);
buff[6] = (unsigned char)(crc16 >> 8);
buff[7] = (unsigned char)crc16;
//发送数据
unsigned long strlen;
if (IsOpen())
{
//发送数据
strlen = WriteChar(8, (char *)buff);
if (strlen == 8)
{
//读数据
memset(buff, 0x00, 255);
Sleep(50);
strlen = ReadChar(255, (char *)buff, 1000);
if (strlen == 0)
{
//无返回
return(-2);
}
else
{
//返回长度有效,解析接收缓冲区
if (strlen == (3 + ((RegCount + 7) / 8) + 2) && buff[0] == rtu && buff[1] == 0x02)
{
crc16 = CRC16(buff, 3 + ((RegCount + 7) / 8));
crctmp = buff[strlen - 2];
crctmp = crctmp << 8 | buff[strlen - 1];
if (crc16 == crctmp)
{
unsigned char row = 0, col = 0;
for (int i = 0; i<RegCount; i++)
{
row = i / 8;
col = i % 8;
list[i] = buff[3 + row] >> col & 0x01;
}
}
else
{
return(-1);
}
}
else
{
return(-1);
}
}
}
else
{
return(-2);
}
}
else
{
return(-2);
}
return(1);
}
/*写一个模拟量 参数:设备号,写地址, 返回数据变量指针 返回:小于零失败,大于零表示成功*/
/*40000*/
char MODBUS_S_WriteSingRegD(unsigned char rtu, unsigned short int RegAdd, short int var)
{
unsigned short int crc16;
memset(buff, 0x00, 255);
buff[0] = rtu;
buff[1] = 0x03;
buff[2] = (unsigned char)((RegAdd - 40001) >> 8);
buff[3] = (unsigned char)(RegAdd - 40001);
buff[4] = (unsigned char)(var >> 8);
buff[5] = (unsigned char)var;
crc16 = CRC16(buff, 6);
buff[6] = (unsigned char)(crc16 >> 8);
buff[7] = (unsigned char)crc16;
//发送数据
unsigned long strlen;
if (IsOpen())
{
//发送数据
strlen = WriteChar(8, (char *)buff);
if (strlen == 8)
{
Sleep(50);
strlen = ReadChar(255, (char *)buff, 1000);
//返回长度有效,解析接收缓冲区
if (!(strlen == 8 && buff[0] == rtu && buff[1] == 0x06))
{
return(-1);
}
}
else
{
return(-1);
}
}
else
{
return(-1);
}
return(1);
}
/*写一个模拟量 参数:站号,写地址, 返回数据变量指针 返回:小于零失败,大于零表示成功*/
char MODBUS_S_WriteSingRegM(unsigned char rtu, unsigned short int RegAdd, bool var)
{
unsigned short int crc16;
memset(buff, 0x00, 255);
buff[0] = rtu;
buff[1] = 0x05;
buff[2] = (unsigned char)(RegAdd >> 8);
buff[3] = (unsigned char)RegAdd;
if (var)
{
buff[4] = 0xff;
buff[5] = 0x00;
}
else
{
buff[4] = 0x00;
buff[5] = 0x00;
}
crc16 = CRC16(buff, 6);
buff[6] = (unsigned char)(crc16 >> 8);
buff[7] = (unsigned char)crc16;
//发送数据
unsigned long strlen;
if (IsOpen())
{
//发送数据
Sleep(50);
strlen = WriteChar(8, (char *)buff);
if (strlen == 8)
{
Sleep(50);
strlen = ReadChar(255, (char *)buff, 1000);
//返回长度有效,解析接收缓冲区
if (!(strlen == 8 && buff[0] == rtu && buff[1] == 0x05))
{
return(-1);
}
}
else
{
return(-1);
}
}
else
{
return(-1);
}
return(1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*2.对全部PLC操作*/
char MODBUS_S_A_WriteSingRegD(unsigned short int RegAdd, short int var)
{
unsigned short int crc16;
memset(buff, 0x00, 255);
buff[0] = 0xff;
buff[1] = 0x06;
buff[2] = (unsigned char)((RegAdd - 40001) >> 8);
buff[3] = (unsigned char)(RegAdd - 40001);
buff[4] = (unsigned char)(var >> 8);
buff[5] = (unsigned char)var;
crc16 = CRC16(buff, 6);
buff[6] = (unsigned char)(crc16 >> 8);
buff[7] = (unsigned char)crc16;
//发送数据
unsigned long strlen;
if (IsOpen())
{
//发送数据
strlen = WriteChar(8, (char *)buff);
if (strlen != 8)
{
return(-1);
}
}
else
{
return(-1);
}
return(1);
}
char MODBUS_S_A_WriteSingRegM(unsigned short int RegAdd, bool var)
{
unsigned short int crc16;
memset(buff, 0x00, 255);
buff[0] = 0xff;
buff[1] = 0x05;
buff[2] = (unsigned char)(RegAdd >> 8);
buff[3]