博途DB块使用详解

博途DB块使用详解


“我明明新建了输入映射DB和输出映射DB,为什么我不能直接写它们的值?”
“为什么我在程序里想给输入DB里的某个点赋值为1,却报错或者没效果?”

🧠 一、首先要明确概念:输入映射DB ≠ 输入区(I区)

当你自己新建一个全局DB,比如:

  • DB_InputMap:用来保存输入信号(IO映射)
  • DB_OutputMap:用来保存输出信号(IO映射)

它们只是普通的内存变量集合,并不和 PLC 实际的输入输出硬件(I、Q区)直接关联。

也就是说:

项目 系统自动IO区 你新建的全局DB
I区 硬件输入寄存器,PLC每扫描周期自动刷新 ❌ 你自己新建的DB不会自动刷新
Q区 硬件输出寄存器,PLC每扫描周期自动写出 ❌ 你自己新建的DB不会自动输出

👉 因此,如果你新建的 DB_InputMap 中变量是人工写的,比如:

DB_InputMap
 ├── Start_Button : Bool
 ├── Stop_Button  : Bool

你直接在程序里写:

DB_InputMap.Start_Button := TRUE;

如图所示对输入点"I42.5"的物理节做了映射,此时如果对"Input.DI1001FCFT"进行赋值 ,虽然语法没错,但逻辑上这是在改“内存变量”,不是改真实输入点
所以它不会影响实际的输入信号,也不会影响逻辑运算中“自动更新”的部分。

⚙️ 二、为什么你不能(或不应该)去改它

在实际工程中,“输入映射DB” 通常是设计成只读的,原因有三点:

1️⃣ 输入信号来自现场硬件(I区),不应该被程序随意更改。
它反映的是外部真实状态,比如按钮、传感器、开关等。

2️⃣ 在扫描周期开始时,PLC自动从I区读入输入映像区,如果你中途强制改值,下一周期又会被硬件刷新掉。因为在主函数"main"中是一直调用"IO映射"函数的,人为写入"Input.DI1001FCFT"进行赋值会被下一周期硬件刷新掉。

3️⃣ 人为写入会造成逻辑混乱,可能导致程序与现场状态不一致。


🔄 三、输入输出映射DB的正确使用方式

这种“映射DB”结构是对程序进行解耦规范化设计的常见方法,但必须分两步用:

✅ 第一步:映射硬件 → DB变量(输入映射)

// 在主程序开头,将I区输入信号赋值给DB变量
DB_InputMap.Start_Button := I0.0;
DB_InputMap.Stop_Button  := I0.1;
DB_InputMap.Sensor_OK    := I0.2;

🧩 说明:

  • DB_InputMap 是输入映射区,如"IO映射的Input块";
  • 它的值在每个扫描周期开始时从 I 区读入;
  • 程序内部所有逻辑都使用 DB_InputMap 中的变量,如使用"IO映射的Input块"中的变量,不再直接用 I 区。

✅ 第二步:DB变量 → 输出区(输出映射)

// 在主程序末尾,将输出映射DB变量写到Q区
Q0.0 := DB_OutputMap.Motor_Run;
Q0.1 := DB_OutputMap.Alarm_Light;

🧩 说明:

  • 程序中所有控制逻辑(FB、FC等)都只操作 DB_OutputMap,如"Output块数据";
  • 最后统一将结果映射回真实的 Q 区。

🧰 四、这样设计的优点

优点 说明
✅ 解耦硬件与逻辑 当你更换IO模块、改地址时,只需修改映射区,不用改逻辑程序
✅ 方便仿真 你可以在不接真实硬件时,手动修改DB_InputMap中的值进行模拟
✅ 清晰易读 逻辑层只用 DB_InputMap.Start_Button,一目了然

⚠️ 五、如果你想手动改输入值做测试怎么办?

你可以这样做:

方法1️⃣:在线监控手动强制

在TIA Portal在线状态下:

  1. 打开监控表;
  2. DB_InputMap.Start_Button 强制(Force)为 TRUE;
  3. 运行逻辑程序;
  4. 取消强制后恢复硬件输入。

方法2️⃣:用测试模式逻辑赋值

例如:

IF Test_Mode THEN
    DB_InputMap.Start_Button := TRUE;
END_IF;

这样你就可以在测试时模拟输入信号,而不改真实硬件。


🧾 六、总结(你现在的情况的根因)

现象 原因 解决方法
新建的输入DB不能直接改 它不是真实I区,只是内存变量 应从I区赋值过来
新建的输出DB不能立即生效 它不是真实Q区,只是内存变量 程序末尾统一赋值到Q区
想测试时赋1但没反应 输入DB是设计成只读映射 用Force或测试逻辑

✅ 七、正确结构示例(推荐)

// ========== 输入映射区 ==========
DB_InputMap.Start := I0.0;
DB_InputMap.Stop  := I0.1;

// ========== 程序逻辑 ==========
IF DB_InputMap.Start AND NOT DB_InputMap.Stop THEN
    DB_OutputMap.Motor_Run := TRUE;
ELSE
    DB_OutputMap.Motor_Run := FALSE;
END_IF;

// ========== 输出映射区 ==========
Q0.0 := DB_OutputMap.Motor_Run;

✅ 八、或在程序首次运行时(如OB100启动组织块)中手动赋值。

  1. 在项目树打开 Program blocks → OB100(Startup block)。如果 OB100 不存在就新建一个(语言选择 SCL 推荐)。
  2. 在 OB100 中写初始化代码(示例假设 DB 名为 DB_Init,数组 MyArray : ARRAY[0..9] OF INT):
// OB100 (SCL) 示例 —— 将数组全部置 0
VAR
  i : INT;
END_VAR

FOR i := 0 TO 9 DO
  DB_Init.MyArray[i] := 0;
END_FOR;

说明:

  • 如果你的数组下界不是 0(例如 [1..10]),就把循环范围改为对应的下/上界。
  • 如果你要按规则填充(比如每个元素等于索引值或某计算结果),在循环体内写相应表达式即可:DB_Init.MyArray[i] := i * 2; 等。
  1. 编译(Compile)OB100 与 DB,确保没有编译错误。
  2. 下载 OB100 和 DB 到 PLC(Download all required blocks)。
  3. 为使 OB100 执行:在在线界面对 PLC 做 Cold start / Restart(冷启动),OB100 会在启动时执行一次(Startup OB)。在调试时你也可以先停止 PLC 再启动以触发该 OB。

 


转载请注明出处:  https://www.cntworld.cn
智能工控 » 博途DB块使用详解

发表回复

提供最优质的资源集合

立即查看 了解详情
文章加载时间:0.0088 秒