PLC数据类型与进制转换详解:从位字节字到工程实战 PLC 编程入门时很多人会把大量精力放在梯形图指令上但真正写工程程序、排查通信数据异常时往往卡在数据类型上。同一个数值在不同长度、不同进制下显示结果可能完全不同。本文结合实际电工与 PLC 编程场景围绕 PLC 数据类型展开配合进制转换的完整训练帮助新手把底层概念理清楚也为之后学习模拟量处理、Modbus 通信、变频器控制和触摸屏组态打下基础。如果你是刚接触 PLC、准备做毕业设计或已经在做小型自动化项目但经常被数据类型绕晕这篇文章都适合通读一遍。文章会同时涉及西门子 PLC 与三菱 PLC 的常见数据模型并给出可复制的进制转换方法和排错思路。1. 为什么学习 PLC 必须先搞懂数据类型1.1 数据类型决定了 PLC 如何理解数据PLC 本质上是一台工业控制计算机它的 CPU 内部只有“0”和“1”两种状态。我们在触摸屏上看到的温度 25.6℃、变频器反馈的转速 1500r/min、传感器传来的开关信号最终都会被 PLC 转换成由高低电平组成的二进制数据流。数据类型就是约定“一段二进制数应该被如何解释”的规则。用一个例子来理解二进制数1111 1111 1111 1111如果它是WORD16 位无符号整数它的值是 65535如果它是INT16 位有符号整数它的值是 -1。同一个二进制序列因为数据类型不同解释出来的结果完全不同。这也是很多初学者在通信调试时看到“数值不对”的根本原因。此外数据类型还决定了数据占用多少存储空间、参与运算时是否溢出、能不能直接传给某个指令等。比如 32 位浮点数REAL可以存储 3.14但INT无论如何也存不下带小数的数值。因此定义变量、设计数据结构、编写运算指令之前都必须先确定数据类型。1.2 PLC 数据存储与普通电脑的“位、字节、字”PLC 内部存储区的基本构成单位是“位”bit一个位只能存放 0 或 1。8 个位组成 1 个字节Byte2 个字节组成 1 个字Word16 位2 个字组成 1 个双字DWord32 位。这个规则在西门子、三菱、欧姆龙、汇川等主流 PLC 中基本一致。名称英文位宽取值范围无符号常见用途位Bit1 位0 或 1按钮、接触器、报警标志字节Byte8 位0~255打包多个开关量、通信字节字Word16 位0~65535模拟量原始值、计数器双字DWord32 位0~4294967295编码器累计值、长数据如果是有符号整数最高位作为符号位那么 16 位INT的取值范围是 -32768~3276732 位DINT的取值范围是 -2147483648~2147483647。这一点在做数据处理时特别重要因为一旦超出范围数据就会溢出得不到预期结果。1.3 不同 PLC 品牌的数据类型命名差异西门子 S7-1200/1500 遵循 IEC 61131-3 标准使用BOOL、BYTE、WORD、DWORD、INT、DINT、REAL等命名三菱 FX 系列和 Q 系列习惯用“软元件”的概念如 X输入、Y输出、M中间继电器、D数据寄存器其中 D 寄存器默认是 16 位存储单元32 位数据则需要用两个连续的 D 寄存器组合。汇川、信捷等国产 PLC 大多兼容西门子或三菱的编程习惯学习时只要能区分“位、字节、字、双字”这四层结构换品牌后也能很快上手。2. PLC 常用数据类型详解2.1 BOOL最基本的一位数据BOOL也称为“位数据”“开关量”只有0FALSE和1TRUE两个值。梯形图中的常开触点、常闭触点、线圈、置位复位指令本质上操作的都是BOOL类型。例如 S7-1200 中I0.0、Q0.1、M0.2 都是位地址。// 梯形图示意当 M0.0 为 1 时Q0.0 输出 1 M0.0 Q0.0 ---| |-----------( )---在三菱 FX 系列中X0~X7、Y0~Y7、M0~M7 也都是按位操作的软元件。需要注意的是三菱 X/Y 的地址编号采用八进制也就是说 X0~X7 之后是 X10~X17没有 X8 和 X9这一点很容易让初学者看错地址。2.2 BYTE、WORD、DWORD不同长度的无符号数据BYTE占 8 位常用来表示一个字节的通信数据。两个BYTE可以组成一个WORD四个BYTE组成一个DWORD。在工程中我们经常需要把多个布尔量打包到一个字节或一个字里这样可以减少通信数据量。比如 S7-1200 的MB0字节里M0.0 是第 0 位M0.1 是第 1 位依此类推M0.7 是最高位。// 将 2#1011_0101 传送到 MB0 // 等价于M0.71, M0.60, M0.51, M0.41, M0.30, M0.21, M0.10, M0.01 MOV 2#10110101, MB0WORD常用于模拟量原始值、Modbus 保持寄存器数据。例如 S7-1200 读取模拟量输入通道IW64得到的就是一个 0~27648 之间的整数这个值就是 16 位无符号数据。DWORD则适合存放编码器累计值、时间戳等大范围数据。2.3 INT、DINT、REAL带符号数与浮点数INT16 位有符号整数是 PLC 编程中使用频率最高的整数类型。多数运算指令返回结果也是INT。但INT的上限只有 32767如果计算结果超过这个值就会发生溢出。比如计算 20000 20000结果会变成负值这在生产环境中是非常危险的。DINT32 位有符号整数适合需要更大范围的场合比如伺服电机的累计脉冲数。REAL32 位浮点数则用来表示带小数的数值例如温度 25.6℃、压力 0.45MPa。触摸屏上显示的模拟量工程值通常在 PLC 内部先通过浮点运算换算得到再传送给 HMI 显示。2.4 TIME、STRING 等特殊数据类型TIME用于存储时间长度单位通常是毫秒。S7-1200 中我们可以直接写入T#5S、T#100MS等常量定时器指令的时间参数就是TIME类型。STRING是字符串类型适合存放设备名称、报警文本但默认长度需要设置且一个字符占用一个字节字符串在通信和触摸屏显示时会有编码差异项目初期建议固定长度。3. PLC 中的进制表示与转换基础3.1 二进制、十进制、十六进制在 PLC 中的写法在 PLC 程序中不同进制有不同的书写前缀或后缀。西门子博途TIA Portal中二进制常写作2#1010_1010十六进制写作16#3C十进制直接写数字。三菱 GX Works 中二进制用B后缀如B1010十六进制用H前缀如H3C十进制可以直接写K前缀或不加前缀。了解这些约定才能在看程序时快速读出数据。下面这张速查表列出 0~15 在常用进制下的表示建议保存备查十进制二进制八进制十六进制00000001000111200102230011334010044501015560110667011177810001089100111910101012A11101113B12110014C13110115D14111016E15111117F3.2 手算进制转换除 2 取余与 8421 法无论使用什么编程软件掌握手算转换都是基本功因为现场没有电脑时靠一张纸一支笔也要能算出通信报文中的数据值。十进制转二进制采用“除 2 取余逆序排列”的方法。以十进制 35 为例35 ÷ 2 17 余 1 17 ÷ 2 8 余 1 8 ÷ 2 4 余 0 4 ÷ 2 2 余 0 2 ÷ 2 1 余 0 1 ÷ 2 0 余 1把余数从下往上写得到100011也就是 32 2 1 35。补齐 8 位写作0010 0011。十六进制转二进制可以按“1 位十六进制对应 4 位二进制”的方法直接转换。例如十六进制2E2对应0010E对应1110所以2E的二进制是0010 1110它的十进制就是 2×16 14 46。二进制转十六进制时从右往左每 4 位分组不足 4 位在高位补 0然后每组用十六进制符号表示。例如二进制1111 0101分成1111和0101对应F5十进制是 15×16 5 245。这种分组方法也叫“8421 法”因为 4 位二进制从高到低分别代表 8、4、2、1。3.3 进制转换中的符号位处理带符号数转进制时最高位代表符号。比如 16 位INT类型的 -1在 PLC 存储中其实是2#1111_1111_1111_1111对应十六进制16#FFFF。如果把这个值当无符号数读出就是 65535。这也是 Modbus 通信中经常遇到的问题从站返回的寄存器值明明显示 65535上位机却把它当成 -1原因就是有符号/无符号解释不一致。所以在做进制转换时第一步要明确“当前数据类型是有符号还是无符号”。需要将 16 位数据读出并显示为有符号数时要选择INT格式需要显示 0~65535 范围时要选择WORD格式。4. 地址与数据类型的对应关系实操4.1 西门子 PLC 的位寻址与字寻址西门子 S7-1200/1500 的存储区以字节为基本单位地址格式为“区域字节地址位地址”。以 M 区为例M0.0M 区第 0 字节的第 0 位是按位访问。MB0M 区第 0 个字节按字节访问可赋值为16#3C。MW0M 区第 0 个字占用MB0和MB1两个字节。MD0M 区第 0 个双字占用MB0~MB3四个字节。这种设计很容易出现地址重叠。如果程序中先向MW0写了 100之后又向MB0写了 200那么MW0的高字节被覆盖整个字的值就不再是 100。排错时要特别留意是否有人误操作了字节地址。4.2 三菱 PLC 的软元件与数据类型三菱 FX 系列中D 寄存器是最常用的数据寄存器默认 16 位。例如D0可以存放 -32768~32767 的整数也可以存放 0~65535 的无符号数具体取决于程序怎么解释。如果需要 32 位数据通常用D0和D1组合低 16 位在D0高 16 位在D1。在 GX Works 中高 16 位和低 16 位的组合顺序需要留意不同指令可能按“高位在前”或“低位在前”的方式解释。通信时如果发现数据错位优先检查组合寄存器方向。4.3 Modbus 通信中的数据类型长度Modbus 是目前工业通信中使用最广泛的协议之一。Modbus RTU 的数据模型很简单线圈Coil1 位对应 PLC 中的BOOL。离散输入Discrete Input1 位对应BOOL。保持寄存器Holding Register16 位读写都支持。输入寄存器Input Register16 位只读。所以一个 Modbus 保持寄存器天然就是WORD或INT的长度。如果需要传输 32 位数据比如浮点数或长整数就需要占用两个连续的保持寄存器。这就要求通信双方约定好字节顺序否则可能出现高 16 位和低 16 位互换数据完全对不上。例如西门子 S7-1200 作为 Modbus 从站40001 地址对应一个 16 位保持寄存器如果上位机要读取 32 位浮点数就需要同时读取 40001 和 40002 两个寄存器再按 IEEE 754 格式拼接成浮点数。5. 进制转换实操从手工到程序5.1 手工转换训练三个典型实例下面做三个最常见的转换训练先不看答案自己动手算一遍。实例一十进制 200 转二进制和十六进制。200 ÷ 2 100 余 0 100 ÷ 2 50 余 0 50 ÷ 2 25 余 0 25 ÷ 2 12 余 1 12 ÷ 2 6 余 0 6 ÷ 2 3 余 0 3 ÷ 2 1 余 1 1 ÷ 2 0 余 1逆序得到11001000即 128 64 8 200。从右往左每 4 位分组1100对应C1000对应8所以十六进制是C8。实例二十六进制3F转十进制和二进制。3对应十进制 3F对应 15所以数值为 3×16 15 63。二进制为0011 1111。实例三二进制1010 1100转十六进制和十进制。1010对应A1100对应C十六进制是AC。十进制为 128 32 8 4 172。5.2 使用编程软件与 Windows 计算器辅助验证手工计算完成后建议使用工具验证一遍。Windows 自带的计算器切换到“程序员”模式即可在 DEC、HEX、BIN 之间快速切换。西门子博途的监控表中也可以把变量显示格式切换为二进制、十六进制、十进制等便于在线观察数据变化。在博途监控表中操作步骤如下新建监控表添加需要监控的变量。右键点击监控值列选择“显示格式”。根据变量类型选择“十六进制”“二进制”或“十进制”。三菱 GX Works 中选择“软元件监控”双击对应寄存器同样可以切换显示格式。学会在编程工具里切换进制显示可以大大提升在线调试效率。5.3 PLC 程序中实现进制转换的思路与示例PLC 程序里一般不直接“转换进制”而是通过选择不同的数据类型来解析同一个二进制数。例如在 S7-1200 中定义两个变量VAR WordValue : WORD; // 无符号 16 位 IntValue : INT; // 有符号 16 位 END_VAR当WordValue和IntValue指向同一个内存地址时例如都指向 MW10同一个二进制数16#FFFFWordValue显示 65535IntValue显示 -1。这就是通过数据类型改变解释方式。如果需要把 BCD 码转换成十进制数可以使用转换指令。西门子 S7-1200 中有BCD_TO_I、I_TO_BCD等指令。三菱 FX 系列有BCD和BIN指令。以下是三菱的示例// 将 D0 中的 BCD 数据转换为二进制数据存放到 D1 BCD D0 D1 // 将 D10 中的二进制数据转换为 BCD 数据存放到 D11 BIN D10 D11这里的BCD和BIN并不是十进制与二进制的直接互转而是 4 位二进制表示一位十进制数的 BCD 码与 CPU 内部二进制数之间的转换。现场维修仪表、触摸屏数值显示时经常会用到。如果用 SCL 编写也可以做简单的数值拆分。例如把 16 位数据的高字节和低字节分别取出VAR myValue : WORD; hiByte : BYTE; loByte : BYTE; END_VAR hiByte : BYTE_TO_BYTE(SHR(IN : myValue, N : 8)); loByte : BYTE_TO_BYTE(myValue AND 16#FF);SCL 中SHR是右移指令16#FF是十六进制常量 255用来屏蔽高字节只保留低字节。这种写法在通信报文处理中非常常见。另外开发调试时我们可以借助 Python 快速验证计算结果。以下脚本可以在 PC 上做进制转换验证# 文件路径converter_demo.py def hex_to_bin(hex_str, bits16): 十六进制转二进制字符串 num int(hex_str, 16) return format(num, f0{bits}b) def dec_to_hex(num): 十进制转十六进制 return hex(num) def bin_to_dec(bin_str): 二进制转十进制 return int(bin_str, 2) if __name__ __main__: print(hex_to_bin(2E, bits8)) # 输出 00101110 print(dec_to_hex(200)) # 输出 0xc8 print(bin_to_dec(11001000)) # 输出 2006. 常见错误与排查思路6.1 数据类型不一致导致编译错误或数值错误PLC 程序在调用指令时如果数据类型不匹配有些编程软件会直接报错有些则会在程序块接口中自动生成转换指令。西门子博途通常会自动插入转换但三菱 GX Works 对类型要求相对宽松容易出现“程序能下载运行但数据错误”的情况。问题现象常见原因解决思路编译报“操作数类型不匹配”INT 与 WORD 混用统一数据类型或显式转换运算结果变成负数INT 溢出超过 32767改用 DINT 或对结果做限幅监控表显示值与触摸屏不一致显示进制/数据类型设置不同检查 HMI 变量类型与 PLC 变量类型Modbus 读到的数值高低字节颠倒32 位数据拼接顺序不一致约定字节序使用 Swap 指令调整BCD 转十进制后数值异常用错 BCD/BIN 指令确认数据源是否为 BCD 格式6.2 符号位问题16#FFFF 到底是多少很多调试场景下通信收到的16#FFFF被显示为 65535而实际设备发送的可能是 -1。这并不一定是通信错误而是数据类型解析不同。排查时先确认协议规定的是有符号数还是无符号数。如果是 -1应使用INT类型接收如果是 65535则使用WORD类型接收。6.3 地址重叠导致数据被意外修改西门子 PLC 中MW0与MB0、MB1共用存储空间。如果程序里同时写MW0和MB0后执行的指令会覆盖先前的数据。三菱 PLC 中使用D0作为 32 位数据低字后D1会被自动占用如果再单独使用D1就会破坏 32 位数据。排查这类问题的方法是交叉引用功能查看同一个地址被哪些指令引用。6.4 模拟量转换时实数与整数混用模拟量输入模块输出的原始值通常是INT或WORD但触摸屏上需要显示工程量例如 0~100℃。这时要先做量程换算运算过程中应使用REAL最后再转换成显示用整数或直接在 HMI 中处理。如果全程用INT中间结果产生小数部分时会被直接舍去导致显示精度明显下降。7. 最佳实践与工程建议7.1 程序命名体现数据类型建议在变量命名中加入数据类型标识便于多人协作和后期维护。例如bStartButton // BOOL启动按钮 wTempRaw // WORD温度模拟量原始值 iMotorSpeed // INT电机转速 dPosition // DINT绝对位置脉冲 rCurrent // REAL电流工程值这样在查看程序时不需要点开变量表也能大致判断每个变量适合参与什么运算。7.2 统一常量进制减少误读程序中的固定参数建议统一使用十六进制。比如 16#3C 比十进制 60 更直观地对应到某个寄存器的位组合而需要和设备手册比对时十六进制可以快速拆解成二进制位状态。如果程序里混合使用 10、0x3C、2#111100 等写法后期阅读会非常吃力。7.3 通信项目必须固化寄存器映射表在做 Modbus 通信、PLC 与上位机通信、PLC 与变频器通信时建议从一开始就建立一张寄存器映射表至少明确以下字段寄存器地址、寄存器数量、数据类型、字节序、数据范围、单位、读写权限。这样做可以避免现场调试时反复猜测数据含义也方便后续维护人员接手。7.4 修改数据地址前先备份并测试任何涉及数据地址、数据类型、通信参数修改的操作都应在测试环境验证或者提前导出完整程序备份。尤其是涉及设备动作的控制逻辑时建议先断开执行机构电源或切换到手动模式再逐步修改验证。在运行设备上直接改数据和地址一旦出错可能造成设备损坏或安全事故。7.5 善用博途在线监控与交叉引用在线调试时优先使用“监控表”观察变量实时值通过切换显示格式对比不同进制下的结果。遇到数据被意外修改时使用“交叉引用”功能查看该地址被哪些指令读写。这个习惯可以节省大量排查时间。8. 结语与下一步学习方向本讲围绕 PLC 数据类型展开详细说明了位、字节、字、双字的基本结构整理了 BOOL、BYTE、WORD、INT、DINT、REAL 等常用类型的使用场景并结合西门子和三菱 PLC 给出了地址与数据类型的对应关系。进制转换部分从手工换算开始覆盖二进制、十进制、十六进制的互转最后落到 PLC 程序中的实际应用与常见排错方法。下一步可以继续学习模拟量信号处理、Modbus 通信协议、PLC 与变频器/伺服驱动器的通信配置这些内容都离不开数据类型和进制转换。建议你在自己的 PLC 上新建一个测试项目定义几个不同类型的变量用不同的进制格式监控它们的变化动手跑一遍才能真正记住。如果按本文方法调试后还有疑问欢迎在评论区留言一起交流。