# DB_MbMultiRead —— 配套全局 DB 说明

> 配套 `FB_MbMultiRead`（S7-1500 Modbus TCP 主站，v3.5）
> 网页版：https://axby.cn/code/modbus-multiread/

## 一、这个 DB 是干什么的

`FB_MbMultiRead` 的三个数据引脚（`aSta` / `aTask` / `aBuf`）是 **`VAR_IN_OUT`**，
块本身不存数据 —— 数组得从外面传进来。所以你需要一个**全局 DB** 装这三张表，
再在 OB1 里把 DB 的三个成员接到 FB 的三个引脚上。

这个文件就是那份**开箱即用的全局 DB**。

| DB 成员 | 类型 | 对应 FB 引脚 | 用途 |
|---|---|---|---|
| `Station` | `Array[1..8] of "UDT_MbStation"` | `aSta` | 从站表，下标即连接槽位号 |
| `Task` | `Array[1..32] of "UDT_MbTask"` | `aTask` | 任务表，最多 32 条 |
| `Buffer` | `Array[0..999] of Word` | `aBuf` | 数据总缓冲，读的落点、写的来源 |

> 成员名和引脚名不一样（`Station` ↔ `aSta`）是正常的：IN_OUT 按**类型和长度**匹配，
> 不按名字匹配。博图里连线时选中 FB 引脚，拖到 DB 里的对应成员即可。

## 二、怎么导入

**顺序不能反**，因为 DB 用到了 FB 源文件里定义的两个 UDT：

1. 先导入 `FB_MbMultiRead_EN.scl`（或另外两个编码版本之一），
   **从源生成块** → 全选 `UDT_MbStation`、`UDT_MbTask`、`FB_MbMultiRead` 三项一起生成。
2. 再导入 `DB_MbMultiRead.scl`（同一步：从源生成块）→ 只会列出 `DB_MbMultiRead` 一项。
3. 打开 OB1，把 `FB_MbMultiRead` 拖进网络：
   - `aSta` ← `"DB_MbMultiRead".Station`
   - `aTask` ← `"DB_MbMultiRead".Task`
   - `aBuf` ← `"DB_MbMultiRead".Buffer`
4. FB 的**实例 DB**（`FB_MbMultiRead_DB`）由博图自动生成，不用手工建。

### 文件格式说明

| 文件 | 编码 | 说明 |
|---|---|---|
| `DB_MbMultiRead.db` | UTF-8 + BOM | 原样保留的源文件（`DATA_BLOCK` 文本格式） |
| `DB_MbMultiRead.scl` | 纯 ASCII | **首推导入版** —— 博图"添加新的外部源文件"对话框默认只显示 `*.scl`，用这个直接能选中 |

> 博图把外部源文件对话框的过滤器默认设成 `*.scl`，`.db` 后缀选不到。
> 两个文件内容完全一样，只是扩展名和换行符不同。

## 三、几个注意点

1. **`NON_RETAIN` 是故意的。** 这张 DB 装的是 IP、端口、任务表 —— 断电重启后
   应该回到初始值，而不是把上次的 IP 留在 PLC 里。这也是官方 `MB_CLIENT_DB`
   一贯的做法。
2. **`Station` 的 `uUnitId` 默认 `16#FF`（255）**，这是 MB_CLIENT 的出厂默认值。
   直连设备一般要改成 **1**，否则采不回来。改的是 `DB_MbMultiRead`.`Station[n].uUnitId`。
3. **别先手工新建同名 DB**，直接用源生成，否则会撞名。
4. 这个 DB **只装表和缓冲**，不装 `MB_CLIENT` 自己的 DB。`MB_CLIENT_DB` /
   `MB_CLIENT_PARA` 里的现场 IP 与连接号由博图自己生成，重导会冲掉你的配置 ——
   所以下载包里**故意不含**那两个。
5. `Buffer` 是 **1000 个字**。要改大必须**两处一起改**：DB 里的 `Array[0..999]`
   和 FB 源里 `aBuf` 的 `VAR_IN_OUT` 声明（外加 FB 内部那两处边界常数）。
   只改一处会越界。

## 四、验证记录

`verify_db_multiread.py` 逐项比对 DB 与 FB 的接口定义，**27 项检查全部通过**：

- 三个成员的数组上下限与元素类型，和 FB 三个 IN_OUT 引脚**逐项相等**
- DB 引用的两个 UDT，在 FB 源文件里确实有 `TYPE` 定义
- 两个 UDT 的全部字段名与 FB 源里的定义一致（改了 UDT 忘了改 DB 会被抓出来）
- `Buffer` 恰好 1000 个字、`Station` 8 个槽位、`Task` 32 条

```bash
python verify_db_multiread.py
```

---

> 源码按「现状」免费提供，仅供学习交流与合法用途。
> 用到项目上请自行验证，关键工况务必先在测试台上跑一遍。
> 设备型号、模块版本、现场条件各不相同，落地前还得对着厂家手册和图纸核实 ——
> 这里能帮少走弯路，不能替你签字。
