PLC 设备配置
在平台上接入 PLC(Modbus)设备:设备连接参数(串口/TCP 地址、从站号、默认字节序)由连接器侧统一配置,不写在指令里;日常工作重心是在仪器指令库中**「编辑读取指令 / 编辑设置指令」**创建指令——平台把 READ:地址:类型 这样的模板翻译成 Modbus 报文(FC01/02/03/04/05/06/10),读线圈、读寄存器、写位、写字全部由模板驱动。
本文以西门子 S7-200 SMART 为贯穿示例,要读哪个点、写哪个点,直接对照第 7 节速查表复制即可。
相关页面:仪器兼容表、PMBus 设备配置、UDS 设备配置。
1. 配置前先懂地址
1.1 地址前缀决定读写方式
Modbus 用展示地址的首位数字区分四类寄存器区,平台按前缀自动选功能码:
| 展示地址范围 | 前缀 | 含义 | 读取功能码 | 能否写 |
|---|---|---|---|---|
| 1 ~ 9999 | 0xxxx | 线圈(DO) | FC01 | 可写(FC05) |
| 10001 ~ 19999 | 1xxxx | 离散输入(DI) | FC02 | 只读 |
| 30001 ~ 39999 | 3xxxx | 输入寄存器(AI) | FC04 | 只读 |
| 40001 ~ 49999 | 4xxxx | 保持寄存器(AO/通用) | FC03 | 可写(FC06/FC10) |
bit 参数在两类地址区含义不同,最容易搞混:
| 地址区 | bit 含义 | 示例 |
|---|---|---|
| 0xxxx / 1xxxx | 相对基址的线圈/离散输入偏移,实际访问地址 = 基址 + bit(单点读) | READ:00001:BOOL:5 读基址 00001 再偏移 5 的单点 |
| 3xxxx / 4xxxx | 16 位寄存器内的字内位(0 ~ 15) | READ:40001:BOOL:5 读 40001 寄存器的第 5 位 |
1.2 200SMART:所有信号都在 4xxxx
200SMART 把 DI/DO/AI/AO 全部映射到 V 区变量存储器,Modbus 侧统一暴露为保持寄存器(4xxxx),只用 FC03/FC06/FC10 访问。「DI/AI 只读」是应用层业务约定,协议层并不阻止写入。
| 业务类型 | 地址范围 | 数据类型 | 占用寄存器 | 读写 |
|---|---|---|---|---|
| DI 数字输入 | 40001 ~ 40004 | Bool(字级,一位一点) | 1 | 只读 |
| DO 数字输出 | 40010 ~ 40016 | Bool(字级) | 1 | 读写 |
| AI 模拟输入 | 40020 ~ 40118 | Real(32 位浮点) | 2 | 只读 |
| AO 模拟输出 | 40200 ~ 40238 | Real(32 位浮点) | 2 | 读写 |
常用点位:40001 第 0 位 = XDI_01 紧急停止、第 5 位起 = MDI_01 开关量检测;40010 第 0~3 位 = 红灯 / 绿灯 / 蜂鸣器 / 黄灯、第 4 位起 = 开关量控制;40020、40022、40024… = 传感器 1、2、3…;40200、40202… = 模拟量控制 1、2…。完整点表以 PLC 侧寄存器定义为准。
1.3 业务写法转平台写法
老文档 / 点表里的 READ:DI:40001:0 是业务含义写法,平台上必须转成「数字地址 + 数据类型」:
| 业务写法(文档/点表) | 平台指令模板 |
|---|---|
READ:DI:40001(整字) | READ:40001:UINT16 |
READ:DI:40001:0(字内位) | READ:40001:BOOL:0 |
READ:AI:40020 | READ:40020:FLOAT |
WRITE:DO:40010:0:1 | WRITE:40010:BOOL:0:1 |
2. 数据类型(dtype)怎么选
| dtype | 占用寄存器 | 适用场景 | 指标类型 |
|---|---|---|---|
BOOL | 1 | 位信号;带 bit 时为字内位或线圈偏移 | 数值(0/1) |
INT16 / UINT16 | 1 | 单字整数(整字状态、计数) | 数值 |
INT32 / UINT32 | 2 | 双字整数 | 数值 |
FLOAT | 2 | 32 位浮点物理量(200SMART 的 AI/AO) | 数值 |
DOUBLE | 4 | 64 位双精度浮点 | 数值 |
- 大小写不敏感,内部统一转大写。
- 读段的类型以模板中的 dtype 为准,测试参数改不了它;要换类型就改模板。
3. 第一步:编辑读取指令
在仪器指令库中新增读取指令,页面分三块:基本信息(指令名称 / 指令编码 / 示例模板 / 指令模板 / 指令说明)、测试参数、测试指标。读取指令的核心:指令模板 + 测试指标(指标条数必须与模板段数一致,见 3.4)。
3.1 模板格式
READ:<addr>:<dtype>[:<bit>][;<addr>:<dtype>[:<bit>]]...[;EXPR:<表达式>]- 首段必须以
READ:开头;后续各段直接写地址:类型,不要再写READ:。 <addr>:整数展示地址(如40020、00001)。<dtype>:第 2 节的数据类型之一。<bit>:可选,0 ~ 15,含义见1.1 节。EXPR:段放在最后,用于换算,见3.4 节。
3.2 配置示例:读取模拟量(200SMART 传感器1)
| 项目 | 填写 |
|---|---|
| 指令名称 | 读取传感器1 |
| 指令编码 | get_read_vc01 |
| 示例模板 | (与指令模板相同,系统自动带出) |
| 指令模板 | READ:40020:FLOAT |
| 指令说明 | 200SMART 传感器1(VD20),量程 0~1600 |
测试指标(1 条):
| 指标名称 | 指标编码 | 指标类型 | 指标分类 | 指标单位 |
|---|---|---|---|---|
| 传感器1 | vc01 | 数值 | 数字 | 按物理量填 |
读整字还是读字内位:
| 需求 | 指令模板 | 说明 |
|---|---|---|
| 读整字(0 ~ 65535) | READ:40001:UINT16 | 1 条指标,返回 16 位整数 |
| 读字内某一位 | READ:40001:BOOL:5 | 1 条指标,返回 0/1 |
3.3 配置示例:读取数字量(紧急停止)
| 项目 | 填写 |
|---|---|
| 指令名称 | 读取紧急停止 |
| 指令编码 | get_read_estop |
| 指令模板 | READ:40001:BOOL:0 |
| 指标名称 / 编码 | 紧急停止 / estop |
| 指标类型 / 分类 | 数值 / 数字 |
3.4 多段读取与 EXPR(一次读多个量)
; 分隔的每一段(含 EXPR:)对应一条测试指标,顺序一一对应。示例——读传感器 1、2 并算平均值,共 3 条测试指标:
| 项目 | 填写 |
|---|---|
| 指令名称 | 读取传感器1/2及平均值 |
| 指令编码 | get_read_vc_avg |
| 指令模板 | READ:40020:FLOAT;40022:FLOAT;EXPR:(vc01+vc02)/2 |
| 顺序 | 指标名称 | 指标编码 | 指标类型 |
|---|---|---|---|
| 1 | 传感器1 | vc01 | 数值 |
| 2 | 传感器2 | vc02 | 数值 |
| 3 | 平均值 | vc_avg | 数值(小数位建议 2) |
规则要点:
- 段数(含 EXPR 段)必须等于指标条数,否则报「模板段数与 replys 数量不匹配」。
- EXPR 中的变量名必须是前面某条指标的指标编码(如
vc01),按段顺序对应。 - 安全表达式:支持
+ - * / % **、括号、一元负号及abs/round/min/max/sqrt;不支持其它函数、属性、下标。
3.5 字节序参数(byteorder / wordorder)
- 多寄存器类型(
INT32/UINT32/FLOAT/DOUBLE)的解码受字节序影响;单字类型不受影响。 - 字节序不写在模板里。需要对单条指令覆盖时,在「测试参数」里添加编码为
byteorder/wordorder的参数,取值big/little。 - 不添加时使用仪器默认值(200SMART 常见 big / big)。
- FLOAT 读出来是离谱大数或 0,先查字节序,再查地址。
4. 第二步:编辑设置指令
写操作一般不添加测试指标,把写入值开放为测试参数,执行时填写。
4.1 模板格式
WRITE:<addr>:<dtype>:<值>
WRITE:<addr>:<dtype>:<bit>:<值>可选后缀(仅一段写操作后允许):;EXPR:<表达式>。
- 三字段:整字 / 多寄存器写,写入值按 dtype 编码。0xxxx 写线圈也用三字段(dtype 填
BOOL、值0/1)。 - 四字段:仅 4xxxx 保持寄存器字内位写(读-改-写),bit 0 ~ 15,值
0/1。 - 1xxxx / 3xxxx 禁止写:只读区,配置了会被拒绝。
4.2 配置示例:写模拟量控制1
| 项目 | 填写 |
|---|---|
| 指令名称 | 设置模拟量控制1 |
| 指令编码 | set_ao_01 |
| 指令模板 | WRITE:40200:FLOAT:{{value}} |
| 指令说明 | 200SMART 模拟量控制1(VD200) |
测试参数(点「添加参数」):
| 字段 | 填写 |
|---|---|
| 参数名称 | 模拟量控制1 |
| 参数编码 | value(必须与模板占位符一致) |
| 参数类型 / 分类 | 数值 / 数字 |
| 参数形式 | 自定义,范围 0 ~ 1600 |
4.3 配置示例:开关红灯(写字内位)
| 项目 | 填写 |
|---|---|
| 指令名称 | 红灯开关 |
| 指令编码 | set_red_lamp |
| 指令模板 | WRITE:40010:BOOL:0:{{value}} |
测试参数:value,参数形式选选项:熄灭 = 0、点亮 = 1。
想做「同一指令控制不同位」的通用开关量指令,把 bit 也开放为参数:
WRITE:40010:BOOL:{{bit}}:{{value}},配bit、value两个参数。
4.4 写入值换算(EXPR 后缀)
- EXPR 中的变量固定为
value(模板里的写入值先转 float 参与运算,结果再按 dtype 编码)。 - 示例——PLC 端要整数、平台填物理量:
WRITE:40200:INT16:{{value}};EXPR:value*10,执行时填25.5,实际写入255。 - 位写 0/1 不要用 EXPR,除非确为数值型写入流程。
5. 设备连接参数在哪配
模板里只写业务(地址 / 类型 / 值)。串口、网络、从站号、默认字节序属于设备级参数,在连接器侧的仪器配置中维护,不在指令页面上填:
| 参数 | RTU(串口) | TCP(以太网) |
|---|---|---|
| 传输协议 protocol | rtu | tcp |
| 串口号 instr | 如 COM3、/dev/ttyUSB0 | — |
| 波特率 baud | 默认 9600 | — |
| 校验 / 数据位 / 停止位 | 默认 N / 8 / 1 | — |
| IP / 端口 host / port | — | 如 192.168.0.10 / 502 |
| 从站号 slave_id | 默认 1 | 默认 1 |
| 默认字节序 / 字序 | big / big | big / big |
需要「一条指令读任意地址」的通用指令时,地址也可以用占位符 + 测试参数:READ:{{address}}:FLOAT,测试参数编码必须是 address。
6. 易错点速查
| 错误做法 | 正确做法 |
|---|---|
模板写业务别名 READ:AI:40020 | 按第 1.3 节转换:READ:40020:FLOAT |
| 多段读取但指标只有 1 项(或数量对不上) | 段数(含 EXPR)= 指标数,顺序一一对应 |
| EXPR 用了未声明的变量名 | 变量必须是前面读段对应指标的指标编码 |
| 4xxxx 位读写把 bit 填成 16 | bit 只能 0 ~ 15 |
| 往 1xxxx / 3xxxx 配写指令 | 只读区;写操作用 0xxxx / 4xxxx |
| 线圈区 bit 理解成字内位 | 0xxxx/1xxxx 的 bit 是基址偏移;3xxxx/4xxxx 才是字内位 |
| FLOAT 读出离谱数值 | 字节序与 PLC 不一致,加 byteorder/wordorder 参数(200SMART 为 big/big) |
| 想用测试参数改读段类型 | 类型以模板中的 dtype 为准,改模板 |
| 通用指令忘了加参数 | 模板里有 {{xxx}},「测试参数」必须有编码 xxx 的参数 |
7. 全量填写速查
- 同一条点位既能读又能写时,表中拆成两行,分别在「编辑读取指令」「编辑设置指令」页面创建。
- 读取指令:测试指标必填;设置指令:不添加测试指标,写入值用测试参数开放。
- 指令模板请原样复制,不要改写成指令编码。
7.1 通用 Modbus 常用读取(照抄建指令)
| 界面 | 指令名称 | 指令编码 | 指令模板 | 测试指标(编码 / 名称 / 类型 / 单位) |
|---|---|---|---|---|
| 读取指令 | 读保持寄存器整数 | get_read_uint16 | READ:40001:UINT16 | value / 读数 / 数值 / / |
| 读取指令 | 读保持寄存器浮点 | get_read_float | READ:40020:FLOAT | value / 读数 / 数值 / 按物理量 |
| 读取指令 | 读输入寄存器 | get_read_input_reg | READ:30001:UINT16 | value / 读数 / 数值 / / |
| 读取指令 | 读线圈单点 | get_read_coil | READ:00001:BOOL:0 | state / 线圈状态 / 数值 / / |
| 读取指令 | 读离散输入 | get_read_di | READ:10001:BOOL:0 | state / 输入状态 / 数值 / / |
| 读取指令 | 读字内位 | get_read_bit | READ:40010:BOOL:0 | state / 位状态 / 数值 / / |
| 读取指令 | 读线圈区整字 | get_read_coil_word | READ:00001:UINT16 | value / 状态字 / 数值 / /(最多 16 位拼成字) |
7.2 200SMART 示例指令(对照 1.2 节点位表)
| 界面 | 指令名称 | 指令编码 | 指令模板 | 测试指标 / 参数 |
|---|---|---|---|---|
| 读取指令 | 读传感器1 | get_read_vc01 | READ:40020:FLOAT | vc01 / 传感器1 / 数值 |
| 读取指令 | 读紧急停止 | get_read_estop | READ:40001:BOOL:0 | estop / 紧急停止 / 数值(1=按下) |
| 读取指令 | 读红灯反馈 | get_read_red_lamp | READ:40010:BOOL:0 | red_lamp / 红灯 / 数值 |
| 读取指令 | 读DO整字 | get_read_do_word | READ:40010:UINT16 | do_word / DO状态字 / 数值(0 ~ 65535) |
| 读取指令 | 读传感器1/2及平均值 | get_read_vc_avg | READ:40020:FLOAT;40022:FLOAT;EXPR:(vc01+vc02)/2 | vc01、vc02、vc_avg 3 条指标 |
| 设置指令 | 设置模拟量控制1 | set_ao_01 | WRITE:40200:FLOAT:{{value}} | 参数 value(数值,0 ~ 1600) |
| 设置指令 | 红灯开关 | set_red_lamp | WRITE:40010:BOOL:0:{{value}} | 参数 value(选项:0=灭,1=亮) |
| 设置指令 | 开关量位控制 | set_do_bit | WRITE:40010:BOOL:{{bit}}:{{value}} | 参数 bit(0 ~ 15)、value(0/1) |
7.3 常用写入(照抄建指令)
| 界面 | 指令名称 | 指令编码 | 指令模板 | 测试参数 |
|---|---|---|---|---|
| 设置指令 | 写保持寄存器整数 | set_write_uint16 | WRITE:40200:UINT16:{{value}} | value |
| 设置指令 | 写保持寄存器浮点 | set_write_float | WRITE:40200:FLOAT:{{value}} | value |
| 设置指令 | 写线圈 | set_coil | WRITE:00001:BOOL:{{value}} | value(0/1) |
| 设置指令 | 写保持寄存器字内位 | set_hr_bit | WRITE:40010:BOOL:{{bit}}:{{value}} | bit(0 ~ 15)、value(0/1) |
| 设置指令 | 带缩放写入 | set_write_scaled | WRITE:40200:INT16:{{value}};EXPR:value*10 | value(填 25.5 实际写 255) |
| 设置指令 | 动态地址写 | set_addr_value | WRITE:{{address}}:FLOAT:{{value}} | address、value |
8. 填错了怎么办
指令执行失败时,优先看返回的提示信息:
| 现象 / 提示关键词 | 可能原因 | 处理建议 |
|---|---|---|
模板段数与 replys 数量不匹配 | 多段 / EXPR 段数与测试指标不一致 | 每段一条指标,顺序一一对应 |
位索引 x 超出范围(0~15) | bit 填错 | bit 只能 0 ~ 15 |
xx 寄存器为只读,不支持写操作 | 往 1xxxx / 3xxxx 写 | 换 0xxxx / 4xxxx 可写区 |
值格式错误,期望 xx | 写入值与 dtype 不符 | FLOAT 填数字;位写只填 0/1 |
Modbus 通信超时 | 接线、串口参数、从站号、IP/端口不对,设备未上电 | 查连接参数;用最简单的单点读验证通路;看连接器日志 |
Modbus 异常码 02(非法地址) | 地址超出该区范围或设备未映射 | 核对点表地址 |
| FLOAT 读出离谱大数 / 乱值 | 字节序与 PLC 不一致 | 加 byteorder/wordorder 参数(200SMART 为 big/big) |
| 指标全是 0 | 地址映射的点位本身为 0,或 bit 位选错 | 先读整字确认原始值,再核对 bit |
自查顺序(建议)
- 模板是不是「数字地址 + dtype」,没写
READ:AI:这类别名 - 读取指令:指标条数 = 段数(含 EXPR)
- 用最简单的一读(如已知点的
UINT16)验证通路 - 再上多段 / EXPR / 位操作
- 仍失败看连接器日志:Modbus 请求是否发出、返回什么异常码
9. 配置流程速览
准备点表(PLC 寄存器地址 / 数据类型 / 读写属性)
↓
按前缀确认地址区(0x/1x/3x/4x)与读写权限 → 换算成「数字地址 + dtype」
↓
编辑读取指令:READ:<addr>:<dtype>[:<bit>] + 测试指标(段数对齐)
或编辑设置指令:WRITE:<addr>:<dtype>[:<bit>]:<值>(+ 测试参数)
↓
一次读多个量 / 需要换算?
→ `;` 分段 + EXPR(变量 = 前面指标编码;写指令变量固定 value)
↓
数值不对 → 查字节序(byteorder/wordorder 参数,200SMART 为 big/big)
失败 → 按第 8 章排查(模板 → 段数 → bit → 只读区 → 通路)