ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PLC数据类型与进制转换:从底层存储到工程实战

PLC数据类型与进制转换:从底层存储到工程实战 1. PLC 数据类型是什么为什么第二十三讲必须搞明白这一讲我们要解决一个工程里非常基础、但天天踩坑的问题PLC 数据类型定义与进制转换。先直接给结论PLC 程序跑得稳不稳很多时候不是逻辑写错而是数据类型选错、进制换算错。比如用 INT 存了一个实际超过 32767 的数值数据直接溢出用浮点数做精确计数累加多了出现误差和别人设备通信时Modbus 寄存器读到的是十六进制要拼成十进制才知道实际温度触摸屏上显示的是 100PLC 里却是 0x64不懂进制转换排查一下午都找不到原因。这一讲的内容适合这几类读者刚入门 PLC 编程还在搞不懂位、字节、字、双字的区别做设备维护经常遇到触摸屏数值显示不对、通信数据对不上需要和第三方设备走 Modbus、TCP/IP 通信要手动解析寄存器数据自学西门子、三菱、汇川等品牌 PLC想一次性把数据类型和进制转换的关系理清楚。本文会围绕五个部分展开PLC 数据类型的底层存储逻辑、位/字节/字/双字/浮点数的区别、进制转换的工程实操方法、触摸屏与通信场景中的数据换算以及常见错误排查清单。无论你用的是西门子博途、三菱 GX Works还是汇川 InoProShop底层的存储原理是一致的。把这讲内容吃透后面学运动控制、伺服通信、PID 运算都会轻松很多。2. PLC 核心能力速览能力项说明适用范围西门子、三菱、汇川、欧姆龙、台达等主流 PLC 编程数据类型位 BOOL、字节 BYTE、整数 INT/DINT、浮点数 REAL/LREAL、字符串 STRING核心痛点数据类型溢出、数据长度不匹配、通信寄存器解析错误进制使用场景Modbus 通信、触摸屏地址映射、PID 参数计算、变频器控制字操作工具计算器程序员模式、博途监控表、GX Works 软元件批量监控常见错误INT 溢出、REAL 精度丢失、十六进制与十进制混淆、字节顺序错误这里要强调一点不同品牌 PLC 对数据类型的关键字命名有差异比如西门子用 DINT 表示双整数三菱用 D 寄存器配合 BIN/BCD 指令汇川与西门子风格接近。但数据在内存里的长度和取值范围是统一的。搞清楚底层位数换品牌只是换指令名字的问题。3. PLC 数据类型的底层存储逻辑PLC 本质上是一台工业专用计算机所有数据在 CPU 内部都以二进制存储。一个二进制的位只有 0 和 1 两个状态多个位组合起来就能表示更大的数。以最常用的 16 位整数为例它的存储范围是 -32768 到 32767。PLC 用最高位第 15 位表示符号0 为正、1 为负剩下 15 位表示数值。这里有一个容易踩坑的点很多人以为 INT 可以存到 65535实际这是无符号 WORD 的范围不是 INT。再往上就是 32 位数据。DINT双整数用 32 位存储范围约 -21 亿到 21 亿REAL浮点数也用 32 位存储但内部把 32 位拆成了符号位、指数位和尾数位所以它能表示很大或很小的数但精度有限。这也是为什么累计计数、钱款计算这类需求不建议用 REAL而要用 LREAL 或 DINT。下面用一个表格总结最常见的 PLC 数据类型数据类型位宽取值范围典型用途BOOL1 位TRUE / FALSE启停信号、报警状态、按钮输入BYTE8 位0 到 255ASCII 码、小范围状态值、通信字节WORD16 位0 到 65535Modbus 寄存器原始值、状态字INT16 位-32768 到 32767普通整数运算、模拟量标定DINT32 位-2147483648 到 2147483647大数计数、累计量、位置值REAL32 位约 ±3.4e38温度、压力、流量等模拟量运算LREAL64 位约 ±1.7e308高精度浮点运算STRING8 位/字符与长度有关设备名称、故障信息、配方名这张表是所有 PLC 程序设计的基石。任何一个变量都要先想清楚它最大可能到多少再决定用哪种类型。比如一个设备运行次数计数器用 INT 可能在半年后溢出但用 DINT 能跑几十年。4. PLC 进制转换基础二进制、十进制、十六进制PLC 编程里最常用的进制是二进制、十进制、十六进制偶尔会用到 BCD 码。二进制是 CPU 的唯一语言每一位只能是 0 或 1。十进制是人类习惯的表示方式。十六进制是二进制的缩写形式每 4 位二进制对应 1 位十六进制方便阅读和书写。对应关系如下二进制 0000 0001 0010 0011 0100 0101 0110 0111 十六 0 1 2 3 4 5 6 7 十进制 0 1 2 3 4 5 6 7 二进制 1000 1001 1010 1011 1100 1101 1110 1111 十六 8 9 A B C D E F 十进制 8 9 10 11 12 13 14 15在 PLC 程序里一个 16 位数据用十六进制表示就是 4 位比如 16#1F4用二进制表示就是 16 位比如 2#0000000111110100可读性差很多。因此编程软件默认会用十六进制显示通信数据和原始寄存器值。这里必须区分 BCD 码和十六进制。BCD 码是用 4 位二进制表示一位十进制数比如十进制 25 的 BCD 编码是 0010 0101而十六进制 0x25 的十进制值是 37。很多老设备、温控器、电子秤的输出就是 BCD 码如果程序里当成普通十六进制处理数值会直接偏掉。工程中进制转换最直接的方法是使用电脑计算器的程序员模式。Windows 自带的计算器切到程序员模式后可以在 HEX、DEC、OCT、BIN 之间切换输入一个值会自动显示其他进制结果。比如在 HEX 里输入 1F4切换到 DEC 就得到 500再切到 BIN 就是 0000000111110100。但不要过度依赖计算器PLC 程序里也会用到进制转换指令。比如西门子的 BCD_I 可以把 BCD 码转成整数I_BCD 可以把整数转成 BCD 码三菱的 BIN 和 BCD 指令功能类似汇川的博途风格指令也支持类似操作。5. PLC 数据类型详解与常见应用场景5.1 BOOL 位数据BOOL 是最基础的数据类型只占 1 位值只能是 TRUE 或 FALSE。在梯形图里常开触点、常闭触点、线圈都基于 BOOL 逻辑。输入端子映射到 I 区输出端子映射到 Q 区中间继电器映射到 M 区都是 BOOL 类型。使用 BOOL 时要注意物理输入和程序逻辑的常开常闭关系。比如急停按钮硬件上通常接常闭触点程序里再用常开指令读取这样断线时设备也能停下来这是安全回路设计的基本原则。5.2 BYTE、WORD、DWORD 无符号数据BYTE 是 8 位WORD 是 16 位DWORD 是 32 位它们都只能表示非负整数。为什么需要无符号类型因为有些数据天然没有负数比如设备状态字、报警位映射、通信协议里的寄存器原始值。用无符号类型可以避免符号扩展带来的麻烦。举个例子Modbus 读取回来的保持寄存器原始值就是一个 16 位 WORD。如果两个寄存器拼成一个 32 位浮点或 DWORD就要注意高低字节顺序。不同设备有 Big-Endian 和 Little-Endian 之分解析错了数值会变得非常离谱。5.3 INT、DINT 有符号整数INT 是 16 位有符号整数DINT 是 32 位有符号整数。这是程序里最常用的计算类型。一个典型问题是模拟量处理。当 4-20mA 或 0-10V 信号进入 PLC模拟量模块会把电流或电压转换成数字量。西门子 S7-1200 的默认范围是 0 到 27648三菱 FX 系列常见范围是 0 到 4000。如果直接把原始值当成工程量去显示肯定不对必须先做标定换算。比如 4-20mA 对应温度 0-100 度采集到的原始值是 13824按公式工程值 原始值 / 满量程 * (上限 - 下限) 下限先判断量程范围是 0 到 27648还是 0 到 4000再计算结果。这个换算过程里数据类型选错会直接导致负数或溢出。5.4 REAL、LREAL 浮点数REAL 是 32 位单精度浮点数LREAL 是 64 位双精度浮点数。温度、压力、流量、速度这些模拟量通常都用浮点数参与运算。REAL 的精度大约 7 位有效数字。看起来精度够用但做累积计算时误差会逐渐放大。比如把一个很小的值反复累加 100 万次REAL 可能出现明显偏差LREAL 会好很多。另一个坑是 EQUAL 比较。两个浮点数不要直接比较是否相等而是比较差值是否小于某个阈值ABS(value1 - value2) 0.001在博途里可以用 EQ 指令配合 ABS 函数在三菱里可以用 ZCP 区间比较或者子程序里做减法判断。5.5 STRING 字符串STRING 用于存放设备名称、报警信息、配方名、JSON 字符串。西门子 STRING 的默认长度是 254 个字符占用空间是长度加 2 个字节管理位。三菱和汇川的字符串处理风格不同有的用了指针结构通信解析时要特别注意长度前缀。通信场景里字符串经常要和 BYTE 数组互相转换。比如用 C# 和西门子 PLC 通过 S7 协议通信读取到的字符串需要按字节解析写入时也要把 C# 字符串转成 PLC 要求的格式否则会出现乱码。6. PLC 进制转换实操模拟量标定与通信数据解析6.1 实操场景一4-20mA 温度信号换算设备上有一个 4-20mA 输出的温度变送器量程 0-150 度PLC 模拟量模块采集到的原始值是 12000。这里要先用计算器把十进制 12000 转成十六进制确认数据没有符号溢出。直接算工程值工程值 12000 / 27648 * 150 - 0 工程值 ≈ 65.1 度如果把原始值当成 INT 读取且模块是 12 位分辨率原始值可能是 3000 而不是 12000因为不同分辨率下每毫安对应的数字量不同。使用前必须先查模块手册。建议在程序里写一个模拟量标定功能块输入原始值和量程上下限输出工程值后面所有通道都复用这个功能块。6.2 实操场景二Modbus 寄存器读取变频器频率通过 Modbus RTU 读取变频器运行频率寄存器地址 0x2100返回 16 位数据。变频器手册规定实际频率 寄存器值 / 100单位 Hz。假设读取到寄存器值十六进制 0x0BB8用计算器切换到 DEX 得到 3000再除以 100 得到 30.00 Hz。在博途里可以用 MOVE 指令把读取的 WORD 移到 INT 变量再除以 100 转成 REAL 显示。在三菱里使用 FROM 指令读取后进行同样的换算。这里最容易错的是溢出。如果寄存器值是 0xFFFF在无符号 WORD 里代表 65535但转成 INT 会变成 -1。因此通信解析时要严格区分有符号和 无符号。Modbus 的保持寄存器本质是无符号 16 位但很多设备会把负数编码成有符号整数解析方式取决于设备手册。6.3 实操场景三BCD 码解析电子秤数据很多电子秤、温控器、老式仪表输出的是 BCD 码。比如 BCD 码数据 0x1234表示十进制 1234不是十六进制的 4660。在西门子里用 BCD_I 指令把 BCD 码转成 INT得到 1234。在三菱里用 BCD 和 BIN 指令进行互转。汇川的指令集与西门子类似可以在指令帮助里搜索 BCD。如果通信读取的数据不符合 BCD 编码规则比如出现 A-F 的位转换结果可能直接报错或得到错误值。这时先检查设备手册确认数据格式是 BCD 还是普通十六进制。6.4 实操场景四DWORD 拆分与组合有些通信协议会把 32 位数据拆成两个 16 位寄存器发送。比如流量计输出累计流量高 16 位存一个寄存器低 16 位存另一个寄存器。读取后要把两个 WORD 组合成 DWORDDWORD_value HIGH_word * 65536 LOW_word如果 PLC 的字符串指令支持也可以使用移位和或运算DWORD_value (HIGH_word 16) | LOW_word注意不同设备可能先发高字节再发低字节也可能相反。正确解析前先用固定测试值验证字节序。比如设备手册说发送 0x12345678看先到的是 0x1234 还是 0x5678。7. 触摸屏与 PLC 数据类型映射触摸屏组态时地址类型和 PLC 数据类型必须一致。常见错误包括触摸屏上建了一个 INTPLC 里却是 REALPLC 里是 DINT触摸屏却按 DWORD 读取导致负数和正数显示错乱。以西门子 Smart Line 触摸屏和 S7-200 SMART PLC 为例地址映射规则如下触摸屏地址PLC 数据区数据类型说明I0.0输入位BOOL按钮/开关状态Q0.0输出位BOOL电机/阀门输出VW100V 区字INT/WORD16 位数据VD200V 区双字DINT/REAL32 位数据在博途的 WinCC 组态里连接 S7-1200 时直接选择 PLC 变量类型会自动带入。但如果是和第三方设备通信或者用触摸屏直接读 Modbus 从站就要手动指定字节顺序、数据类型和数据长度。很多触摸屏有数据格式设置可以选择 BCD、HEX、DEC 等显示方式选错会出现一个值对不上的问题。如果出现触摸屏显示值和 PLC 监控值不一致先做三件事确认触摸屏和 PLC 连接是否建立通信状态是否正常确认地址是否偏移西门子 V 区地址和 Modbus 地址存在差一或差二的情况确认数据类型和数据格式REAL 按 DINT 读取浮点数会变成奇怪的数字。8. PLC 数据类型与进制转换常见问题排查问题现象可能原因排查方式解决方案数值超过 32767 变成负数INT 溢出打开监控表查看变量类型改为 DINT 或使用无符号 WORD触摸屏显示值和 PLC 不一致地址偏移或数据类型不一致对比触摸屏地址和 PLC 变量地址核对地址映射表统一数据类型Modbus 读取结果异常大有符号/无符号解析错误用计算器查看十六进制确认设备手册按手册规定用 WORD 或 INT 解析浮点数累计误差越来越大REAL 精度不足查看累计次数和数值范围改用 LREAL 或 DINT 计数BCD 码解析结果偏了把 BCD 当十六进制处理确认设备输出格式为 BCD使用 BCD_I 或 BIN 指令转换通信数据高低字节反了字节序错误用固定值 0x1234 测试交换高字节低字节或修改组态模拟量原始值跳变数据类型长度不匹配检查模拟量模块分辨率确认范围 0-27648 / 0-4000 / 0-4095字符串显示乱码字符串格式不一致查看 PLC 字符串管理字节按 PLC 品牌格式转换字符串前面讲到的这些排查方法核心思路只有一个先回到二进制层面看数据再回到 PLC 变量类型看解释方式。数据是一样的解释方式不同结果就完全不同。9. PLC 数据类型与进制转换最佳实践这一节直接给出工程建议照着做能避开大多数数据类型相关的坑。第一建立统一的变量命名规范。命名里带类型前缀例如bStart // BOOL 启动信号 wStatusWord // WORD 状态字 iTemperature // INT 温度原始值 diCounter // DINT 累计次数 rPressure // REAL 压力工程值这样写梯形图时看到变量名就能判断它是什么类型不易搞混。第二模拟量通道统一使用功能块。把原始值到工程值的换算封装成一个功能块输入量程上下限和原始值输出工程值。比如西门子 FC / FB 里做一个 Analog_Scale 块三菱和汇川也可以做类似子程序。这样更换量程时不需要改主程序只改参数。第三通信地址和类型做成配置文件。如果项目里要对接多个从站设备建议把设备地址、寄存器起始地址、数据类型、字节序、缩放系数都放在一个数据结构里统一解析。排查问题时只需要比对配置表和设备手册不需要一行行看梯形图。第四批量任务和批量监控要有分层。比如一套设备有 8 个温度通道建议用数组或结构体数组管理数据。西门子里可以用 UDT 定义结构体三菱里可以用文件寄存器加变址寻址。这样批量下装、批量监控、批量修改参数都会方便很多。第五进制转换要保留计算过程和注释。比如写模拟量标定时注释里写清量程、原始范围、换算公式写 Modbus 解析时注释里写清映射地址和数据类型。半年后维护程序这些注释能救命。第六在线下载前先备份原程序下载时选择只下载修改内容避免因为强制赋值导致设备状态变化。涉及实际设备的修改一定要先切到手动模式或安全状态。10. 总结与下一步这一讲把 PLC 数据类型和进制转换放在一起讲是因为它们在工程中根本分不开。类型决定了数据在内存中的解释方式进制决定了外部通信和显示时的数值呈现形式。任何一方搞错程序逻辑再正确最终出来的数据也是错的。最值得先动手验证的事情是打开你正在用的 PLC 编程软件新建一个监控表用不同类型的变量存储同一个十六进制值观察显示结果。比如把 0xFFFF 分别放到 WORD 和 INT 里你会看到一个是 65535一个是 -1。这个实验做完了你对数据类型和进制转换的理解会上一个台阶。最容易踩的坑就是模拟量处理和通信协议解析时不查手册凭经验猜测数据范围和字节序。不同厂家分辨率不同、地址偏移不同、字节序不同动手前先花五分钟确认手册能省掉几个小时排查时间。后续可以继续扩展的方向PLC 数组与结构体、Modbus RTU/TCP 通信实战、模拟量 PID 控制、PLC 与上位机 C# 通信、触摸屏报警系统和配方管理。把这些串起来你就能独立完成一个完整设备的程序设计和调试。建议收藏备用。下一讲如果有机会可以继续剖析 PLC 工程师查故障的通用思路用案例串讲数据类型、通信报文和设备动作的联动关系。
返回列表