PLC数据类型与进制转换实战:从位、字节到BCD码一次讲透
2026/9/1 10:49:13 网站建设 项目流程

PLC编程里最常见的一种“逻辑没毛病、结果对不上”,就是数据类型和进制转换出了问题。程序不报错,但比较结果总是反的,模拟量换算老是差一位,通过通信读上来的数据像乱码,这类故障根子大多数都不在梯形图逻辑,而在数据类型没理清,或者进制理解有偏差。这一讲作为PLC实操系列的二十三讲,我把数据类型、存储结构和进制转换一次性讲透,然后按西门子、三菱和汇川的常用环境分别演示一套能直接照着做的验证流程。文章内容不挑具体硬件型号,重点看思路和判断标准,学完至少能自己排查掉七成以上的数据错乱问题。

1. 先搞懂PLC运算的最小单元:位、字节、字、双字

1.1 位是PLC里最小的状态表达

PLC的底层运算说到底只有两种状态:有电和没电,通和断,对应数字就是1和0。这个最小单位叫Bit,中文常叫“位”。一个位只能表达两个状态,所以用来描述按钮、继电器、电机接触器这类开关量非常合适。比如X0输入是一路按钮,Y0输出是一路接触器,梯形图里X0控制Y0,本质上就是某一个位从0变1,再让另一个位从0变1。

到这里大部分人都能理解。但实际调试时,位并不是单独存在的,它会被组合成字节、字、双字来读写。这也是很多人第一次看监控表时发懵的原因:明明只按了一个按钮,却看到某个地址里出现了一个很大的数字,其实那是多个位一起组成的数据。

1.2 字节、字、双字的容量关系

数据量从小到大排列如下:

  • 位(Bit):1个二进制位,值为0或1。
  • 字节(Byte):8个位,能表达256种状态,无符号范围是0到255。
  • 字(Word):16个位,由2个字节组成,无符号范围是0到65535。
  • 双字(DWord):32个位,由4个字节组成,无符号范围是0到4294967295。

这里要记住一个核心关系:1字等于2字节等于16位,1双字等于4字节等于32位。很多程序里地址编号是连续的,比如MW10占了MB10和MB11两个字节,如果不知道这个结构,你往MW10里写数据,监控MB10时只看到一个不完整的值,就很难判断数据到底对不对。

注意:在西门子PLC里,MB、MW、MD这类地址经常交叉占用。MW10和MB10不能同时用来存两组无关数据,否则后写入的数据会覆盖掉前面的结果。

1.3 为什么数据类型必须显式声明

PLC里的每个变量不能只叫“数值1”,它必须有一个明确的数据类型。原因是同一个32位二进制串,按无符号整数看可能是4294967295,按有符号整数看是-1,按浮点数看又是另一个完全不同的值。CPU本身不理解“数字多少”,它只负责按你指定的类型去解释这一段二进制串。

所以,编程软件里所有变量都有类型下拉框,比如Bool、Byte、Int、Real。把这个下拉框理解成“解释规则”就好:数据存储形式一样,解释规则不同,结果就不同。做项目时,从一开始就为每个变量设定好类型,比后面到处猜要省时间得多。

2. PLC里的常用数据类型:从布尔量到实数

2.1 无符号与有符号:0到65535为什么有时会变成负数

无符号整数就是把全部位都用来表达数值,16位的范围是0到65535;有符号整数用最高位做符号位,范围是-32768到32767。很多刚入门的人把0到65535的数据直接存进INT变量里,结果发现大于32767后显示成了负数,这不是PLC坏了,而是数据溢出后发生了补码解释。

举个例子,把十进制的40000二进制转为1001110001000000,刚好16位。如果这个地址被声明为无符号WORD,监控显示40000;如果同一个地址被声明为有符号INT,显示就成了-25536。输入没变,存储的位模式也没变,只是解释方式变了。做项目时,先问自己:这个量会不会为负,取值范围到底是多少,再决定用WORD还是INT。

2.2 INT、DINT、REAL:多数指令出错的重灾区

实际项目里最常用的是INT、DINT、REAL这三种。

  • INT:16位有符号整数,适合温度、速度、计数器等整数值。
  • DINT:32位有符号整数,适合大范围计数、累计量、编码器位置。
  • REAL:32位浮点数,适合模拟量换算、PID参数、带小数点的计算。

