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。

相关推荐
米奇妙啊妙19 小时前
agent 学习 -模拟AI调用工具
人工智能·学习
渡己之道19 小时前
笔记-lvgl移植到stm32f407
c语言·笔记·stm32
FakeOccupational19 小时前
【电路笔记 电源模块】“桥接”布局法+电源隔离+GND隔离+统一地平面防干扰
笔记·平面
试剂界的爱马仕19 小时前
AI学习实现:如何给基金实时估值?
大数据·人工智能·科技·学习·机器学习
2301_7926748620 小时前
java学习day31(redis)
java·redis·学习
xuhaoyu_cpp_java20 小时前
MyBatis学习(一)
java·经验分享·笔记·学习·mybatis
monkeyhlj21 小时前
AI Agent开发课程笔记记录 - 提升篇 About RAG
人工智能·笔记
苦 涩21 小时前
考研408笔记之操作系统(三)——内存管理
笔记·操作系统·考研408
爱上好庆祝21 小时前
学习js的第三天
前端·css·人工智能·学习·计算机外设·js
SunAqua21 小时前
《MCU与DSP芯片笔记》一、DSP芯片TI C2000系列TMS320F28035
笔记·单片机·嵌入式硬件