复制 数据块DB到项目前,先理解它的本质:DB是PLC的"电子表格",存放程序运行需要的所有变量。用不好会导致程序臃肿、扫描周期变长、调试困难。本文从创建到优化,手把手教你把DB用得干净利落。
一、DB的两种类型:选对才能少走弯路
PLC提供两种数据块,选错类型后期改动成本极高。
| 类型 | 英文名 | 核心特点 | 适用场景 |
|---|---|---|---|
| 全局DB | Global DB | 所有程序块都能读写,无限制 | 设备参数、HMI交互数据、跨块共享数据 |
| 背景DB | Instance DB | 专属绑定某个FB,自动跟随 | 配合FB使用,存储该FB的静态变量 |
判定标准:如果多个程序块需要读写同一组数据,选择 全局DB;如果数据只服务于某个功能块(如电机控制FB),选择 背景DB让系统自动管理。
二、创建DB的完整流程
2.1 全局DB创建步骤
打开 TIA Portal项目,双击 PLC设备 下的 程序块 文件夹。右键 空白处,选择 添加新块 → 数据块。命名 遵循规则:前缀+功能+序号,例如 DB10_MotorParam。取消勾选 "优化的块访问"(如需兼容S7-300/400或传统寻址),或保持勾选(推荐用于S7-1200/1500,支持符号寻址和更大的地址空间)。
点击 确定后进入DB编辑界面。双击 第一行 名称 列,输入 变量名如 MotorSpeed。选择 数据类型:Real(浮点数)、Int(整数)、Bool(开关量)、Array(数组)、Struct(结构体)等。在 起始值 列 填入 默认值,在 注释 列 填写 中文说明。
2.2 关键设置项解析
优化的块访问(Optimized block access):
- 勾选状态:变量无固定地址,系统自动分配。优势是存储紧凑、无对齐填充、支持复杂数据类型嵌套。劣势是无法使用绝对地址(如
DB1.DBW0),必须用符号名(如MotorParam.MotorSpeed)。 - 取消勾选:变量显示绝对地址(
偏移量列),兼容传统S7-300/400语法,但会浪费存储空间(Bool占1字节而非1位)。
仅存储在装载存储器(Retain实际为"仅存储在装载存储器"的误译,正确理解是"写保护"或"仅装载存储"):
- 对于S7-1500,此选项实际指数据仅保存在装载存储器(存储卡),不占用工作存储器。适合存储大量常数参数,但读取速度较慢。
三、寻址方式详解:符号寻址 vs 绝对寻址
3.1 符号寻址(推荐)
格式:"DB名称".变量名 或 DB名称.变量名
示例:
"MotorParam".StartCommand
"RecipeData".Ingredient[3].Weight
优势:程序可读性强,修改变量顺序不影响代码,自动完成和类型检查有效。
在程序中使用方法:
打开 程序块(OB/FB/FC),拖动 指令如 MOVE。点击 输入引脚,输入 双引号 "开始 输入DB名,选择 自动提示的DB,继续 输入点号 .选择 目标变量。
3.2 绝对寻址(兼容旧系统)
格式:DB[块号].数据类型[字节地址]
| 数据类型 | 后缀 | 占用空间 | 示例 |
|---|---|---|---|
| 位 | DBX |
1位 | DB1.DBX0.0(第0字节第0位) |
| 字节 | DBB |
8位 | DB1.DBB0(第0字节) |
| 字 | DBW |
16位 | DB1.DBW2(第2-3字节) |
| 双字 | DBD |
32位 | DB1.DBD4(第4-7字节) |
关键规则:地址必须连续对齐。Real 和 DInt 需双字对齐(地址能被4整除),Int 和 Word 需字对齐(地址能被2整除)。强行 使用不对齐地址会触发编译错误。
启用绝对寻址:右键 DB → 属性 → 常规 → 取消勾选 优化的块访问。
四、高级数据结构:数组与结构体
4.1 数组(Array)的创建与访问
应用场景:10台电机的速度设定值,用数组比单独建10个变量更高效。
创建步骤:在 DB中 新建 变量,命名 MotorSpeedSet,选择 数据类型为 Array[1..10] of Real。在 数组元素 右键 → 编辑数组元素,可单独 为每个元素设置起始值。
程序访问方法:
- 直接索引:
"MotorParam".MotorSpeedSet[5]→ 访问第5台电机设定值 - 变量索引:使用
PEEK/POKE指令或 在 SCL中 直接 用整型变量作为索引
SCL示例:
// 循环初始化10台电机参数
FOR #i := 1 TO 10 DO
"MotorParam".MotorSpeedSet[#i] := 1500.0; // 默认1500rpm
"MotorParam".MotorEnable[#i] := TRUE;
END_FOR;
4.2 结构体(Struct)的嵌套设计
应用场景:配方数据包含名称、温度、时间、重量等多个属性。
创建步骤:在 DB中 新建 变量,命名 Recipe,选择 数据类型为 Struct。点击 展开箭头,添加 成员:Name(String[20])、Temp(Real)、Time(Time)、Weight(Real)。
嵌套结构体:在 结构体中 再添加 Struct 类型成员,实现层级数据。例如 Recipe → HeatingStage → Stage1/Stage2,每个阶段有自己的温度时间参数。
访问路径:"RecipeData".Recipe.HeatingStage.Stage1.Temp
五、DB优化实战技巧
5.1 存储空间压缩
问题诊断:右键 DB → 属性 → 占用 标签页,查看 "装载存储器"和"工作存储器"占用。对比 实际变量总量与占用字节,识别浪费。
压缩方法:
- 启用 优化的块访问:Bool类型从1字节压缩到1位,理论上可节省87.5%的布尔存储空间
- 调整 变量顺序:将相同类型变量集中排列,减少填充字节。手动 调整非优化DB的变量顺序,或使用
重新组织功能 - 使用 合适的数据类型:
SInt(-128~127,1字节)替代Int(-32768~32767,2字节)用于小范围数值
5.2 访问速度优化
局部变量缓存:频繁访问的DB变量,在 FB的 Temp 区 建立 副本,运算 完成后再写回。
示例:
// 不好的做法:每次循环都访问DB
FOR #i := 1 TO 1000 DO
#Result := "GlobalDB".InputValue * #i;
"GlobalDB".OutputArray[#i] := #Result;
END_FOR;
// 好的做法:缓存到临时变量
#CachedInput := "GlobalDB".InputValue;
FOR #i := 1 TO 1000 DO
#Result := #CachedInput * #i;
END_FOR;
"GlobalDB".OutputArray := #CachedArray; // 批量写回(若类型匹配)
5.3 保持性(Retain)设置
设置位置:在 DB编辑界面,点击 变量行的 保持性 列的复选框,或 在 变量属性中 设置。
范围选择:
- 仅选定变量:勾选特定变量,适合少量关键参数
- 所有变量:在 DB属性 →
常规→保持性选择 "在DB中设置保持性",所有标记变量自动保持
断电保持机制:S7-1200需搭配电池卡或CM1241,S7-1500内置超级电容/电池,数据保存至断电保持存储器。
六、DB与HMI的数据交互
6.1 HMI直接访问DB
配置步骤:在 TIA Portal中 打开 HMI设备,进入 HMI变量 编辑器。点击 添加 → PLC变量,浏览 至目标DB,选择 具体变量。设置 采集模式:循环连续(实时更新)或 必要时(降低通信负荷)。
性能优化:避免 HMI直接访问大型数组元素,建议 在PLC中 建立 HMI专用交互DB,只包含 当前显示需要的变量,通过 程序 定时刷新。
6.2 配方管理实现
标准方案:使用 PLC数据类型(UDT)定义 配方结构,创建 数据块 DB_RecipeStore,类型 为 Array[1..50] of "UDT_Recipe"。
配方切换流程:
- HMI 写入 目标配方号至
HMI_DB.SelectedRecipeNo - PLC 验证 编号合法性(1-50)
- 复制
DB_RecipeStore.Recipe[#SelectedNo]至DB_ActiveRecipe - 设备 按
DB_ActiveRecipe参数 运行
// SCL配方加载程序
IF #LoadRecipeTrig AND #SelectedNo >= 1 AND #SelectedNo <= 50 THEN
"ActiveRecipe" := "RecipeStore".Recipe[#SelectedNo];
#RecipeLoaded := TRUE;
ELSE
#RecipeLoaded := FALSE;
END_IF;
七、调试与故障排查
7.1 在线监控DB
操作步骤:下载 程序后,双击 打开DB,点击 工具栏 眼镜 图标(监视模式)。观察 实际值 列与 起始值 列的差异,黄色 背景表示该值正在被程序修改。
强制修改变量:在 监视模式下,右键 目标变量 → 修改 → 修改为1 或 修改为0(Bool),或 修改值(其他类型)。用于 模拟信号测试。
7.2 常见编译错误
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
| 地址重叠 | 非优化DB中变量地址冲突 | 检查 偏移量列,调整 地址或 改用 优化访问 |
| 类型不兼容 | 程序中变量类型与DB定义不符 | 核对 数据类型,Bool 与 Byte 不可混用 |
| 符号未定义 | 程序中使用了已删除或重命名的DB变量 | 更新 程序中的符号引用,或 使用 重新连接 功能 |
| 保持性冲突 | 优化DB与非优化DB的保持性设置矛盾 | 统一 项目中的保持性配置方式 |
7.3 数据一致性保护
风险场景:程序正在写入DB某变量时,HMI同时读取,可能得到新旧混合的无效数据(如32位Real只更新了低16位)。
保护措施:
- 使用
AT覆盖:将大变量拆分为字节数组,用SCL逐字节拷贝实现原子操作 - 建立 互锁标志:
DB_HMI.HMIReading为TRUE时,PLC暂停写入该数据区 - 优先 使用S7-1500的
数据块不可中断属性:在 DB属性 →属性勾选 "不可中断的数据访问"
八、完整项目示例:电机控制DB设计
场景:控制8台变频器电机,每台需正反转命令、速度设定、电流反馈、运行状态、故障代码。
UDT定义(PLC数据类型):
| 名称 | 数据类型 | 说明 |
|---|---|---|
| StartFwd | Bool | 正转启动命令 |
| StartRev | Bool | 反转启动命令 |
| Stop | Bool | 停止命令 |
| SpeedSet | Real | 速度设定值,单位rpm |
| CurrentAct | Real | 电流实际值,单位A |
| Running | Bool | 运行状态反馈 |
| Fault | Bool | 故障状态 |
| FaultCode | Word | 故障代码 |
DB结构:
DB_MotorControl (全局DB,优化访问)
├── Motor[1..8] : Array of "UDT_Motor" // 8台电机数组
├── HMIInterface : Struct // HMI交互区
│ ├── SelectedMotor : Int // HMI选择的电机号
│ ├── CmdPanel : "UDT_Motor" // 当前操作的命令面板
│ └── ApplyCmd : Bool // 应用命令触发
└── System : Struct // 系统级参数
├── MaxCurrent : Real // 最大电流限制
└── AlarmDelay : Time // 故障确认延时
程序调用示例:
// 主循环中处理HMI命令
IF "DB_MotorControl".HMIInterface.ApplyCmd THEN
#Selected := "DB_MotorControl".HMIInterface.SelectedMotor;
IF #Selected >= 1 AND #Selected <= 8 THEN
// 将HMI命令写入对应电机
"DB_MotorControl".Motor[#Selected].StartFwd :=
"DB_MotorControl".HMIInterface.CmdPanel.StartFwd;
"DB_MotorControl".Motor[#Selected].SpeedSet :=
"DB_MotorControl".HMIInterface.CmdPanel.SpeedSet;
END_IF;
"DB_MotorControl".HMIInterface.ApplyCmd := FALSE; // 复位触发位
END_IF;
掌握 这些技巧后,评估 现有项目的DB使用情况:检查 是否有非必要取消优化的DB,合并 分散的同类数据块,重构 重复代码为数组+循环结构。一个设计良好的DB架构,能让程序量减半,调试时间缩短三分之二。

暂无评论,快来抢沙发吧!