容易出错的点在于指令之间的类型不匹配。西门子博途环境下,MOVE指令可以直接把INT给REAL吗?不一定,有些情况下软件会报类型错误,有些情况会强制你加转换指令。三菱和汇川环境下,不同类型的数据也不能直接放进同一个运算指令里,否则指令不执行或者结果异常。

我最常给的建议是:项目里建一个统一的“数据类型约定”表,模拟量通道用INT,累计量用DINT,浮点运算用REAL,通信数据尽量用WORD或BYTE,然后统一规律,不要今天这个变量用INT,明天为了省事改成DINT,后天又改成REAL。类型一乱,排查成本立刻翻倍。

2.3 各品牌PLC数据类型命名差异

同一套数据概念,在不同品牌PLC里命名不一样。

  • 西门子:Bool、Byte、Word、DWord、Int、DInt、Real。
  • 三菱:Bit、Word、DWord在软元件里直接体现,但编程变量常见的整数类型有16位、32位之分。
  • 汇川:沿用了IEC标准较多,类型命名和西门子接近。

千万不要因为名称不同就怀疑自己学错了。核心还是记住每个类型占多少位,有没有符号,能不能表达小数。只要把这三件事弄清楚,换到任何一个品牌都只需要重新记一下指令名。

3. 进制转换的核心规则:手算、心算和程序算法

3.1 二进制、十进制、十六进制的基本关系

进制转换在PLC里不是数学考试,而是日常调试工具。PLC内部只认二进制,但人看二进制太累,所以编程软件用十进制显示,用十六进制检查寄存器内容,通信报文里也常见十六进制。四者关系如下表:

进制基数数字组成PLC里常见场景
二进制20、1位状态、指令表底层表达
八进制80到7部分PLC的输入输出地址编号
十进制100到9人机交互、触摸屏、一般变量显示
十六进制160到9、A到F寄存器值、通信报文、查故障代码

二进制转十六进制,最简单的方法是从右往左每4位一组。比如二进制10101100,从右往左分成1010和1100两组,1010对应十六进制A,1100对应C,结果就是0xAC。这个方法比逐位乘权重快,而且不容易错。

二进制转十进制,可以从左往右按2的幂累加。10101100,从高位到低位分别是1×128、0×64、1×32、0×16、1×8、1×4、0×2、0×1,加起来128+32+8+4=172。而0xAC的十六进制转十进制是10×16+12=172,三个结果一致。

3.2 BCD码和普通十六进制不要混为一谈

BCD码是PLC里很经典的坑。BCD码不是简单地把十进制数转成十六进制,而是把十进制每一位单独转成4位二进制。比如十进制25,普通十六进制是0x19,但BCD码需要把2转成0010,把5转成0101,结果是00100101,也就是0x25。

这导致在监控表或触摸屏上看到的值和实际数值经常差一截。很多编码器、温控仪表、称重仪表、老式文本屏会使用BCD码,如果你按十六进制去读,会得到一个看起来正常但实际不对的数据。

三菱PLC里有BCD和BIN指令,作用就是完成“普通二进制和BCD编码”之间的转换。西门子环境里,处理仪表通信时也经常要手动拼BCD字节。处理这类问题时,先确认通信协议里的描述写的是HEX还是BCD,再决定要不要转。

3.3 用PLC程序做进制转换的基本思路

PLC里做进制转换可以不用手算,很多指令能直接完成:

  1. 复制指令MOV:把数据从源地址搬到目标地址,不改变位模式。
  2. 转换指令CONV:把同一位宽的数据从一种类型解释转换为另一种类型,比如INT转REAL。
  3. 数值处理指令:比如三菱的BCD、BIN,西门子里通过转换函数或SCL计算。

如果现场没有现成指令,也可以使用四则运算实现“除基取余”,例如连续除以16取余得到十六进制每一位。但常规项目不建议自己写复杂换算逻辑,驱动和仪表通常直接提供十六进制或十进制寄存器,能省则省。

4. 实操一:西门子PLC环境下的数据类型与转换

4.1 先做最小实验:用MOVE指令验证存储结构

建议实际动手时不要直接上完整程序,而是先建一个最小实验。

