S7-1500PLC学习笔记:MOVE_BLK、MOVE_BLK_VARIANT、BLKMOV的区别

在 S7‑1500 里,MOVE_BLK、MOVE_BLK_VARIANT、BLKMOV 是三种最常用的块移动指令,但定位、用法、限制完全不同。

一、定位

  • MOVE_BLK简单数组复制(固定类型、固定数组、编译时确定)
  • MOVE_BLK_VARIANT灵活 / 动态数组复制(支持 Variant、结构体数组、单变量、运行时索引)
  • BLKMOV底层内存字节复制(跨存储区、按字节、非优化 DB、兼容旧指令风格)
特性 MOVE_BLK MOVE_BLK_VARIANT BLKMOV
核心定位 标准数组块移动 变体 / 动态数组块移动西门子工业支持中心 底层内存字节移动
数据类型 基本类型数组(INT/REAL/BYTE) 支持Variant、结构体、UDT、数组、单变量 字节复制,无视类型
源 / 目标 必须是数组元素(如 DB1.Data [0]) 可:数组、单变量、Variant 指针 区域 + DB 号 + 偏移(底层寻址)
偏移方式 直接写数组下标(编译时固定) SRC_INDEX / DEST_INDEX(变量动态偏移)西门子工业支持中心 byteOffset(字节偏移)
存储区 仅限DB 数组 DB、M、I、Q、全局变量均可 任意区(I/Q/M/DB/PI/PQ)
DB 优化块 ✅ 支持(优化 / 非优化均可) ✅ 支持 仅非优化 DB
返回值 无(ENO) RET_VAL(错误码)西门子工业支持中心 无(ENO)

二、语法与示例(SCL)

1. MOVE_BLK
  • 只能传同类型基本数组
  • IN/OUT数组元素的含义是移动的块的起点索引
  • COUNT = 元素个数

scl:

复制代码
// 复制 DB1.Data[5] 开始的 10 个 INT → DB2.Data[0]
MOVE_BLK(

    IN    := DB1.Data[5],   // 源:数组元素

    OUT   := DB2.Data[0],   // 目标:数组元素

    COUNT := 10             // 元素个数

);
2. MOVE_BLK_VARIANT(最强大)
  • 只能传同类型数据
  • 支持 Variant、结构体、单变量、动态索引
  • SRC_INDEX / DEST_INDEX 可用变量
  • 有错误码 RET_VAL

scl:

复制代码
// 复制 DB1.MyStructArr[3] 开始 5 个结构体 → DB2.MyStructArr[0]

RET_VAL := MOVE_BLK_VARIANT(

    SRC        := DB1.MyStructArr,  // 源数组(或Variant)

    DEST       := DB2.MyStructArr,  // 目标数组

    COUNT      := 5,                // 元素个数

    SRC_INDEX  := 3,                // 源起始索引(变量)

    DEST_INDEX := 0                 // 目标起始索引(变量)

);



// 单变量 → 数组(COUNT=1)

MOVE_BLK_VARIANT(

    SRC        := MyIntVar,

    DEST       := DB1.Data[10],

    COUNT      := 1,

    SRC_INDEX  := 0,

    DEST_INDEX := 0

);
3. BLKMOV(底层字节)
  • 整块复制
  • 完全按字节复制,不关心类型
  • 必须非优化 DB
  • IN/OUT 是数组或数组元素

scl:

复制代码
// 复制 DB10:"src_DB" 到 DB20:"des_DB
#TMP1 := BLKMOV(SRCBLK := "src_DB", DSTBLK => "des_DB");
#TMP3 := BLKMOV(SRCBLK := P#M200.0 BYTE 10, DSTBLK => P#M300.0 BYTE 10);
  • 需要注意的是:

BLKMOV的SRCBLK和DSTBLK的参数中如果是数组元素,其含义为:块移动这个元素所代表的数据,而不是以此为起点移动,这与MOVE_BLK的参数中的数组元素意义完全不同。

scl:

复制代码
// 复制 "src_DB".DBW64 到 "des_DB".DBW0
#TMP1 := BLKMOV(SRCBLK := "src_DB".DBW64, DSTBLK => "des_DB".DBW0);

这行代码的意思是:复制 "src_DB".DBW64 到 "des_DB".DBW0"(只复制一个WORD),而非"将src_DB从DBW64复制到des_DB".DBW0开始的位置。

  • BLKMOV的通用规则:

源区域和目标区域不得重叠。如果源和目标区域长度不同,则只能移动较小长度的区域。

如果源区域小于目标区域,则将整个源区域的数据都写入到目标区域中。而目标区域的其余字节则保持不变。

如果目标区域小于源区域,将写满整个目标区域。而忽略源区域的剩余字节。

三、怎么选

✅ 用 MOVE_BLK 当:

  • 只是普通基本类型数组复制
  • 下标编译时固定
  • 追求最简单、最快

✅ 用 MOVE_BLK_VARIANT 当:

  • 结构体 / UDT 数组复制
  • 动态索引(变量做偏移)
  • 通用 FB/FC(接口用 Variant)
  • 单变量 ↔ 数组复制
  • 错误码 RET_VAL

✅ 用 BLKMOV 当:

  • 要忽略类型的底层字节操作
  • 旧 S7‑300/400 程序移植
  • 配合和取代 PEEK/POKE 风格

四、综合运用demo

  • 源数据块:一个有各种不同格式数据的DB块,名称为src_DB
  • 目标数据块:array of bytes格式数据的DB块(比如用来拼接网络发送内容的块)
  • **设计目标:**将源数据块不分数据类型按照预设的起点和长度逐字节移动到目标数据块中预设的起点区域中。
  • 实施过程:
  1. 创建一个中间数据块,数据类型为Array of bytes,将其命名为:bytes_DB;
  2. 使用BLKMOV将src_DB整体复制到中间数据块bytes_DB中,利用BLKMOV可以忽略类型复制的特性,将源DB块转为Array of bytes格式的DB块;
  3. 使用MOVE_BLK或MOVE_BLK_VARIANT将中间数据块bytes_DB的字节复制到目标DB块中。

上述过程是可逆的,就是说,可以把一个Array of bytes格式的DB块的内容复制到一个与src_DB数据类型相同的DB块中,还原出原有数据。而这,正是网络通信所干的事情:decode和encode。

相关推荐
darkhorsefly2 小时前
玩24算的益处
学习·游戏·24算
雨浓YN3 小时前
OPC UA 通讯开发笔记 - 基于本地dll文件
windows·笔记
深蓝海拓4 小时前
S7-1500学习笔记:用户自定义数据类型(UDT)
笔记·学习·plc
罗罗攀4 小时前
PyTorch学习笔记|神经网络的损失函数
人工智能·pytorch·笔记·神经网络·学习
aP8PfmxS24 小时前
从零学习Kafka:数据存储
分布式·学习·kafka
AI成长日志5 小时前
【算法学习专栏】动态规划基础·中等两题精讲(198.打家劫舍、322.零钱兑换)
学习·算法·动态规划
tq10866 小时前
价值:社会对劳动所产生的效用增量形成的局部共识
笔记
A923A6 小时前
【小兔鲜电商前台 | 项目笔记】第八天
前端·vue.js·笔记·项目·小兔鲜
arvin_xiaoting6 小时前
OpenClaw学习总结_III_自动化系统_1:Hooks详解
运维·学习·自动化