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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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