ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

PLC数据类型与进制转换详解:从位、字到浮点数与Modbus通信调试

PLC数据类型与进制转换详解:从位、字到浮点数与Modbus通信调试 1. 为什么PLC数据类型和进制转换值得单独讲一讲很多PLC初学者在入门时会有一个错觉数据类型是高级编程语言比如Java、Python才需要纠结的事情PLC里面不就是X、Y、M、D这些软元件地址吗会接通、会断开、能传输数据就完事了。但真正进入项目开发后你会很快发现事情没那么简单。举个例子你在触摸屏上设定了一个温度值 100.5通过 Modbus 通信传给 PLCPLC 收到后却显示乱码或者数值不对。又或者你用三菱 PLC 和变频器通信从 D0 寄存器读出来的数据是 6000但变频器说明书上明明写着频率应该在 0 到 50.00 Hz 之间6000 这个数值到底代表什么这些问题的根源往往不是通信协议配置错了而是数据类型理解不到位。变频器的 6000 可能是十六进制值可能是 BCD 码可能是放大 100 倍后的整数还可能是 32 位浮点数的某一半。如果不理解 PLC 里数据的存储方式和进制转换规则排查这样的问题会非常痛苦。我见过不少刚接触 PLC 的工程师梯形图已经画得很熟练位逻辑指令用得飞起但一遇到数据运算、通信处理、模拟量标定就卡壳。原因很简单PLC 的程序执行不只是通断问题更是数据怎么存、怎么算、怎么解释的问题。这篇教程从 PLC 数据类型的本质讲起把 8 位、16 位、32 位这些概念和实际软元件对应起来再用大量实操例子把二进制、八进制、十进制、十六进制的转换方法讲透。最后我会用几个真实项目中经常遇到的案例比如 Modbus 通信、模拟量采集、触摸屏数据显示来说明进制转换和数据类型为什么会直接影响程序正确性。看完这篇文章你会掌握三件事第一PLC 里每个数据类型到底占多少位、能表示多大范围第二不同进制之间怎么快速转换以及为什么 PLC 程序里到处是十六进制第三遇到通信数据不对、显示数据错乱这类问题时从数据类型角度排查的完整思路。2. PLC数据类型的本质存储区的视图2.1 位、字节、字、双字的层次关系PLC 内部处理的本质是二进制数也就是0和1。所有复杂的控制逻辑、数值计算、通信协议最终都落到二进制位的处理上。但在工程开发中我们不会整天用0000 0001这种形式写程序而是用数据类型来规定一段二进制数据该怎么解释。这就引出了 PLC 中最基本的几个层次概念数据类型位数说明常见软元件位 BIT1 位只有 0 或 1对应触点的通断三菱 X、Y、M西门子 I、Q、M字节 BYTE8 位一个字节范围 0 到 255无符号文件寄存器的一部分字 WORD16 位两个字节PLC 数据运算的基本单位三菱 D、R西门子 MW、DBW双字 DWORD32 位四个字节可以表示更大的整数或浮点数三菱 D 寄存器连续两个西门子 MD、DBD理解了这张表你会发现一个关键点数据类型不是物理上存在的东西而是对存储区的一种视图。同一个寄存器你可以把它当 16 位整数用也可以把两个寄存器拼在一起当 32 位浮点数用关键看你用什么样的指令去读写它。很多人学到这里容易卡住因为和高级语言不同PLC 里的变量没有声明类型这一步类型是使用时才确定的。这也是 PLC 和普通计算机编程最大的思维方式差异之一。2.2 为什么 PLC 中数据类型的认识会影响编程效率举一个实际场景。你用三菱 FX 系列 PLC 读取模拟量模块通道 0 的数据程序里写MOV D8260 D100D8260 是模拟量模块的当前值缓冲寄存器D100 是你程序里的存储地址。然后你在触摸屏上显示 D100却发现数值在 0 到 4000 之间变化但现场传感器对应的是 0 到 100 摄氏度屏幕显示却是0到4000完全不是温度值。这就是典型的数据类型理解问题。模拟量模块的原始值是 16 位无符号整数而温度值需要带小数。你要么在触摸屏上做量程换算要么在 PLC 里用浮点运算把原始值转成实际工程值MOV D8260 D100 ; 读取原始值 0~4000 FLT D100 D102 ; 转为浮点数 MUL D102 K25 D104 ; 对应 0~100度乘以 0.025先乘 25如果不懂整数、浮点数的区别不理解原始值不等于工程量这类问题是很难定位的。这也是为什么说数据类型的掌握程度直接决定了你写出的程序是能跑还是跑得正确。3. PLC中常用的数据类型详解3.1 位、字节、字、双字的详细对比在 PLC 编程中位Bit是最基本的元素。它对应一个继电器触点或线圈的状态只有 0 和 1 两种取值。在梯形图中常开触点、常闭触点本质上都是在读取某个位的状态。字节Byte由 8 个位组成比如 8 个输入点 X0 到 X7 可以组成一个字节。在西门子 PLC 中I0.0 到 I0.7 组成了输入字节 IB0。字Word由 16 个位组成是两个字节。在数据运算中字是最常见的单位。三菱 D 寄存器、西门子 MW 区域的长度都是 16 位。双字Double Word由 32 个位组成可以表示更大范围的整数或者用来存储单精度浮点数。在三菱 PLC 中D0 和 D1 组合起来就是一个 32 位的数据区使用 DFRO、DINT 这类指令时会自动按照双字处理。3.2 无符号数与有符号数的区别这是初学者最容易混淆的地方。16 位无符号整数的范围是 0 到 6553516 位有符号整数的范围是 -32768 到 32767。同一个十六进制数 8000如果当作无符号数解释是 32768如果当作有符号数解释是 -32768。数值本身没有变变的只是解释方式。实际项目中最典型的例子是模拟量模块的输出。很多模拟量模块在 4 到 20mA 或 0 到 10V 输入时输出的就是一个有符号整数范围可能是 -32768 到 32767。如果你用无符号数的方式去读取可能得到一个看似正确但完全不对的数值。还有一个常见场景三菱 PLC 的比较指令 CMP、区间比较指令 ZCP对 16 位数据默认按有符号处理。如果你拿一个大于 32767 的无符号数参与比较比如 40000会被当成负数结果完全出乎意料。正确做法是把 40000 拆成两个 16 位寄存器做 32 位比较或者改用浮点数。3.3 整数与浮点数整数类型我们上面已经说了在 PLC 中主要分为 16 位整数和 32 位整数。32 位整数也叫双整数范围约为 -21 亿到 21 亿。浮点数则用来表示带小数的数值。PLC 中的浮点数通常指 32 位单精度浮点数也就是符合 IEEE 754 标准的 FLOAT 类型。它能表示的数值范围非常大但精度只有约 7 位有效数字。实际项目中模拟量工程量换算、PID 运算、运动控制中的位置和速度计算几乎都会用到浮点数。这里要特别注意PLC 中的浮点数和整数不能直接进行四则运算。三菱 PLC 里加法指令 ADD 是整数运算DEADD 才是浮点数加法乘法指令 MUL 是整数乘法DEMUL 才是浮点数乘法。如果你用 ADD 指令把两个浮点数相加结果会被当成整数处理小数部分被截断计算结果完全错误。3.4 BCD码PLC历史遗留的重要类型BCD 码Binary-Coded Decimal是一种用二进制编码表示十进制数的方式。每个十进制位用 4 位二进制数表示比如十进制数 25BCD 码是 0010 0101。在老的 PLC 程序中BCD 码非常常见因为早期的数码管显示、拨码开关、编码器输入等设备直接使用 BCD 码。三菱 PLC 中专门有 BCD 指令和 BIN 指令用于 BCD 码和二进制数之间的转换。一个典型应用是读取旋转编码器的数值。有些编码器输出的不是普通二进制而是 BCD 码格式如果你不对它进行转换读出来的数据会显得很怪——不是连续变化的数值而是跳变的数字。另外触摸屏上有时会显示乱码比如显示199但实际上应该是99很可能是数据类型选错了把 BCD 值当成十进制用了。3.5 不同品牌PLC数据类型对照数据类型西门子 S7-1200/1500三菱 FX/Q汇川 H系列位BOOLI/Q/MX/Y/MX/Y/M字节BYTEIB/QB/MBD 低 8 位或特定字节区IB/QB/MB字WORD/INTMW/DBWD 寄存器D 寄存器双字DWORD/DINTMD/DBDD 寄存器连续两个D 寄存器连续两个浮点数REALMD/DBDD 寄存器连续两个浮点D 寄存器连续两个从表中可以看出来不同品牌虽然指令不同、地址格式不同但底层的位数和范围是相通的。学透一种 PLC 的数据类型换其他品牌时上手会非常快这就是我经常建议学员不要只背指令、不学原理的原因。4. 进制转换PLC工程师的基本功4.1 为什么PLC到处都是十六进制如果你打开一个 PLC 程序的监控表或者看通信报文会发现大量十六进制数。原因很简单十六进制和二进制之间的转换非常直觉化一位十六进制正好等于四位二进制。例如二进制数 1011 1100 拆成高四位 1011 和低四位 1100分别对应十六进制的 B 和 C所以整个字节就是 0xBC。这种映射关系让工程师在调试通信数据时非常方便——看到 0xBC脑子里就能浮现出 1011 1100 的二进制展开。十进制则不是这样。十进制 188 对应二进制是 1011 1100无法按位直接心算。所以在 PLC 编程、通信报文分析、寄存器地址计算时十六进制是比十进制更自然的中间语言。4.2 二进制、八进制、十进制、十六进制转换方法4.2.1 二进制转十进制从右往左每一位乘以 2 的 n 次方然后求和。n 从 0 开始递增。1011 0100 1×2^7 0×2^6 1×2^5 1×2^4 0×2^3 1×2^2 0×2^1 0×2^0 128 0 32 16 0 4 0 0 1804.2.2 十进制转二进制用短除法不断除以 2取余数最后倒序排列。比如十进制 180180 ÷ 2 90 余 0 90 ÷ 2 45 余 0 45 ÷ 2 22 余 1 22 ÷ 2 11 余 0 11 ÷ 2 5 余 1 5 ÷ 2 2 余 1 2 ÷ 2 1 余 0 1 ÷ 2 0 余 1倒序得到 1011 0100。4.2.3 十六进制转二进制一位十六进制转四位二进制0x8A 1000 1010 0x3F 0011 1111 0xFF 1111 11114.2.4 二进制转十六进制从右往左每四位一组不足四位前补 010110100 → 1011 0100 → B 4 → 0xB44.2.5 八进制PLC 中八进制主要用于输入输出地址编号比如三菱 FX 系列的输入点 X0 到 X7X10 到 X17计数到 7 后直接跳到 10没有 X8、X9。这是硬件寻址方式和普通数学中的八进制计数一致。实际编程中需要做数据转换时八进制用得较少但遇到有人把输入点编号写成 X8 时你要知道这不是语法错误而是地址根本不存在。4.3 8421法则PLC工程师最常用的心算技巧8421 法则本质上就是 2^3、2^2、2^1、2^0 的权重。一个四位二进制数从高到低每位对应 8、4、2、1。比如看到一个十六进制数 0x7立即能反应出二进制是 0111也就是权重 4217。看到 0xA二进制是 1010权重 802010。熟练使用 8421 法则后任何一位十六进制数到二进制的转换都可以在零点几秒内完成这在调试通信报文时特别有用。比如收到一帧 Modbus 报文数据段是 0x03 0xE8你可以快速在脑中展开为 0000 0011 1110 1000这是 16 位二进制数十进制是 1000也就是 Modbus 寄存器中常见的数据值。4.4 负数在PLC中的表示补码PLC 中处理负数时用的是计算机通用的补码表示法。一个 16 位有符号整数的补码规则是正数的补码就是原码本身负数的补码是原码按位取反再加 1。举个具体例子-5 在 16 位 PLC 寄存器中怎么存第一步5 的二进制是 0000 0000 0000 0101。 第二步按位取反得到 1111 1111 1111 1010。 第三步加 1 得到 1111 1111 1111 1011这就是 -5 的补码表示十六进制是 0xFFFB。如果你在监控表里看到一个寄存器的值是 0xFFFB指令把它当有符号数时显示的是 -5把它当无符号数时显示的是 65531。这再次说明同样的数据不同类型解释下结果完全不同。在通信中从变频器读到的负数值比如 -10.00 Hz 的转速指令通常在报文里就是补码形式。如果你没有正确处理符号位可能读到一个很大的正数然后直接当成 60000 多转处理——这在运动控制项目里是非常危险的。4.5 浮点数的十六进制表示32 位浮点数在 PLC 中按 IEEE 754 标准存储。比如十进制的 1.0在内存中是 0x3F800000。当你通过 Modbus 读取一个 32 位浮点数时会拆成两个 16 位寄存器。问题来了哪个寄存器是高 16 位哪个是低 16 位这就是通信中常说的字节序问题。在很多国产仪表和第三方设备中寄存器顺序可能是低位在前高位在后也可能相反。如果你把两个寄存器的顺序搞反读出来的浮点数会是一个天文数字或者接近 0 的极小值。排查这类问题时可以先在触摸屏或调试软件里把两个寄存器分别以十六进制显示然后手动拼一下。0x3F80 和 0x0000拼成 0x3F800000 就是 1.0如果拼成 0x00003F80结果就完全是另一个数。5. 环境准备与PLC编程软件说明这篇教程的实操部分不限制具体硬件品牌。只要你的电脑能正常安装并使用任意一款主流 PLC 编程软件就能完成所有验证。常见组合包括三菱 GX Works2 或 GX Developer配合 FX 系列 PLC 或者 GX Simulator 仿真器。西门子 TIA Portal配合 S7-1200/1500 或 PLCSIM 仿真。汇川 InoProShop配合 H 系列 PLC。我这里以最常见的三菱 FX 系列 PLC 编程习惯为例因为它的指令相对简单直观适合初学者把注意力集中在数据类型 进制转换这两个核心主题上。其他品牌原理完全一样指令名称换成自己用的即可。需要提醒的是如果你用的是仿真器模拟量读取、通信指令等部分功能可能有限制。本文涉及的进制转换、数据存储、浮点运算、通信数据处理都可以通过仿真器验证大部分逻辑。但涉及具体硬件模块地址时建议在真实设备上再确认一遍。6. 核心实操进制转换指令与程序实现6.1 三菱PLC的进制转换指令三菱 PLC 中与进制转换直接相关的指令有BINBCD 码转二进制数。BCD二进制数转 BCD 码。16 进制数在程序中可以直接用 H 前缀表示比如 H0A、HFFFF。十进制数直接用 K 前缀表示比如 K100、K-32768。下面写一个简单示例假设 D0 中存放的是一个 BCD 码数值 0x0123代表十进制 123。我们需要把它转换成普通二进制数存放在 D10 中。LD M0 BCD D10 D0 ; 二进制转BCD如果D10中本来就有二进制数 BIN D0 D20 ; BCD转二进制结果存D20注意指令的方向和实际逻辑。三菱的 BCD 指令是将 BIN 数据转换成 BCD 码BIN 指令是将 BCD 码转换成 BIN 数据。很多初学者会记反导致转换后数据完全不对。6.2 十进制与十六进制在PLC中的字面量表示在三菱 PLC 的程序中MOV K100 D0 ; 把十进制100存入D0 MOV H64 D0 ; 把十六进制0x64存入D0和K100相等 MOV HFFFF D2 ; 把65535无符号或-1有符号存入D2这里有一个实用技巧如果你需要用程序给某个寄存器预置一个全1值比如初始化数据区直接写 HFFFF 比写 K65535 更直观因为 HFFFF 一眼就能看出每一位都是 1。同理清零一个 16 位寄存器可以写 K0也可以写 H0。6.3 模拟量工程值换算整数与浮点配合使用模拟量输入模块读出的原始值是整数但工程上要显示温度、压力、流量时通常需要带小数的工程量。这就需要先转浮点再做缩放运算。下面以三菱 FX 5U 为例读取模拟量输入通道值并转换为 0 到 100℃ 的温度值// 梯形图无法直接展示这里用 ST 结构化文本描述逻辑 // 假设模拟量模块读取的原始值在 D100范围 0~4000 对应 0~100℃ D100 : U16_TO_REAL(ANALOG_READ_CH0); D102 : D100 / 4000.0 * 100.0;如果设备不支持直接模拟量读取函数可以先用 MOV 指令读取缓冲区地址再执行浮点运算MOV D8260 D100 ; 读取原始值到D1000~4000 FLT D100 D102 ; 转浮点 DEMUL D102 K100 D106 ; 乘100先扩大到整数方便显示 DEDIV D106 K4000 D110 ; 除以4000D110中就是浮点温度值浮点运算会产生小数触摸屏显示时保留一位或两位小数即可。6.4 Modbus通信中的进制与数据类型处理Modbus 是工业现场最常用的通信协议之一。它传输的基本单位是 16 位寄存器数据在报文中以十六进制形式出现。假设我们从一台 Modbus 仪表读取当前温度仪表说明书上写着温度数据占 1 个寄存器数据类型为无符号整数实际温度 寄存器值 / 10。那程序处理逻辑就是// 从Modbus从站地址读取寄存器值存入D200 MOV D200 D300 ; 原始值比如实际读到 253代表 25.3℃ // 整数除法示例注意整数除法会丢失小数 MOV D300 K10 D302 ; 结果为25小数被截断 // 推荐做法转为浮点再运算 FLT D300 D310 ; 253.0 DEDIV D310 K10 D312 ; 25.3可送触摸屏显示如果仪表数据占 2 个寄存器32 位整数或浮点数还要考虑两个寄存器的顺序。比如先读到 D200后读到 D201那么 32 位数据有两种拼法高 16 位在 D200低 16 位在 D201数据 D200 × 65536 D201。高 16 位在 D201低 16 位在 D200数据 D201 × 65536 D200。不同厂商默认不同有些还允许在参数里配置。遇到这种问题先把两个寄存器的十六进制值打出来结合已知的物理量值手动拼一次就知道顺序了。6.5 触摸屏数据显示乱码的数据类型排查触摸屏上显示 PLC 寄存器数据时需要设置显示格式包括数据类型有符号/无符号、16位/32位/浮点、进制十进制/十六进制等。常见坑PLC 中 D100 存的是十六进制数 0x1234触摸屏显示格式设为十进制显示 4660设为十六进制显示 1234。数据本身是负数的补码触摸屏按无符号显示则显示 65535 左右的数。数据是 BCD 码触摸屏按十进制显示数字看起来是跳变的。排查步骤在 PLC 编程软件中打开监控表确认 D100 的实际值。在触摸屏工程里查看元件属性确认显示格式。把两者对齐确保数据类型一致。7. 进制转换速查表与常用对照为了方便日常开发这里整理一张常用进制对照表十进制二进制十六进制000000100011200102300113401004501015601106701117810008910019101010A111011B121100C131101D141110E151111F这张表建议收藏。实际调试时频繁用到的是十六进制和二进制之间的转换要能根据十六进制数快速写出二进制展开。几个高频值十六进制十进制无符号十进制有符号0x0000000x7FFF32767327670x800032768-327680xFFFF65535-10x3F8016256浮点对应1.0的前半部分8. 常见问题与排查思路问题现象可能原因排查方式解决方案触摸屏显示数据乱码或跳变数据类型选错BCD码当十进制或有符号无符号不匹配在PLC监控表确认原始值在触摸屏属性中核对格式将触摸屏元件的数据类型改为与PLC实际存储一致通信读到的数据和仪表显示不一致寄存器顺序错误或数据实际为32位而按16位读取打印报文查看两个寄存器十六进制值手动拼接调整高16位、低16位的读取顺序或改用双字读取比较指令结果不对16位无符号数大于32767被当成有符号负数检查参与比较的数的取值范围改用32位比较指令或用浮点数比较模拟量显示数值不对未做量程换算或整数除法丢失小数检查程序是否使用浮点运算先转浮点再计算最后送显示负数在通信中变成很大的正数有符号数被按无符号解释检查通信协议中数值是否有符号报文是否为补码在PLC程序里做有符号转换或调整触摸屏显示格式浮点数通过Modbus读取后变成天文数字两个寄存器的字节顺序反了两个寄存器按不同顺序分别计算取合理值调整寄存器高低顺序三菱PLC中X8、X9不存在输入地址采用八进制编号查看PLC硬件手册的地址定义使用X10、X11等有效地址9. 最佳实践与工程建议9.1 建立自己的数据类型速查表不同品牌的 PLC 数据类型名称各异但底层原理相同。建议你在一张纸上或者笔记软件中记录自己常用 PLC 的位、字节、字、双字对应的软元件。整数指令、浮点指令的助记符。进制转换指令的用法。模拟量通道缓冲寄存器的地址。这样换项目、换品牌时可以快速对照。9.2 通信调试时先看十六进制遇到通信数据不对的问题不要急着在程序里加系数或者在触摸屏上做换算。先在监控表里把寄存器的值切换成十六进制显示手动算出这个数据可能代表什么。比如0x0064 100如果仪表量程是 0 到 100很可能就是 100。0xFF38 如果是负数补码算出 -200再结合仪表量程判断是否合理。把原始数据看清楚再写处理逻辑这是排查通信问题最重要的原则。9.3 程序中使用有符号数时明确注释在程序中给寄存器赋值或做运算时养成为关键数据写注释的习惯。比如MOV HFFFF D100 ; 传给变频器FFFE~FFFF为启停控制字如果程序里没有注释三个月后你自己回来看也未必记得 D100 里存的到底是 65535 还是 -1。有了注释维护成本会大幅下降。9.4 浮点数运算尽量集中处理浮点运算比整数运算慢而且占用寄存器多。实际项目中建议把需要浮点运算的计算集中在一个程序段或专用子程序中不要在每一段逻辑里都穿插浮点指令。这样既方便调试也方便后期维护。9.5 使用仿真器验证进制转换逻辑在把程序下载到真实 PLC 之前先用仿真器或者离线监控模式输入几个典型值验证进制转换、浮点换算的逻辑是否正确。尤其是涉及负数、边界值比如 32767、-32768、65535时提前验证能避免现场返工。10. 总结与下一步实践方向这篇文章把 PLC 数据类型和进制转换的核心内容梳理了一遍重点解决的是以下问题数据类型不是高级编程语言专属PLC 中的位、字节、字、双字、整数、浮点数、BCD 码每一种都有明确的位宽和适用范围。同一个寄存器的数据用不同数据类型解释结果可能天差地别这也是大量通信异常、显示异常问题的根源。二进制、十进制、十六进制之间转换要熟练掌握尤其是 8421 法则和补码表示法。实际项目中模拟量换算、Modbus 通信、触摸屏显示这些高频场景的实现都依赖对数据类型和进制转换的正确理解。如果你现在刚学完梯形图基础找一台仿真器按照下面的清单练一遍用 MOV 指令向 D0 写入 K100、H64、K-100、HFF9C观察监控表中的十六进制和十进制显示。用 FLT 指令把 D0 的整数转为浮点观察结果。模拟一个 Modbus 32 位数据把两个寄存器按不同的顺序拼接观察计算结果的差异。用 BCD 和 BIN 指令做一次转换确认自己理解指令方向是否正确。把这四步做完你对 PLC 数据的理解会上一个台阶。后续再学习模拟量处理、PID 控制、运动控制、通信协议时会发现很多之前觉得很玄的概念本质上都是数据类型和进制转换的应用。
返回列表