64 lines
2.1 KiB
C#
64 lines
2.1 KiB
C#
using System;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace StandardScene.Signal.Plc
|
|
{
|
|
/// <summary>西门子 DB 字节/位地址拼装与缓冲区位操作。</summary>
|
|
internal static class PlcAddress
|
|
{
|
|
private static readonly Regex Addr = new Regex(
|
|
@"^DB(\d+)\.(?:DBB|DBX|DBW)?(\d+)(?:\.(\d+))?$",
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
public static string Bit(int db, int absByte, int bit) =>
|
|
$"DB{Math.Max(1, db)}.DBX{Math.Max(0, absByte)}.{ClampBit(bit)}";
|
|
|
|
public static string Byte(int db, int absByte) =>
|
|
$"DB{Math.Max(1, db)}.DBB{Math.Max(0, absByte)}";
|
|
|
|
public static int ClampBit(int bit)
|
|
{
|
|
if (bit < 0) return 0;
|
|
if (bit > 7) return 7;
|
|
return bit;
|
|
}
|
|
|
|
public static bool TryParse(string address, out int db, out int absByte, out int bit)
|
|
{
|
|
db = 0;
|
|
absByte = 0;
|
|
bit = 0;
|
|
if (string.IsNullOrWhiteSpace(address))
|
|
return false;
|
|
var m = Addr.Match(address.Trim());
|
|
if (!m.Success)
|
|
return false;
|
|
db = int.Parse(m.Groups[1].Value);
|
|
absByte = int.Parse(m.Groups[2].Value);
|
|
if (m.Groups[3].Success)
|
|
bit = ClampBit(int.Parse(m.Groups[3].Value));
|
|
return true;
|
|
}
|
|
|
|
public static bool GetBit(byte[] buffer, int originByte, int absByte, int bit)
|
|
{
|
|
var i = absByte - originByte;
|
|
if (buffer == null || i < 0 || i >= buffer.Length)
|
|
return false;
|
|
return (buffer[i] & (1 << ClampBit(bit))) != 0;
|
|
}
|
|
|
|
public static void SetBit(byte[] buffer, int originByte, int absByte, int bit, bool value)
|
|
{
|
|
var i = absByte - originByte;
|
|
if (buffer == null || i < 0 || i >= buffer.Length)
|
|
return;
|
|
var mask = (byte)(1 << ClampBit(bit));
|
|
if (value)
|
|
buffer[i] |= mask;
|
|
else
|
|
buffer[i] = (byte)(buffer[i] & ~mask);
|
|
}
|
|
}
|
|
}
|