增加Modbus协议,实现了协议解析,部分从机,未实现主机

This commit is contained in:
Stone 2014-11-25 12:28:14 +00:00
parent 3a7dd0feb2
commit f93f352d5b
8 changed files with 208 additions and 16 deletions

65
Modbus/Modbus.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "Modbus.h"
Modbus::Modbus()
{
Address = 0;
Code = 0;
Error = 0;
Length = 0;
Crc = 0;
Crc2 = 0;
}
bool Modbus::Read(MemoryStream& ms)
{
if(ms.Remain() < 4) return false;
byte* buf = ms.Current();
assert_ptr(buf);
uint p = ms.Position();
Address = ms.ReadByte();
Code = ms.ReadByte();
if(Code & 0x80)
{
Code &= 0x7F;
Error = 1;
}
Length = ms.Remain() - 2;
ms.Read(&Data, 0, Length);
Crc = ms.Read<ushort>();
// 直接计算Crc16
Crc2 = Sys.Crc16(buf, ms.Position() - p - 2);
}
void Modbus::Write(MemoryStream& ms)
{
uint p = ms.Position();
ms.Write(Address);
byte code = Code;
if(Error) code |= 0x80;
ms.Write(code);
if(Length > 0) ms.Write(Data, 0, Length);
byte* buf = ms.Current();
byte len = ms.Position() - p;
// 直接计算Crc16
Crc = Crc2 = Sys.Crc16(buf - len, len);
ms.Write(Crc);
}
void Modbus::SetError(ModbusErrors::Errors error)
{
Code |= 0x80;
Length = 1;
Data[0] = error;
}

75
Modbus/Modbus.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef __Slave_H__
#define __Slave_H__
#include "Sys.h"
#include "Stream.h"
class ModbusErrors
{
public:
// 错误代码
enum Errors
{
// 错误的功能代码
Code = 1,
// 错误的数据地址
Address = 2,
// 错误的数据值
Value = 3,
// 错误的个数
Count,
// 处理出错
Process,
// 错误的数据长度
Length,
// Crc校验错误
Crc
};
};
// Modbus消息实体
class Modbus
{
private:
public:
byte Address; // 地址
byte Code; // 功能码
byte Error; // 是否异常
byte Length; // 数据长度
byte Data[32]; // 数据
ushort Crc; // 校验码
ushort Crc2; // 动态计算得到的校验码
Modbus();
bool Read(MemoryStream& ms);
void Write(MemoryStream& ms);
void SetError(ModbusErrors::Errors error);
private:
};
#endif
/*
* GB/T 19582.1-2008 Modbus协议的工业自动化网络规范
* 1|n字节数据|2CRC校验
* 1+0x80|1
*
* Modbus数据模型基本表
* 访
* I/O系统可提供这种类型的数据
* 线
* 16 I/O系统可提供这种类型的数据
* 16
*
*/

43
Modbus/Slave.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "Slave.h"
Slave(ITransport* port)
{
_port = port;
Address = 0;
}
Slave::~Slave()
{
delete _port;
_port = NULL;
}
void Slave::OnReceive(ITransport* transport, byte* buf, uint len, void* param)
{
assert_ptr(param);
Slave* slave = (Slave*)param;
MemoryStream ms(buf, len);
Modbus entity;
if(!entity.Read(ms)) return;
slave->Dispatch(entity);
}
// 分发处理消息。返回值决定是否响应
bool Slave::Dispatch(Modbus& entity)
{
// 是否本地地址或者本地是否0接收所有消息
if(Address && Address != entity.Address) return false;
// 检查Crc
if(entity.Crc != enable.Crc2)
{
entity.SetError(ModbusErrors::Crc);
return true;
}
return true;
}

25
Modbus/Slave.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef __Slave_H__
#define __Slave_H__
#include "Sys.h"
// Modbus从机
class Slave
{
private:
ITransport* _port; // 传输口
public:
byte Address; // 地址
Slave(ITransport* port);
~Slave();
private:
static void OnReceive(ITransport* transport, byte* buf, uint len, void* param);
// 分发处理消息。返回值决定是否响应
bool Dispatch(Modbus& entity);
};
#endif

View File

@ -1 +0,0 @@
#include "Slave.h"

View File

@ -1,15 +0,0 @@
#ifndef __Slave_H__
#define __Slave_H__
#include "Sys.h"
// Modbus从机
class Slave
{
private:
public:
private:
};
#endif