You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HslCommunication.ModBus
{
/// <summary>
/// Modbus-Ascii通讯协议的类库基于rtu类库完善过来
/// </summary>
/// <remarks>
/// 本客户端支持的标准的modbus-tcp协议内置的消息号会进行自增地址格式采用富文本表示形式
/// <note type="important">
/// 地址共可以携带3个信息最完整的表示方式"s=2;x=3;100"对应的modbus报文是 02 03 00 64 00 01 的前四个字节,站号,功能码,起始地址,下面举例
/// <list type="definition">
/// <item>
/// <term>读取线圈</term>
/// <description>ReadCoil("100")表示读取线圈100的值ReadCoil("s=2;100")表示读取站号为2线圈地址为100的值</description>
/// </item>
/// <item>
/// <term>读取离散输入</term>
/// <description>ReadDiscrete("100")表示读取离散输入100的值ReadDiscrete("s=2;100")表示读取站号为2离散地址为100的值</description>
/// </item>
/// <item>
/// <term>读取寄存器</term>
/// <description>ReadInt16("100")表示读取寄存器100的值ReadInt16("s=2;100")表示读取站号为2寄存器100的值</description>
/// </item>
/// <item>
/// <term>读取输入寄存器</term>
/// <description>ReadInt16("x=4;100")表示读取输入寄存器100的值ReadInt16("s=2;x=4;100")表示读取站号为2输入寄存器100的值</description>
/// </item>
/// </list>
/// 对于写入来说也是一致的
/// <list type="definition">
/// <item>
/// <term>写入线圈</term>
/// <description>WriteCoil("100",true)表示读取线圈100的值WriteCoil("s=2;100",true)表示读取站号为2线圈地址为100的值</description>
/// </item>
/// <item>
/// <term>写入寄存器</term>
/// <description>Write("100",(short)123)表示写寄存器100的值123Write("s=2;100",(short)123)表示写入站号为2寄存器100的值123</description>
/// </item>
/// </list>
/// </note>
/// </remarks>
/// <example>
/// 基本的用法请参照下面的代码示例,初始化部分的代码省略
/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Modbus\ModbusAsciiExample.cs" region="Example" title="Modbus示例" />
/// 复杂的读取数据的代码示例如下:
/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Modbus\ModbusAsciiExample.cs" region="ReadExample" title="read示例" />
/// 写入数据的代码如下:
/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Modbus\ModbusAsciiExample.cs" region="WriteExample" title="write示例" />
/// </example>
public class ModbusAscii : ModbusRtu
{
#region Constructor
/// <summary>
/// 实例化一个Modbus-ascii协议的客户端对象
/// </summary>
public ModbusAscii( )
{
}
/// <summary>
/// 指定服务器地址,端口号,客户端自己的站号来初始化
/// </summary>
/// <param name="station">站号</param>
public ModbusAscii( byte station = 0x01 ) : base( station )
{
}
#endregion
#region Modbus Rtu Override
/// <summary>
/// 检查当前的Modbus-Ascii响应是否是正确的
/// </summary>
/// <param name="send">发送的数据信息</param>
/// <returns>带是否成功的结果数据</returns>
protected override OperateResult<byte[]> CheckModbusTcpResponse( byte[] send )
{
// 转ascii
byte[] modbus_ascii = ModbusInfo.TransRtuToAsciiPackCommand( send );
// 核心交互
OperateResult<byte[]> result = ReadBase( modbus_ascii );
if (!result.IsSuccess) return result;
// 还原modbus报文
OperateResult<byte[]> modbus_core = ModbusInfo.TransAsciiPackCommandToRtu( result.Content );
if (!modbus_core.IsSuccess) return modbus_core;
// 发生了错误
if ((send[1] + 0x80) == modbus_core.Content[1]) return new OperateResult<byte[]>( modbus_core.Content[2], ModbusInfo.GetDescriptionByErrorCode( modbus_core.Content[2] ) );
// 成功的消息
return OperateResult.CreateSuccessResult( modbus_core.Content );
}
#endregion
#region Object Override
/// <summary>
/// 返回表示当前对象的字符串
/// </summary>
/// <returns>字符串信息</returns>
public override string ToString( )
{
return $"ModbusAscii[{PortName}:{BaudRate}]";
}
#endregion
}
}