plc 快速学习 S7-1200 数据类型、存储区与寻址方式(I/Q/M/DB 详解

第二章:plc 快速学习 S7-1200 数据类型、存储区与寻址方式(I/Q/M/DB 详解

上一章,基础概念到产品参数

我们不用急着写代码。我们先搞清楚一个问题——PLC这玩意儿,它到底是怎么"活"过来的?它怎么知道什么时候该睡觉(STOP),什么时候该起床(STARTUP),什么时候该干活(RUN)?它脑子里的"记忆"存在哪里?它怎么找到自己要的数据?把这些搞明白了,后面写梯形图、写SCL,那就是水到渠成的事情。

第一部分:CPU 的工作模式 —— PLC 的"作息时间表"

1.1 三种基本状态:STOP、STARTUP、RUN

如果把 S7-1200 的 CPU 比作一个人,它一天只有三种状态:
表格
 
 
状态 英文 人话解释 专业解释
停止 STOP 睡觉,啥也不干 不执行用户程序,不刷新过程映像,但可以进行通信和组态下载
启动 STARTUP 刚睁眼,还在赖床,先伸个懒腰 上电后或从 STOP 切到 RUN 之前的过渡状态,执行一次启动组织块(OB),做初始化
运行 RUN 完全清醒,开始干活 循环执行用户程序(OB1),不断刷新输入/输出

1.2 模式转换的六条"铁律"

CPU 不是你想切就能切的,它的状态转换有严格的顺序(看下面这个流程图逻辑):
plain
 
① POWER ON → STARTUP(上电后暖启动)
② POWER ON → STOP(上电后停在停止)
③ STOP → STARTUP(拨到RUN或远程启动)
④ STARTUP → STOP(启动失败或拨到STOP)
⑤ STARTUP → RUN(启动完成,进入循环扫描)
⑥ RUN → STOP(拨到STOP或出现致命错误)
 
重点讲透
  • ① 暖启动(Warm Restart):这是 S7-1200 的默认启动方式。意思是"上电后,非保持性存储区清零,保持性存储区保留,然后执行启动OB,最后进入RUN"。
  • ④ 启动失败回 STOP:如果启动OB里写的初始化程序有逻辑错误(比如除零、数组越界),CPU 会"起不来",直接退回 STOP,这时候你拨到 RUN 也没用,必须改好程序重新下载。

1.3 启动组织块(Startup OB)—— 伸懒腰时顺便把牙刷了

从 STOP 切换到 RUN 的瞬间,CPU 会先执行启动组织块,然后再进入日常的循环扫描。
特点(结合截图)
  • 支持多个启动 OB,按编号顺序执行(OB100 → OB123 → OB124)
  • 只执行一次,不是循环执行
  • 在里面写什么?
    • 初始化变量(给某些计数器清零)
    • 设置 HSC(高速计数器)的初始值
    • 配置 PWM、PtP(点对点通信)模块的参数
    • 校准传感器零点
讲师比喻:启动 OB 就像你早上起床的"自动化流程"——先睁眼(OB100),再坐起来(OB123),再穿拖鞋(OB124),这三件事只做一次,做完之后你才进入"循环工作状态"(RUN),开始一天重复的搬砖。

第二部分:程序结构与块调用 —— 程序的"套娃艺术"

2.1 程序的"骨架":组织块(OB)

S7-1200 的程序不是一行一行往下读的,它是事件驱动 + 块调用的结构。
  • OB1(程序循环 OB):主程序,相当于 C 语言的 main(),周而复始地执行。
  • 启动 OB(OB100/123/124):只在上电/STOP→RUN 时执行一次。
  • 中断 OB:外部事件触发(比如急停按钮按下),立刻打断当前工作去处理。

2.2 程序的"器官":FB、FC、DB

这是西门子最核心的思想——块化编程
表格
 
 
块类型 全称 人话 核心区别
OB 组织块 程序的"入口" 由系统事件调用,用户不能调用
FB 功能块 带"记忆"的功能 有自己的"背景数据块(DB)",每次调用状态可以保存
FC 功能 纯"干活"的函数 没有背景 DB,像数学公式,输入→计算→输出,用完即走
DB 数据块 公共仓库/私人衣柜 存放数据,全局 DB 大家都能用,背景 DB 专属于某个 FB

2.3 嵌套调用 —— 像俄罗斯套娃一样写程序

看截图里的调用关系
plain
 
OB1
 ├─ FB1(带背景DB)
 │   ├─ FC1
 │   └─ DB(静态数据)
 ├─ FB2(带背景DB)
 │   ├─ FB1(另一个实例,带另一个背景DB)
 │   │   └─ FC21
 │   └─ FC1
 └─ FC1
 
讲师解读
  • 为什么要套娃? 为了模块化。比如"电机控制"写成一个 FB,"气缸控制"写成一个 FB,主程序 OB1 里只需要调用这些块,而不是把所有逻辑都堆在一起。
  • FB1 被调用了两次? 没问题!只要分配不同的背景 DB(比如 FB1 第一次用 DB1,第二次用 DB2),这就是"多实例"——同一个功能块,控制两台不同的电机,各自记各自的数据。
  • DB 的两种身份
    • 全局 DB:像工厂的公共工具柜,谁都能去拿。
    • 背景 DB:像工人的私人工具箱,挂在 FB 名下,只有这个 FB 能直接管理。

第三部分:存储区与寻址方式 —— 数据的"房产证"与"门牌号"

讲师过渡语:前面我们知道了 CPU 怎么"作息",程序怎么"套娃"。现在我们要进入最硬核、最基础、也最容易让人懵圈的部分——数据到底存在哪里?我怎么找到它? 搞懂这个,你才算真正入门西门子。

3.1 存储器机制 —— CPU 的"三套房产"

S7-1200 的 CPU 内部有三类存储器,性质完全不同:
表格
 
 
类型 性质 断电后 扩展性 存放内容
装载存储器 非易失性(ROM/Flash) 数据保留 可用外部存储卡(SD卡)扩展 用户程序、数据、组态信息
工作存储器 易失性(RAM) 数据丢失 无法扩展 当前正在执行的程序代码、变量实时值
保持性存储器 非易失性(由电池/电容维持) 数据保留 无法扩展 用户指定的保持变量(如计数器当前值、重要参数)
大白话
  • 装载存储器 = 你家的硬盘(存着 Windows 系统和所有文件,断电不丢)
  • 工作存储器 = 你家的内存条(运行时的临时数据,关机就清空)
  • 保持性存储器 = 硬盘里的"自动保存"文件夹(你特意勾选的重要文件,断电也留着)
避坑提醒:很多新手问"为什么我的计数器断电后归零了?"——因为你没把它设为"保持性"!在变量表或 DB 里勾选"保持性(Retain)",它才会住进"保持性存储器"。

3.2 地址区详解 —— 五大"楼盘"的房产证

这是本章最核心的表格,必须背熟:
表格
 
 
地址区 全称 符号 作用 特点
过程映像输入区 Input I 接收按钮、传感器、开关的信号 扫描周期开始时,从物理输入端子复制进来
过程映像输出区 Output Q 控制继电器、接触器、指示灯 扫描周期结束时,复制到物理输出端子
位存储区 Memory M 程序内部的"中间继电器" 全局访问,没有物理端子对应
数据块 Data Block DB 结构化数据仓库 可自定义结构,支持复杂数据类型
临时存储区 Local L 块内部的"草稿纸" 仅在当前块执行时有效,块执行完就释放
逐区解剖

① I 区(Input)—— 耳朵

  • 物理对应:CPU 上的 DI 端子(Digital Input)、AI 端子(Analog Input)
  • 寻址示例:I0.0(第0字节第0位)、IW64(第64字,占2字节)、ID100(第100双字,占4字节)
  • 过程映像机制:CPU 在每个扫描周期开始时,"咔嚓"拍一张照片,把所有物理输入端子的状态复制到 I 区。程序运行期间,即使外部按钮松开了,I 区里的值在这个周期内不会变——这就是信号一致性

② Q 区(Output)—— 手脚

  • 物理对应:CPU 上的 DQ 端子、AQ 端子
  • 寻址示例:Q0.0QW128QD256
  • 过程映像机制:程序里修改的是 Q 区的"映像值",直到扫描周期结束,CPU 才统一把 Q 区的值刷到物理端子。这样做是为了避免程序执行到一半时,输出端子抖动。

③ M 区(Memory)—— 大脑里的临时想法

  • 没有物理端子!纯粹是程序内部的"辅助继电器"。
  • 寻址示例:M0.0MW10MD20
  • 用途:记录中间状态(比如"自动模式标志位")、做逻辑过渡、存储计算结果。
  • 注意:M 区默认是全局的,任何块都能改。大型项目建议少用 M,多用 DB,否则容易"撞车"。

④ DB 区(Data Block)—— 档案室

  • 这是西门子最优雅的设计之一。
  • 全局 DBDB1DB2... 里面可以定义变量表,比如 DB1.Product_NameDB1.Target_Speed
  • 背景 DB:自动分配给 FB 的,名字通常是 DBxxx(Instance of FB1),里面存着这个 FB 的输入、输出、静态变量。
  • 优势:支持结构化数据(数组、结构体),支持符号寻址(用名字而不是地址),支持保持性设置。

⑤ L 区(Local/Temp)—— 草稿纸

  • 只在当前块(OB/FB/FC)执行时存在。
  • 用途:存放中间计算结果,块执行完就扔掉。
  • 重要:L 区不会保持!如果你在一个 FC 里用 L0.0 存储关键状态,下次调用时它可能是乱的。

3.3 寻址方式 —— 怎么找到你的数据?

方式一:过程映像访问 vs 直接物理访问

表格
 
 
方式 语法 适用场景 特点
过程映像访问 I0.0Q0.0 普通逻辑控制 保证扫描周期内信号一致,有缓冲
直接物理访问 I0.0:PQ0.0:P 高速、实时性要求极高 绕过映像区,直接读写端子,响应更快
讲师举例
控制一个普通电机启停,用 I0.0 读按钮,完全没问题。
但如果是高速计数器飞剪控制,扫描周期内的 20ms 延迟可能致命,这时候必须用 :P 直接访问物理端子。

方式二:按位、字节、字、双字访问

西门子寻址的"粒度"很灵活:
表格
 
 
粒度 符号 大小 示例 说明
1 bit I0.0M10.7 开关量,TRUE/FALSE
字节 B 8 bit IB0QB1 8个位打包
W 16 bit IW0MW10 2个字节,无符号整数 0~65535
双字 D 32 bit ID0MD20 4个字节,存大整数或浮点数
注意对齐
IW0 包含 IB0IB1IW2 包含 IB2IB3
不要重叠! 如果你用了 MW10,就不要再用 MB10MB11,否则会"打架"。

方式三:Slice 访问(片段访问)—— 精细到"比特级手术"

这是 TIA Portal V13 以后引入的强大功能,支持对 I/Q/M/DB 等地址区,按符号方式对操作数进行位、字节、字的"切片"。
看截图里的内存图
plain
 
DWord-Variable(32位)
├─ W1(高16位)→ Word-Variable
│   ├─ B1(高8位)→ Byte-Variable
│   │   └─ x3..x0(位访问)
│   └─ B0(低8位)
└─ W0(低16位)
    └─ ... 
 
语法示例
scl
 
// 假设 MyDWord 是一个 DWord 类型变量
MyDWord.W1      // 取高16位(Word)
MyDWord.B0      // 取最低8位(Byte)
MyDWord.%X3     // 取第3位(Bit)
 
应用场景
一个 DWord 里打包了 32 个报警位,你想单独取第 5 个报警位做指示灯,不需要复杂的移位指令,直接 Alarm_Pack.%X5 即可。

方式四:AT 访问(数据覆盖)—— "借壳上市"

AT 访问允许你在不增加内存占用的情况下,用不同的"视角"看同一块数据。
截图对比
表格
 
 
访问类型 特点 适用场景
标准访问 绝对地址固定,支持位访问 兼容旧项目,需要直接操作地址
优化访问 系统自动分配地址,只支持符号寻址 新项目首选,效率高,支持切片
AT 覆盖示例
scl
 
// 在 FB 的接口区定义:
Input:
  MyWord : Word;           // 一个16位变量
  AT_MyWord AT MyWord : Array[0..15] of Bool;  // 覆盖为16个布尔量
 
这样,MyWordAT_MyWord[0]~[15] 占用同一块内存。你可以既把它当整数运算,又单独取每一位做逻辑控制。

3.4 数据类型详解 —— 从"幼儿园"到"研究生"

这是讲课时必须花时间夯实的地基。西门子 S7-1200 的数据类型分为基本类型复合类型

3.4.1 基本数据类型(必须倒背如流)

表格
 
 
类型 关键字 大小 范围 人话解释
布尔 Bool 1 bit 0 或 1 开关:灯亮/灭,按钮按下/松开
字节 Byte 8 bit 16#00 ~ 16#FF 8个开关打包,常存状态字
Word 16 bit 16#0000 ~ 16#FFFF 16个开关打包,或 0~65535
双字 DWord 32 bit 16#00000000 ~ 16#FFFFFFFF 32个开关打包
短整数 SInt 8 bit -128 ~ 127 小范围整数
整数 Int 16 bit -32768 ~ 32767 最常用的整数
双整数 DInt 32 bit -2147483648 ~ 2147483647 大整数
无符号短整数 USInt 8 bit 0 ~ 255 正整数
无符号整数 UInt 16 bit 0 ~ 65535 正整数
无符号双整数 UDInt 32 bit 0 ~ 4294967295 大正整数
浮点数 Real 32 bit ±1.18E-38 ~ ±3.40E+38 带小数点的数(精度约6位)
长浮点数 LReal 64 bit 更大范围 高精度小数(精度约15位)
时间 Time 32 bit T#-24d20h31m23s648ms ~ T#24d20h31m23s647ms 持续时间
日期 Date 16 bit D#1990-01-01 ~ D#2089-12-31 日历日期
时间日期 Date_And_Time 64 bit   时间戳
字符串 String 最多254字符   文本,如 'ERROR_01'
讲师强调
  • Real 不是万能的! 它只有 32 位,精度约 6~7 位有效数字。算钱(财务)不能用 Real,会丢分!要用 LReal 或者转成整数(分)来算。
  • Int vs DInt:计数脉冲用 DInt,因为 Int 最大到 32767,高速计数器几毫秒就溢出了。

3.4.2 复合数据类型(进阶)

表格
 
 
类型 说明 示例
Array(数组) 同类型数据的连续队列 Array[0..9] of Int —— 10个整数
Struct(结构体) 不同类型数据的打包 一个结构体里包含:速度(Real)、使能(Bool)、报警码(Int)
UDT(用户数据类型) 自定义的"模板" 定义一个"电机"UDT,包含电流、温度、状态,然后在全局 DB 里创建 10 个电机实例

3.4.3 寻址与数据类型的"配对"关系

表格
 
 
寻址方式 适合的数据类型 示例
I0.0 Bool 读一个按钮
IB0 Byte / SInt / USInt 读8个开关状态
IW0 Word / Int / UInt 读一个模拟量(0~27648)
ID0 DWord / DInt / Real / Time 读一个浮点数(温度传感器)
DB1.Real_Var Real 直接符号寻址,最推荐

3.5 常见问题与实战技巧 —— 浮点数比较

看最后一张截图:如何比较两个浮点数是否相等?
问题3.14 存到 Real 里,可能变成 3.14000013.1399999。因为浮点数是二进制近似存储,直接判断 IF A == B 很可能永远为 FALSE。
正确做法(三种)
方法一:用容差比较(推荐)
scl
 
// 计算差值,看是否在允许范围内
#Temp_Diff := ABS(#Real_A - #Real_B);
IF #Temp_Diff < 1.0E-6 THEN
    // 认为相等
END_IF;
 
方法二:用 IN_RANGE 指令
scl
 
// 判断 B 是否在 [A-容差, A+容差] 范围内
IN_RANGE(MIN := #Real_A - 1.0E-6,
           VALUE := #Real_B,
           MAX := #Real_A + 1.0E-6);
 
方法三:转换为整数比较(工业现场常用) 比如传感器量程 0~100.0℃,精度 0.1℃。把 Real 乘以 10 转成 Int:
scl
 
#Temp_Int_A := REAL_TO_INT(#Real_A * 10.0);
#Temp_Int_B := REAL_TO_INT(#Real_B * 10.0);
IF #Temp_Int_A = #Temp_Int_B THEN
    // 在0.1℃精度下认为相等
END_IF;
 

本章小结 —— "记忆口诀"

今天总结:没有讲一条具体的梯形图指令,但我们搭起了整座大厦的地基。记住这几句话:
  1. 启动模式:STOP 睡觉,STARTUP 赖床伸懒腰(执行 OB100),RUN 搬砖。
  2. 程序结构:OB 是入口,FB 带记忆(背景 DB),FC 是工具人,DB 是仓库。
  3. 存储器:装载存程序(硬盘),工作存临时(内存),保持存宝贝(保险柜)。
  4. 五大地址区:I 是耳朵,Q 是手脚,M 是临时想法,DB 是档案室,L 是草稿纸。
  5. 寻址方式:过程映像保一致(I/Q),直接物理求快(:P),Slice 能切片,AT 能借壳。
  6. 数据类型:Bool 是开关,Int 是整数,Real 是小数(别直接比相等!),Array 是排队,Struct 是打包。
posted @ 2026-06-08 18:34  鬼门元歌  阅读(23)  评论(0)    收藏  举报