第一步新建一个项目,PLC选S7-1200、S7-1500、200 SMART都可以。第二步在DB块里建立几个变量:

变量名数据类型初始值
Data_WordWord0
Data_IntInt0
Data_RealReal0.0
Data_ByteByte0

第三步写一段梯形图:用一个常ON触点,把十六进制16#1234通过MOVE指令传给Data_Word。然后在线监控,观察Data_Word的值。你会发现Data_Word显示4660,因为16#1234转换成十进制就是4660。

再把同时建的Data_Int也赋值为16#8000,观察显示值。0x8000按WORD看是32768,但按INT看是-32768。这就是同一个二进制串在不同类型下的差异。最小实验做一次,比背十遍概念都管用。

4.2 CONV指令的用法和常见误区

西门子博途里的转换指令叫CONV,可以把一种类型转换成另一种类型。常见用法:

  • INT转REAL:用于模拟量换算、PID运算前。
  • REAL转DINT:用于浮点结果转成整数显示。
  • BYTE转INT:用于通信数据包的单字节组合。

需要注意,CONV转换不是简单的重新解释,有时会改变数值的表示方式,有时会因为目标类型范围不够而溢出。实际使用中,先把源数据在线监控里看好当前值,再考虑要不要转换。REAL转INT时,如果是负数或带小数,还要想清楚是四舍五入还是截断。

举例:模拟量模块输入0到27648,对应0到10V,要换算成0到100的温度值。常见写法是先把AIW或IW拿到手的INT值转成REAL,再除以27648,乘以100,最后转成DINT或INT给触摸屏用。如果不转REAL,直接用INT做除法,整数除法会丢掉小数部分,结果会变成0或者跳变明显。

4.3 模拟量换算里的数据类型配合

模拟量处理是最容易暴露数据类型问题的地方。西门子模拟量模块通常返回16位整数,默认范围0到27648。如果直接用这个值和设定温度比较,数值单位对不上,所以中间必须有一层换算。

推荐流程:

  1. 读取模拟量原始值,类型是INT。
  2. 用CONV指令把INT转成REAL。
  3. 做线性换算,例如:实际值 = 原始值 / 27648.0 × 量程上限。
  4. 把结果转回DINT或保留REAL,用于触摸屏显示和报警比较。

这里还要警惕模块断电、断线时返回值变成32767或-32767的情况。这些极限值不是正常量程数据,程序里要加范围判断。否则断了一根线,触摸屏显示的温度冲到最大,报警也会跟着乱报,现场第一反应就会怀疑模块坏了,实际就是数据没做边界过滤。

5. 实操二:三菱和汇川环境里的转换指令与通信判断

5.1 三菱FX系列的BIN和BCD指令

三菱FX系列里,控制字地址通常用D寄存器,比如D0、D100。写入的数据默认为十进制整数,底层是二进制存储。但很多老式仪表、编码器或者文本屏希望收到BCD编码,这时就要用到BCD指令。

示例流程:

  • 把D0里的十进制数值转换成BCD结果,传到D10。
  • 如果D0=1234,执行BCD指令后D10里保存的0x1234,在线监控如果按十进制看是4660,按十六进制看才是1234。
  • 反向操作时,用BIN指令把D10里的BCD值还原成普通二进制数值。

这个例子非常典型。只从监控表数值来看,很多人以为D10变成了4660就是程序算错了,实际上三菱软件里D10默认十进制显示,4660只是十六进制1234的十进制表现。只要确认通信协议要求的是BCD,数据就是正确的。

注意:通信协议写明“BCD码”时,触摸屏或仪表的寄存器显示值往往和实际数值相差一个“十进制和十六进制”的视觉差。判断标准不是看数值像不像,而是看协议描述。

5.2 汇川PLC中的常用转换指令

汇川PLC整体指令风格和IEC标准更接近,数据类型概念和西门子有相似之处,比如支持INT、DINT、REAL等类型。编程时同样要遵守类型匹配原则,不同类型做运算前需要转换。

汇川环境里常见的做法是使用转换指令或直接在结构化文本里使用类型转换函数。如果在梯形图里碰到类型不匹配,软件会提示;但提示不意味着程序不能下载,有些情况下只是警告,结果不对,要回到数据类型上重新检查。

