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