You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中实现TIA Portal PLC标签文件夹的非DB类标签读写?

可行实现方案

方案一:扩展S7.Net库支持非DB地址读写

S7.Net是开源项目,可通过修改其地址解析逻辑,让它支持I/Q/M等直接内存区域的读写:

  1. 定位并修改S7.Net中的地址解析类(如Address),新增对"I"、"Q"、"M"前缀的识别逻辑,对应到S7的内存区域:
    • I → 输入区域(Area.Input = 0x81)
    • Q → 输出区域(Area.Output = 0x82)
    • M → 标志位区域(Area.Memory = 0x83)
  2. 解析地址中的字节和位偏移(如I0.0对应字节0、位0)
  3. 扩展Read/Write方法,添加非DB区域的读写分支

示例扩展代码:

public void Write(string address, object value)
{
    var parsedAddr = ParseNonDBAddress(address);
    if (parsedAddr != null)
    {
        switch (parsedAddr.Area)
        {
            case Area.Input:
                WriteBit(Area.Input, 0, parsedAddr.ByteAddr, parsedAddr.BitAddr, (bool)value);
                break;
            case Area.Output:
                WriteBit(Area.Output, 0, parsedAddr.ByteAddr, parsedAddr.BitAddr, (bool)value);
                break;
            case Area.Memory:
                WriteBit(Area.Memory, 0, parsedAddr.ByteAddr, parsedAddr.BitAddr, (bool)value);
                break;
        }
        return;
    }
    // 保留原有DB地址处理逻辑
    base.Write(address, value);
}

private ParsedAddress? ParseNonDBAddress(string address)
{
    if (address.StartsWith("I", StringComparison.OrdinalIgnoreCase))
    {
        var parts = address.Substring(1).Split('.');
        if (parts.Length == 2 
            && byte.TryParse(parts[0], out byte byteAddr) 
            && byte.TryParse(parts[1], out byte bitAddr))
        {
            return new ParsedAddress { Area = Area.Input, ByteAddr = byteAddr, BitAddr = bitAddr };
        }
    }
    // 同理处理Q、M前缀
    if (address.StartsWith("Q", StringComparison.OrdinalIgnoreCase))
    {
        var parts = address.Substring(1).Split('.');
        if (parts.Length == 2 
            && byte.TryParse(parts[0], out byte byteAddr) 
            && byte.TryParse(parts[1], out byte bitAddr))
        {
            return new ParsedAddress { Area = Area.Output, ByteAddr = byteAddr, BitAddr = bitAddr };
        }
    }
    if (address.StartsWith("M", StringComparison.OrdinalIgnoreCase))
    {
        var parts = address.Substring(1).Split('.');
        if (parts.Length == 2 
            && byte.TryParse(parts[0], out byte byteAddr) 
            && byte.TryParse(parts[1], out byte bitAddr))
        {
            return new ParsedAddress { Area = Area.Memory, ByteAddr = byteAddr, BitAddr = bitAddr };
        }
    }
    return null;
}

private struct ParsedAddress
{
    public Area Area;
    public byte ByteAddr;
    public byte BitAddr;
}

方案二:使用TIA Portal Openness API

通过西门子官方的TIA Portal开放API,可直接读写PLC的绝对地址(包括I/Q/M区域),适合需要和TIA Portal集成的场景:

  1. 安装对应版本的TIA Portal(需支持Openness,部分版本需专业版授权)
  2. 引用Siemens.Engineering.dll等相关程序集
  3. 连接TIA Portal并读写标签,示例代码:
using Siemens.Engineering;
using Siemens.Engineering.SW;
using Siemens.Engineering.HW;

// 获取运行中的TIA Portal实例
var tiaPortal = TiaPortal.TiaPortalConnections.FirstOrDefault();
if (tiaPortal == null)
    throw new InvalidOperationException("未检测到运行的TIA Portal");

// 查找目标PLC
var plc = tiaPortal.Find<Plc>(p => p.Name.Equals("你的PLC名称"));
// 建立在线连接
plc.Connection.Connect();

// 写入I0.0
var inputTag = plc.Tags.CreateTag("I0.0", DataType.Bool, TagType.Absolute);
inputTag.Write(true);

// 读取I0.0
bool currentValue = (bool)inputTag.Read();

方案三:基于S7Comm协议手动实现

若需完全自定义逻辑,可直接基于S7Comm协议构造读写报文,手动处理不同内存区域的参数:

  • 输入区域(I):Area=0x81,DbNumber=0
  • 输出区域(Q):Area=0x82,DbNumber=0
  • 标志位(M):Area=0x83,DbNumber=0
    解析地址前缀后,构造对应PDU报文,发送给PLC完成读写。此方式需熟悉S7Comm协议细节,开发工作量较大,但灵活性最高。

内容的提问来源于stack exchange,提问作者Paul Maubray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 18:57:48