我在实际项目里会优先把通信类寄存器统一配置成Word或DWord,再把需要运算的数值通过转换指令变成Int或Real。这样通信层和人机交互层分离,排查问题时能快速定位是通信解包错了,还是数据运算错了。

5.3 通信场景下的数据长度和进制判断

PLC做Modbus通信时,寄存器默认16位,一个寄存器能读到一个Word。如果设备说明书里写“寄存器地址40001,数据类型为无符号整数,单位0.1℃”,那你读到的值要乘以0.1才是实际温度。这里既有数据长度问题,也有数值解释问题。

如果设备有两个寄存器组合成一个32位浮点数,就要考虑字节顺序和字顺序。常见的顺序组合有ABCD、CDAB等,顺序不对会导致数值变成天文数字或特别小的数。这种问题不是进制不会算,而是没有确认协议格式。

排查通信数值异常时,我会按这个顺序来:

  1. 先看原始寄存器值,确认数据类型,是16位还是32位。
  2. 再看编码方式,是普通二进制还是BCD码。
  3. 再看有无符号,是无符号整数还是有符号整数。
  4. 最后看高低字节顺序,是否需要交换。

这四层都要和仪表说明书的寄存器表对照。只有说明书齐全,才能一次性判断出该用哪种转换。

6. 总是出错?按这个顺序排查数据类型和进制问题

6.1 从现象反推问题层次

数据不对的排查不应该从“猜指令”开始,而应该从现象分层。

  • 如果触摸屏上显示的值和实际设备读数相差很大,先看是不是模拟量量程换算问题。
  • 如果通信读到的寄存器值一直是0或65535,先看数据类型和寄存器地址。
  • 如果比较运算结果不稳定,先看参与比较的变量是INT还是REAL,是否混用了类型。
  • 如果程序偶尔报错但下载正常,先看是否存在数组越界、数据超出目标范围。

不要一上来就改算法。先用监控表把每一个中间量都看一遍,找到第一个数值出现异常的位置,再顺藤摸瓜。

6.2 常见错误一:有符号和无符号混用

典型场景:外部设备返回一个无符号整数40000,PLC变量却声明成INT,程序里就显示-25536。此时无论是比较、显示还是通信回传,都会错。

处理方式:把变量类型改成Word或DInt,确保目标范围能覆盖源数据。如果不是自己项目里的变量,最好在程序里加一条范围判断,把超出合理范围的数据丢弃或报警。

6.3 常见错误二:十六进制当成BCD码处理

典型场景:温控仪表返回BCD码0x2500,代表温度250.0℃。如果直接把0x2500按普通十六进制转成十进制,结果是9472,再除以10就是947.2℃,完全乱了。

处理方式:判断协议里有没有“BCD”字样。有BCD字样时,按BCD解码,比如0x2500解析为十位2、百位5、个位0、小数位0,再合成250.0。不要看到十六进制就按HEX转十进制,先把编码方式确认了再动手。

6.4 常见错误三:通信字节顺序颠倒

典型场景:读一个32位浮点数,PLC解出来是1.23,触摸屏显示成823456000000000000000之类的超大数。

处理方式:直接按字节交换顺序验证。可以先把原始四个字节按顺序LOW、HIGH、HIGH、LOW或HIGH、LOW、LOW、HIGH组合一遍,看哪个结果落在合理范围内。实际项目里,这个试错过程一般不超过十分钟。

6.5 固定排查清单

最后留一份我自己排查数据类故障时会对照的清单:

检查项判断标准
数据类型是否明确每个变量都有类型,没有灰色寄存器
数值范围是否匹配无符号数不超过上限,有符号数不出现负值异常
通信协议编码方式明确是HEX、BCD、还是二进制补码
字节顺序16位和32位分别检查是否需要交换
模拟量量程换算确认原始值上下限和工程量上下限
边界值处理断线、超限、初始值都有过滤条件

这个清单可以贴在调试工位旁边。每次遇到“数值对不上”,按表逐项打勾,大多数问题都能在半小时内定位。做PLC项目,数据类型的功夫不在背概念,而在遇到问题时有条理地拆开检查,先看存储规则,再看进制解释,最后查通信顺序。把这一套流程练熟,后面再接触运动控制、视觉通信、数据库对接,都能少走很多弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询