174 lines
4.1 KiB
C++
174 lines
4.1 KiB
C++
|
#include "Modbus.h"
|
||
|
#include "CRC16.h"
|
||
|
#include "../utils/DataByte.h"
|
||
|
|
||
|
Modbus::Modbus(unsigned char addr)
|
||
|
:m_addr(addr)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
Modbus::~Modbus(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ReadModbus::ReadModbus(unsigned char addr,unsigned short startReg,unsigned short regCount)
|
||
|
:Modbus(addr)
|
||
|
,m_startReg(startReg)
|
||
|
,m_regCount(regCount)
|
||
|
{
|
||
|
m_funcCode=0x03;
|
||
|
}
|
||
|
|
||
|
ReadModbus::~ReadModbus()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
int ReadModbus::GetRequestSequence(unsigned char* bseq)
|
||
|
{
|
||
|
bseq[0]=m_addr;
|
||
|
bseq[1]=m_funcCode;
|
||
|
bseq[2]=m_startReg>>8;
|
||
|
bseq[3]=(unsigned char)m_startReg;
|
||
|
bseq[4]=m_regCount>>8;
|
||
|
bseq[5]=(unsigned char)m_regCount;;
|
||
|
unsigned short crc=CRC16(bseq,6);
|
||
|
bseq[6]=crc>>8;
|
||
|
bseq[7]=(unsigned char)crc;
|
||
|
return 8;
|
||
|
}
|
||
|
|
||
|
bool ReadModbus::Verify(unsigned char* rseq,int dlength)
|
||
|
{
|
||
|
int rlength=5+m_regCount*2;
|
||
|
if(dlength!=rlength)return false;
|
||
|
if(rseq[0]!=m_addr)return false;
|
||
|
if(rseq[1]!=m_funcCode)return false;
|
||
|
if(rseq[2]!=(unsigned char)(m_regCount*2))return false;
|
||
|
unsigned short crc=CRC16(rseq,dlength-2);
|
||
|
unsigned char crchi=crc>>8;
|
||
|
unsigned char crclo=(unsigned char)crc;
|
||
|
if(rseq[dlength-2]!=crchi || rseq[dlength-1]!=crclo)return false;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
WriteModbus::WriteModbus(unsigned char addr,unsigned short startReg)
|
||
|
:Modbus(addr)
|
||
|
,m_startReg(startReg)
|
||
|
,m_regCount(0)
|
||
|
,m_byteCount(0)
|
||
|
{
|
||
|
m_funcCode=0x10;
|
||
|
}
|
||
|
|
||
|
WriteModbus::~WriteModbus()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
void WriteModbus::AddShort(short value){
|
||
|
m_regCount++;
|
||
|
m_byteCount+=2;
|
||
|
m_valueBytes.push_back(value>>8);
|
||
|
m_valueBytes.push_back((unsigned char)value);
|
||
|
}
|
||
|
|
||
|
void WriteModbus::AddInt(int value){
|
||
|
m_regCount+=2;
|
||
|
m_byteCount+=4;
|
||
|
m_valueBytes.push_back((unsigned char)((value>>24)&0xff));
|
||
|
m_valueBytes.push_back((unsigned char)((value>>16)&0xff));
|
||
|
m_valueBytes.push_back((unsigned char)((value>>8)&0xff));
|
||
|
m_valueBytes.push_back((unsigned char)value);
|
||
|
}
|
||
|
|
||
|
void WriteModbus::AddFloat(float value)
|
||
|
{
|
||
|
m_regCount+=2;
|
||
|
m_byteCount+=4;
|
||
|
FLOATDATA f;
|
||
|
f.fValue=value;
|
||
|
m_valueBytes.push_back(f.data[3]);
|
||
|
m_valueBytes.push_back(f.data[2]);
|
||
|
m_valueBytes.push_back(f.data[1]);
|
||
|
m_valueBytes.push_back(f.data[0]);
|
||
|
}
|
||
|
|
||
|
int WriteModbus::GetRequestSequence(unsigned char* bseq)
|
||
|
{
|
||
|
bseq[0]=m_addr;
|
||
|
bseq[1]=m_funcCode;
|
||
|
bseq[2]=m_startReg>>8;
|
||
|
bseq[3]=(unsigned char)m_startReg;
|
||
|
bseq[4]=m_regCount>>8;
|
||
|
bseq[5]=(unsigned char)m_regCount;;
|
||
|
bseq[6]=m_byteCount;
|
||
|
for(size_t i=0;i<m_valueBytes.size();++i){
|
||
|
bseq[7+i]=m_valueBytes[i];
|
||
|
}
|
||
|
unsigned short crc=CRC16(bseq,7+(unsigned short)m_valueBytes.size());
|
||
|
bseq[7+m_valueBytes.size()]=crc>>8;
|
||
|
bseq[8+m_valueBytes.size()]=(unsigned char)crc;
|
||
|
return 9+m_valueBytes.size();
|
||
|
}
|
||
|
|
||
|
bool WriteModbus::Verify(unsigned char* rseq,int dlength)
|
||
|
{
|
||
|
if(dlength!=8)return false;
|
||
|
if(rseq[0]!=m_addr)return false;
|
||
|
if(rseq[1]!=m_funcCode)return false;
|
||
|
unsigned short startReg=((rseq[2]&0xff)<<8)+(rseq[3]&0xff);
|
||
|
if(startReg!=m_startReg)return false;
|
||
|
unsigned short regCount=((rseq[4]&0xff)<<8)+(rseq[5]&0xff);
|
||
|
if(regCount!=m_regCount)return false;
|
||
|
unsigned short crc=CRC16(rseq,dlength-2);
|
||
|
unsigned char crchi=crc>>8;
|
||
|
unsigned char crclo=(unsigned char)crc;
|
||
|
if(rseq[dlength-2]!=crchi || rseq[dlength-1]!=crclo)return false;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
ReadCoilModbus::ReadCoilModbus(unsigned char addr, unsigned short startReg, unsigned short regCount)
|
||
|
:Modbus(addr)
|
||
|
, m_startReg(startReg)
|
||
|
, m_regCount(regCount)
|
||
|
{
|
||
|
m_funcCode = 0x01;
|
||
|
}
|
||
|
|
||
|
ReadCoilModbus::~ReadCoilModbus()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
int ReadCoilModbus::GetRequestSequence(unsigned char* bseq)
|
||
|
{
|
||
|
bseq[0] = m_addr;
|
||
|
bseq[1] = m_funcCode;
|
||
|
bseq[2] = m_startReg >> 8;
|
||
|
bseq[3] = (unsigned char)m_startReg;
|
||
|
bseq[4] = m_regCount >> 8;
|
||
|
bseq[5] = (unsigned char)m_regCount;;
|
||
|
unsigned short crc = CRC16(bseq, 6);
|
||
|
bseq[6] = crc >> 8;
|
||
|
bseq[7] = (unsigned char)crc;
|
||
|
return 8;
|
||
|
}
|
||
|
|
||
|
bool ReadCoilModbus::Verify(unsigned char* rseq, int dlength)
|
||
|
{
|
||
|
int temp= ceil((float)m_regCount / 8.0f);
|
||
|
int rlength = 5 + temp;
|
||
|
if (dlength != rlength)return false;
|
||
|
if (rseq[0] != m_addr)return false;
|
||
|
if (rseq[1] != m_funcCode)return false;
|
||
|
if (rseq[2] != temp )return false;
|
||
|
unsigned short crc = CRC16(rseq, dlength - 2);
|
||
|
unsigned char crchi = crc >> 8;
|
||
|
unsigned char crclo = (unsigned char)crc;
|
||
|
if (rseq[dlength - 2] != crchi || rseq[dlength - 1] != crclo)return false;
|
||
|
return true;
|
||
|
}
|