DB 块访问
数据块 (Data Block, DB) 是 PLC 中用于存储数据的结构化内存区域,是程序间数据交换、HMI 数据访问、配方管理的基础。
DB 块概念
DB 块本质上是预定义的内存区域,包含结构化变量。与临时变量不同,DB 块的数据在扫描周期之间保持,并且在 PLC 停止/启动后可通过保持属性 (RETAIN) 持久化。
全局 DB 与背景 DB
| 类型 | 说明 | 使用场景 |
|---|---|---|
| 全局 DB | 全局可见,所有 POU 可读写 | 共享数据、工艺参数、IO 映射 |
| 背景 DB | 与功能块实例绑定,仅该实例可见 | 功能块内部状态存储 |
全局 DB 定义:
// 全局数据块: 工艺参数
DATA_BLOCK DB_ProcessParam
bEnable : BOOL := TRUE;
rSetTemp : REAL := 100.0;
rActTemp : REAL;
iErrorCode : INT;
sRecipeName : STRING[32];
END_DATA_BLOCK
背景 DB 定义 (自动生成):
// 调用 FB 时编译器自动生成背景 DB
VAR
fbMotor1 : FB_MotorControl; // 编译器为其生成背景 DB
fbMotor2 : FB_MotorControl;
END_VAR
符号寻址与绝对寻址
| 寻址方式 | 语法 | 示例 |
|---|---|---|
| 符号寻址 | DB_名称.变量 | DB_ProcessParam.rSetTemp |
| 绝对寻址 | DB<编号>.DBW<偏移> | DB1.DBW4 |
推荐使用符号寻址,便于代码阅读和维护。
在 SCL 中访问 DB 块
直接访问
PROGRAM Main
// 直接引用全局 DB 变量
rSetTemp := DB_ProcessParam.rSetTemp;
rActTemp := DB_ProcessParam.rActTemp;
// 写入 DB 变量
DB_ProcessParam.rActTemp := rSensorValue;
DB_ProcessParam.iErrorCode := 0;
END_PROGRAM
使用 AT 关键字映射到 IO
// 将 DB 变量映射到物理 IO 地址,实现结构化 IO 访问
DATA_BLOCK DB_IO_Mapping
// 数字量输入
bStartBtn : BOOL AT %IX0.0;
bStopBtn : BOOL AT %IX0.1;
bEmergency : BOOL AT %IX0.2;
bSensorIn : BOOL AT %IX1.0;
bSensorOut : BOOL AT %IX1.1;
// 数字量输出
bMotorRun : BOOL AT %QX0.0;
bAlarmLamp : BOOL AT %QX0.1;
bValveOpen : BOOL AT %QX0.2;
// 模拟量
rTempIn : REAL AT %IW100;
rSpeedOut : REAL AT %QW200;
END_DATA_BLOCK
结构体嵌套
TYPE ST_AxisConfig :
STRUCT
rMaxSpeed : REAL := 3000.0;
rAccelTime : REAL := 0.5;
rDecelTime : REAL := 0.3;
rJerkLimit : REAL := 10000.0;
bEnablePos : BOOL := TRUE;
bEnableNeg : BOOL := TRUE;
END_STRUCT;
END_TYPE
TYPE ST_MachineData :
STRUCT
sMachineName : STRING[32];
iAxisCount : INT;
stAxes : ARRAY[0..7] OF ST_AxisConfig;
rProductionCounter : REAL;
bMaintenanceMode : BOOL;
END_STRUCT;
END_TYPE
// 全局 DB 使用嵌套结构体
DATA_BLOCK DB_Machine
stData : ST_MachineData;
END_DATA_BLOCK
// 访问
DB_Machine.stData.stAxes[0].rMaxSpeed := 2000.0;
DB_Machine.stData.bMaintenanceMode := TRUE;
在 HMI 中访问 DB 变量
变量绑定
HMI 控件通过变量路径直接绑定 DB 变量:
路径格式: DB_名称.变量名
示例: DB_ProcessParam.rSetTemp
读写权限
| 变量类型 | HMI 默认权限 | 说明 |
|---|---|---|
| 输入参数 | 只读 | 防止 HMI 误修改输入 |
| 输出参数 | 可读写 | 监控与操作 |
| 内部变量 | 只读 | 不允许 HMI 直接修改 |
| 全局 DB | 可读写 | 按需配置 |
数组与结构体
<!-- HMI 数据源配置示例 -->
<DataSource Name="AxisSpeed">
<Binding Path="DB_Machine.stData.stAxes[0].rMaxSpeed" />
</DataSource>
跨程序 DB 共享
多 OB 访问同一 DB
// OB1 (主循环) — 读取配置,写入 IO
DB_ProcessParam.rActTemp := %IW100;
// OB30 (10ms 周期中断) — PID 控制
fbPID_Temp(
rSetpoint := DB_ProcessParam.rSetTemp,
rFeedback := DB_ProcessParam.rActTemp
);
多 PLC 间 DB 共享 (DarraLink)
通过 DarraLink 协议(端口 18821),远程 PLC 可读写本机 DB 块:
// C# SDK: 远程读取 DB 变量
var client = new DarraLinkClient("192.168.1.100", 18821);
float temp = await client.ReadDbAsync<float>("DB_ProcessParam", "rSetTemp");
await client.WriteDbAsync("DB_ProcessParam", "rSetTemp", 150.0f);
DB 在线监视
IDE 在线监视
在 IDE 中打开 DB 块,切换到在线模式即可监视和修改:
| 功能 | 说明 |
|---|---|
| 在线值 | 显示当前运行值 |
| 修改值 | 允许直接写入测试值 |
| 强制值 | 锁定变量为指定值 (不受程序影响) |
| 趋势图 | 选择变量加入趋势图观察变化 |
强制操作
// 在 IDE 中强制 DB 变量
// 方法 1: 右键变量 → 强制值
// 方法 2: 使用在线面板
// 强制时显示状态
// 正常值 (黑色) ← 正常运行
// 强制值 (紫色) ← 已强制锁定
// 修改值 (蓝色) ← 单次写入
保持 (RETAIN) 属性
断电时保持数据,适用于累计值、配方等需要持久化的数据。
DATA_BLOCK DB_RetainData
// 保持型变量 (断电不丢失)
diTotalCounter : DINT := 0;
rRecipeParam : REAL := 25.0;
sLastRecipe : STRING[32];
END_DATA_BLOCK
批量操作
批量初始化
// 在 OB100 中初始化所有 DB 变量
IF OB100_FirstScan THEN
// 复位工艺参数
DB_ProcessParam.rSetTemp := 0.0;
DB_ProcessParam.iErrorCode := 0;
// 批量数组赋值
FOR i := 0 TO 7 DO
DB_Machine.stData.stAxes[i].rMaxSpeed := 3000.0;
END_FOR;
END_IF;
批量复制
// 结构体整体复制 (同类型)
DB_Machine_Backup.stData := DB_Machine.stData;
// 数组复制
arTemp := DB_ProcessParam.arHistory;
DB 在线监视与修改
在线模式
在 IDE 中打开 DB 块,切换到在线模式后可以实时监视和修改变量值。
| 功能 | 操作方式 | 显示颜色 |
|---|---|---|
| 在线监视 | 点击"在线"按钮或按 F5 | 黑色 — 正常运行值 |
| 修改值 | 双击变量输入新值后回车 | 蓝色 — 单次写入 |
| 强制值 | 右键 → 强制 → 输入值 | 紫色 — 锁定值 |
| 取消强制 | 右键 → 取消强制 | 恢复黑色 |
强制操作
强制用于调试场景,将变量锁定为指定值,不受 PLC 程序影响:
// 在 IDE 中执行强制后,以下程序写入不会生效
// 强制值始终为 TRUE,即使程序写入 FALSE
DB_Status.bAlarmActive := FALSE; // 被强制,不生效
强制注意事项:
- 强制仅对单个变量有效,结构体强制会锁定整个结构体
- PLC 停止或重启后强制保持(可配置是否清除)
- 强制值在项目关闭后自动清除
- 生产运行时建议取消所有强制
趋势图
选择 DB 变量加入趋势图面板,观察变量随时间的变化曲线:
- 右键 DB 变量 → 添加到趋势图
- 设置采样周期(100ms ~ 10s)
- 趋势图支持多条曲线叠加对比
DB 数据持久化
RETAIN 保持
RETAIN 变量在 PLC 断电后保持值不变,适用于累计值、计数值、工艺参数等。
DATA_BLOCK DB_RetainData
// 保持型变量 — 断电不丢失
RETAIN
diTotalCounter : DINT := 0; // 总产量计数
rLastRecipeTemp : REAL := 0.0; // 上次配方温度
sLastOperator : STRING[16]; // 最后操作员
bCalibrated : BOOL := FALSE; // 校准标志
END_RETAIN
// 非保持变量 — 断电清零
iErrorTemp : INT;
END_DATA_BLOCK
PERSISTENT 持久化
PERSISTENT 是比 RETAIN 更强的持久化方式,即使项目重新下载也能保持:
DATA_BLOCK DB_PersistentData
PERSISTENT
diLifetimeCounter : DINT := 0; // 生命周期累计 — 永不重置
sSerialNumber : STRING[16]; // 设备序列号
dInstallDate : DATE; // 安装日期
END_PERSISTENT
END_DATA_BLOCK
持久化策略对比
| 特性 | RETAIN | PERSISTENT | 普通变量 |
|---|---|---|---|
| 断电保持 | ✓ | ✓ | ✗ |
| 项目下载后保持 | ✓ (配置项) | ✓ | ✗ |
| 跨固件升级保持 | ✗ | ✓ | ✗ |
| 存储介质 | SRAM/FRAM | Flash | RAM |
| 写寿命 | 无限 | 10^5 次 | 无限 |
| 典型应用 | 计数值、工艺参数 | 序列号、校准参数 | 临时数据 |
持久化存储配置
在 IDE 项目属性中配置持久化区域大小:
| 参数 | 默认值 | 最大值 | 说明 |
|---|---|---|---|
| RetainSize | 16 KB | 256 KB | RETAIN 区大小 |
| PersistentSize | 4 KB | 64 KB | PERSISTENT 区大小 |
| RetainRetention | 10 年 | — | 电池备份保持时间 |
持久化写寿命
PERSISTENT 使用 Flash 存储,写入次数有限(约 10^5 次)。不要在 PERSISTENT 中存放频繁变化的变量(如扫描计数),应在 RETAIN 中存放。IDE 编译时会检查 PERSISTENT 变量写入频率并给出警告。
NVRAM 完整性校验
PLC 启动时自动校验非易失存储完整性:
- CRC 校验 — 失败则 RETAIN 区清零,触发 OB100 冷启动
- 电池低压预警 — 状态字
%SW50位 0 置 1 - 日志记录每次 NVRAM 写入(长寿命管理)
- 电池电量不足时,IDE 报警提示更换
排错表
| 问题 | 原因 | 解决 |
|---|---|---|
| DB 变量无法写入 | 变量被强制 | 在 IDE 中取消强制 |
| 断电后值丢失 | 未声明 RETAIN | 改用 RETAIN 变量 |
| HMI 读不到 DB 值 | 变量路径错误 | 检查路径格式 DB_名称.变量 |
| 多 OB 写冲突 | 同一变量被多处写 | 收拢写点为单一 POU |
| 背景 DB 误删 | 删除了 FB 实例 | 删除前先解引用 |
| 结构体尺寸不匹配 | 在线修改了结构体 | 重新编译整个项目 |
| PERSISTENT 写入超寿命 | 频繁写入 Flash | 改用 RETAIN 存储 |
| 电池低压报警 | 备份电池耗尽 | 更换电池后热重启 |
| 在线监视显示 ### | 变量路径不可达 | 确认 PLC 在线状态 |
最佳实践
- 命名规范: DB 名称加
DB_前缀,如DB_ProcessParam - 分组管理: 按功能域分组 DB (工艺参数 / 报警 / 配方 / IO 映射)
- 初始化: 默认值在声明时设定,避免运行时初始化遗漏
- 保持策略: 仅对需要断电保持的变量声明 RETAIN
- 访问权限: 关键变量(温度上限、速度上限)在 HMI 中设为只读
- 版本管理: DB 结构变更时同步更新所有引用的 POU 和 HMI
- 写收敛: 每个 DB 变量尽量只在一个 POU 中写入,避免多源冲突
- 大小控制: 单个 DB 不超过 64 KB,超大数据使用多个 DB 分段
- 持久化分层: 频繁变化 → RETAIN;极少变化 → PERSISTENT
- 在线修改慎重: 在线修改变量值仅用于调试,正式运行需修改源码并重新下载