2024-03-19 17:45:12 +08:00

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;
}