很多人学 PLC,前面几课学得还挺顺。
会写启动停止,会写定时器,会写顺控,也能做个小水泵控制。可一到后面,程序一复杂,就开始乱。
最常见的问题不是不会写触点,也不是不会写线圈,而是这几个问题:
这个信号该放在 X 里,还是放在 M 里
这个数值为什么不能直接用线圈
模拟量为什么要放到 D 里
计数值为什么和开关量不一样
一个温度值到底占一个寄存器,还是两个寄存器
为什么有时候程序明明没错,数据却乱了
说到底,问题都集中在一个地方:
你对 PLC 的数据类型和寄存器分工还没有真正建立起来。
这一讲,我们就把这个最容易被初学者忽略、但又特别关键的基础彻底讲明白。
你把这一讲吃透,后面学比较指令、运算、通讯、模拟量、PID、触摸屏、变频器通讯,都会顺很多。
一 先说最核心的一句话
PLC 程序不是只有“有电”和“没电”两种东西。
它既要处理开关量,也要处理数字量,还要处理模拟量、计数值、时间值、状态字、故障码、设定值。
所以 PLC 内部一定要有不同类型的数据存放方式。
你可以把 PLC 想成一个小型工业计算机。
它一边采集现场输入信号,一边执行程序,一边把结果输出给设备。
在这个过程中,它必须有“地方”来存东西。
这些“地方”,就是我们平时说的寄存器、软元件、存储区。
而不同种类的数据,需要放在不同类型的寄存器里。
这就是为什么我们总会看到:
X
Y
M
D
T
C
不同品牌写法略有差异,但背后的思想是一样的。
二 什么叫数据类型
先不要急着背字母,先把“数据类型”理解掉。
所谓数据类型,你可以简单理解成:
PLC 里存储数据时,这个数据到底是按什么形式存在的。
最常见的有四类。
1 位
位就是最小的数据单位。
它只有两个状态:
0
1
也就是:
断开
接通
或者:
假
真
所以位最适合表示这种信息:
按钮有没有按下
传感器有没有到位
报警有没有发生
电机有没有运行
模式是不是自动
阀门是不是打开
这种东西不需要存 58,也不需要存 126,更不需要存 2350。
它只需要表示“有”或者“没有”。
所以这种信号最适合用位。
2 字节
字节由 8 位组成。
也就是说,一个字节可以同时表示 8 个 0 和 1 的组合。
在很多 PLC 基础编程里,字节这个概念不一定天天单独拿出来用,但它很重要。
因为通讯、状态字拆分、故障码分析、ASCII 字符处理时,经常会碰到字节。
你可以先记住:
1 个字节等于 8 位。
3 字
字通常是 16 位。
也就是两个字节组成一个字。
16 位能表示的数值范围就比单个位大得多。
因此很多“数值型数据”都会放在字寄存器里。
比如:
模拟量采样值
温度值
频率设定值
累计产量
参数设定值
故障代码
通讯寄存器值
这些都不是简单的 0 和 1,往往需要用一个“字”来存。
4 双字
双字通常是 32 位。
也就是两个字组成一个双字。
为什么需要双字?
因为有些数据范围特别大,一个字已经不够装了。
比如:
很大的累计计数
脉冲总量
编码器累计位置
长时间累计运行时间
更高精度的工程量
某些通讯数据
32 位整数
如果一个字最大只够表示几万,而你的累计量已经几十万、几百万,那就必须上双字。
三 初学 PLC 时,最容易犯的第一个错误
很多人刚开始学 PLC,会把“位”和“字”混成一回事。
这是最危险的。
位适合做状态
例如:
启动按钮
停止按钮
电机运行反馈
液位高位开关
报警标志
自动模式标志
字适合做数值
例如:
温度 68.5 摄氏度
压力 0.42 兆帕
变频器给定频率 35.0 赫兹
当前产量 126 件
延时设定 15 秒
故障代码 203
你不能把“温度 58.3”这种数值,硬塞到一个位元件里。
也不能把“电机运行状态”非要用一个字来存。
如果分工不清,程序写到后面一定乱。
四 PLC 里常见寄存器到底是干什么的
下面进入最关键的部分。
我们把常见的几类寄存器一个个讲清。
不同 PLC 品牌名称可能不一样,但思路差不多。
这里咱们先用最常见、最容易理解的写法来讲。
五 X 输入继电器
X 一般表示外部输入点。
也就是说,现场接到 PLC 输入端子的那些开关信号,经过 PLC 采集后,会映射到 X 区。
比如:
启动按钮接到输入端子
停止按钮接到输入端子
接近开关接到输入端子
光电开关接到输入端子
压力开关接到输入端子
液位开关接到输入端子
程序里就会用 X0、X1、X2 之类去读取它们的状态。
X 的特点
第一,X 是位。
它只有 0 和 1 两种状态。
第二,X 一般对应真实硬件输入。
也就是说,X 的状态来自现场,而不是你在程序里随便“造”出来的。
第三,X 通常用于条件判断。
比如:
X0 按下了没有
X3 到位了没有
X5 有没有过载信号
X7 急停是不是断开了
一个简单例子
如果启动按钮接在 X0,停止按钮接在 X1,接触器输出在 Y0。
那最基本的启动停止逻辑,实际上就是拿 X0 和 X1 作为输入条件。
这里 X 就是“外部世界告诉 PLC 的信息”。
六 Y 输出继电器
Y 一般表示外部输出点。
PLC 程序经过运算后,会把结果送到 Y 区,再由输出端子去驱动现场设备。
比如:
接触器线圈
电磁阀
指示灯
蜂鸣器
继电器
变频器启停端子
制动器
Y 的特点
第一,Y 也是位。
它只有开和关两种状态。
第二,Y 一般对应真实硬件输出。
比如 Y0 通电,外部接触器吸合;Y1 通电,电磁阀动作。
第三,Y 是程序运算后的执行结果。
也就是说,X 是“采集进来的”,Y 是“控制出去的”。
一个直观理解
X 像耳朵和眼睛。
PLC 通过 X 听现场、看现场。
Y 像手和脚。
PLC 通过 Y 去推动现场设备动作。
七 M 内部继电器
M 是最重要、也最容易被初学者忽视的一类元件。
M 一般表示内部继电器,也叫辅助继电器、中间标志位、内部位。
它不直接对应现场输入端子,也不直接对应现场输出端子。
它是 PLC 内部自己用来存储逻辑状态的。
你可以把 M 理解成程序里的“中间变量”或者“内部开关”。
M 最适合干什么
自动模式标志
启动条件成立标志
步骤 1 状态
步骤 2 状态
报警锁存标志
复位允许标志
联锁成立标志
某段逻辑执行结果
某个动作完成标志
为什么 M 特别重要
因为真实项目里,程序逻辑不可能永远直接拿 X 控 Y。
如果一上来就是:
X0 按了,Y0 动
X1 按了,Y1 动
程序会非常原始,也很难维护。
工程上更常见的做法是:
先把条件整理成一个内部状态
再根据内部状态去控制输出
例如:
自动模式成立,用 M10 表示
系统允许运行,用 M11 表示
泵一启动命令,用 M20 表示
泵一运行中,用 M21 表示
故障锁存,用 M30 表示
这样程序就清楚很多。
M 和 X Y 的关系
X 是外部输入
Y 是外部输出
M 是内部逻辑状态
这三者分工一旦清楚,程序就开始像样了。
八 D 数据寄存器
D 是数值处理里最关键的一类。
D 一般表示数据寄存器,用来存放数值。
它通常不是单个位,而是一个字,很多时候也可以组合成双字。
D 最适合放什么
模拟量采样值
工程量换算结果
温度值
压力值
频率值
时间设定值
计数设定值
故障代码
通讯读写数据
配方参数
产量累计
设备运行时间
举一个最常见的例子
一个温度变送器输出 4 到 20 毫安,接到 PLC 模拟量输入模块。
模块采集到的原始值可能是 0 到 4000,或者 0 到 32000。
这个值通常会先放进某个 D 寄存器里,比如 D100。
然后程序再根据量程换算,把它变成实际温度,比如 0 到 100 摄氏度,结果放到 D110。
这就说明:
D100 里存的是原始采样值
D110 里存的是工程量温度值
这两个都不是位,而是数值。
所以都应该放在 D 里。
再举一个例子
触摸屏上设置一个变频器运行频率 35.0 赫兹。
这个设定值通常也会写到 D 寄存器里,比如 D200。
PLC 再把 D200 里的值通过通讯发给变频器,或者经过模拟量模块输出给变频器。
你看,这里 D 就成了“参数仓库”。
九 T 定时器
T 是定时器。
定时器看起来像一个元件,其实它通常包含两部分信息:
一个是定时器触点状态
一个是当前计时值或完成状态
在基础编程里,我们最常用的是它的触点效果。
比如定时到,T0 接通;没到,T0 断开。
T 本质上解决什么问题
让程序具备“时间逻辑”。
例如:
启动后延时 3 秒再开风机
停止后延时 10 秒再关阀门
报警出现 5 秒后才确认
按钮按下超过 2 秒才算有效
润滑泵每隔 30 分钟运行一次
T 和普通位有什么不同
M 只是状态
T 带时间属性
也就是说,M10 可能只是表示“自动模式成立”。
而 T0 表示“这个条件成立后,已经累计一段时间”。
所以 T 虽然在程序里也常通过触点来用,但它背后本质上不是普通位,而是带计时功能的特殊元件。
十 C 计数器
C 是计数器。
它和 T 很像,也是一类带功能属性的元件。
只不过 T 是按时间累计,C 是按次数累计。
C 适合干什么
产品到一个算一个
包装数量达到 10 个动作一次
电机启动次数统计
故障发生次数统计
信号脉冲计数
批量生产件数累计
C 和普通位的区别
位只能表示“有没有”
计数器能表示“有了多少次”
比如传感器每来一个脉冲,就让 C0 加 1。
当 C0 到达设定值 20 时,触发某个动作。
所以 C 的本质,不只是开关,而是带数量属性的逻辑元件。
十一 那字节、字、双字到底和这些元件怎么对应
这是很多人最容易糊涂的地方。
简单说:
X、Y、M 多数情况下按位来用
D 多数情况下按字来用,也可以组合成双字
T、C 是特殊功能元件,既有状态属性,也往往带当前值或设定值
一个通俗理解
如果你要表示“启动按钮按下没有”,这是位。
如果你要表示“当前温度 63”,这是字。
如果你要表示“累计运行总脉冲 256800”,可能就要双字。
所以不是先问这个元件叫什么字母,
而是先问这个数据本质上是状态,还是数值,还是大数值。
十二 为什么模拟量一定离不开 D
因为模拟量本来就不是“开”和“关”。
比如压力变送器输出 4 到 20 毫安,量程是 0 到 1.0 兆帕。
PLC 采集后,得到一个整数值,比如 1860,或者 27840,具体看模块分辨率。
这时候这个数必须存到一个能表示数值的地方。
这个地方通常就是 D。
然后再做比例换算:
原始值
转成
工程值
假设换算后得到 0.62 兆帕。
为了便于 PLC 处理,很多工程里会把它放大 10 倍或 100 倍来存。
比如把 0.62 兆帕存成 620 或 62。
无论怎么处理,本质上都在 D 里流转。
所以学模拟量之前,你必须先明白 D。
十三 为什么触摸屏参数也大多写到 D
因为触摸屏不是只负责显示“亮”和“灭”。
它更多时候要显示和输入的是数值。
比如:
温度设定值
运行时间
变频器频率
压力上限
计数目标值
报警阈值
手自动切换状态字
配方号
班产量
这些本质上都是数据。
所以触摸屏和 PLC 通讯时,经常围绕 D 区来交换数据。
举个很典型的例子。
HMI 上有一个“压力设定值”,操作员输入 0.45。
PLC 为了避免浮点处理复杂,可能把它写成 450,放到 D300。
程序里拿 D300 和实际压力 D100 做比较,决定要不要启动水泵或调节输出。
这就是最典型的“参数寄存器应用”。
十四 为什么内部逻辑尽量多用 M,而不是乱占 Y
初学者有一个很常见的坏习惯:
还没真正接输出设备,就先拿 Y0、Y1、Y2 当内部标志用。
这种写法短期似乎也能跑,但工程上很不好。
因为 Y 本来是输出点。
你拿它做内部逻辑,就会导致:
后面硬件分配混乱
别人看程序不清楚
现场调试时容易误以为真实输出动作
修改时很危险
所以建议是:
内部条件、步骤、状态、锁存、联锁,优先用 M
真实执行输出,才用 Y
这是一种很重要的程序习惯。
十五 实际项目里,寄存器分工最好怎么做
这部分特别重要。
你程序后面乱不乱,不是由“会不会写指令”决定的,而是由“寄存器分工清不清”决定的。
下面给你一个比较实用的分工思路。
1 X 区
只放现场输入信号
比如:
启动按钮
停止按钮
急停
到位开关
液位开关
故障反馈
热继电器触点
手自动选择开关
2 Y 区
只放现场输出控制
比如:
接触器
电磁阀
蜂鸣器
指示灯
风机
泵
变频器启停
制动器
3 M 区
放内部逻辑和状态
比如:
自动模式
手动模式
运行允许
复位允许
报警锁存
步骤一
步骤二
启动命令
延时确认完成
条件组合结果
4 D 区
放数值和参数
比如:
设定温度
实际温度
原始模拟量
换算结果
运行时间设定
计数目标
产量累计
故障代码
通讯接收数据
通讯发送数据
5 T 区
放时间逻辑
比如:
启动延时
停止延时
报警确认延时
润滑周期
消抖延时
6 C 区
放数量逻辑
比如:
产品计数
包装计数
故障次数
循环次数
工件数量
你按这个思路写程序,哪怕程序大一些,也不容易乱。
十六 一个小案例,把这些元件串起来
咱们用一个很简单的风机控制案例来看看。
现场要求
按启动按钮后,风机不要马上启动,延时 3 秒启动。
风机运行后,绿灯亮。
如果热继电器动作,风机停机,红灯亮,同时故障锁存。
按复位按钮后,故障消除。
触摸屏上可设定启动延时时间。
还要统计风机累计启动次数。
这时候各类寄存器怎么分工
X0 启动按钮
X1 停止按钮
X2 热继故障
X3 复位按钮
Y0 风机接触器
Y1 运行绿灯
Y2 故障红灯
M10 运行命令
M11 故障锁存
M12 启动允许
D100 启动延时设定值
D110 启动次数累计
T0 启动延时定时器
C0 启动计数器
逻辑怎么理解
第一步,启动按钮按下,且没有故障,且满足运行条件,先置一个 M10 运行命令。
这里用 M,而不是直接拉 Y0,是为了让逻辑清晰。
第二步,M10 成立后,启动 T0 延时计时。
T0 到时后,才输出 Y0,驱动风机。
第三步,Y0 动作后,Y1 亮。
说明风机运行。
第四步,如果 X2 热继故障来了,立即断开 Y0,同时置位 M11 故障锁存,Y2 亮。
第五步,X3 复位按钮按下,且故障输入消失后,复位 M11。
第六步,每次风机真正启动成功,就让 C0 或 D110 进行计数累计。
你看,这时候每一类元件都各有分工。
程序思路一下就清晰了。
十七 初学者最容易踩的几个坑
下面这些坑,现场特别常见。
1 用 M 代替一切
有些人学会了 M,觉得特别方便,就什么都用 M。
实际值用 M,参数也想用 M,结果很快就出问题。
你要记住:
M 适合状态
D 适合数值
不要混。
2 把内部逻辑塞进 Y
前面说过,这是坏习惯。
短期能跑,长期麻烦。
3 不区分“实际输入”和“内部推导结果”
例如:
X0 是启动按钮
M10 是启动命令成立
这两个不是一回事
X0 只是“按钮被按下”
M10 可能是“按钮按下,而且没有故障,而且自动模式成立,而且联锁满足”之后的综合结果
所以别把原始输入和处理后的内部结果混了。
4 参数没有固定区域
比如这个程序里:
D10 存温度
D11 存压力
D12 突然又存报警码
D13 又变成延时设定
D14 又拿去做通讯发送
如果前面没规划,后面一定很难维护。
建议你从一开始就分区。
例如:
D100 到 D149 放模拟量采样
D200 到 D249 放参数设定
D300 到 D349 放通讯数据
D400 到 D449 放累计值
哪怕程序不大,也要养成这个习惯。
5 不知道什么时候该用双字
如果某个累计值只用一个字存,而数据越来越大,最后会溢出。
一溢出,数据就乱了。
比如产量累计特别大、脉冲累计特别大、运行时间特别长,这些都要提前考虑容量问题。
十八 为什么这一讲其实决定了你后面学得顺不顺
很多人以为 PLC 学习路线是这样的:
先学触点
再学定时器
再学计数器
再学通讯
再学项目
其实中间有一个特别关键的“桥梁”,就是这一讲。
因为后面几乎所有内容,都建立在数据寄存器和变量分工之上。
后面第10讲比较指令
要比较什么
比较的往往是 D 里的数值
第11讲数学运算
运算的对象大多也是 D
第12讲上升沿下降沿
虽然用的是位逻辑,但通常会和 M 配合
第15讲手自动急停复位
内部模式切换大量依赖 M
第20讲触摸屏
大量读写 D 和 M
第21讲变频器控制进阶
状态常用 M
参数常用 D
输入输出靠 X 和 Y
第23讲 Modbus RTU
更是离不开 D 区收发寄存器
所以这一讲学会了,后面就不是在“死记地址”,而是在“理解数据流”。
十九 给初学者一个非常实用的编程习惯
以后你每接到一个小项目,不要上来就写梯形图。
先做这一步:
先把点和数据分类型。
你可以先拿个本子,或者在电脑上列出来。
一类 现场输入
哪些是按钮
哪些是开关
哪些是传感器
哪些是报警反馈
二类 现场输出
哪些是接触器
哪些是阀
哪些是灯
哪些是蜂鸣器
三类 内部状态
哪些是自动模式
哪些是步骤状态
哪些是联锁条件
哪些是锁存故障
四类 参数和数值
哪些是设定值
哪些是实际值
哪些是累计值
哪些是通讯值
五类 时间和计数
哪些要延时
哪些要计数
哪些要定周期
你先分完类,再写程序,效率会高很多。
这也是从“会写几条梯形图”迈向“会做项目”的第一步。
二十 本课小结
这一讲你最少要真正记住下面这几件事。
第一,PLC 里不只有开和关,还有很多数值型数据。
所以必须理解数据类型。
第二,位适合表示状态,字适合表示数值,双字适合表示更大的数值范围。
第三,X 一般是外部输入,Y 一般是外部输出,M 一般是内部状态,D 一般是数值寄存器,T 是定时器,C 是计数器。
第四,程序写得乱,很多时候不是逻辑本身乱,而是寄存器分工没做好。
第五,内部逻辑多用 M,数值参数多用 D,真实输入输出分别放 X 和 Y,这是最基本的工程习惯。
第六,从这一讲开始,你要慢慢建立“先分数据,再写逻辑”的思路,而不是一上来就画梯形图。
二十一 这一讲之后,你应该能做到什么
学完这一讲,你至少应该能做到下面这些事情:
看懂一个简单程序里,X、Y、M、D、T、C 各自承担什么角色
知道一个按钮信号为什么该用 X,一个温度值为什么该用 D
知道内部状态为什么最好放 M
知道参数和模拟量为什么离不开 D
知道写程序前,先做寄存器分工是很重要的一步
如果这些你已经顺了,后面第10讲的比较指令与区间判断,你就会学得很舒服。
二十二 下节预告
下一课我们接着往下讲:
PLC 基础课 第10讲
比较指令与区间判断:大于、小于、等于,现场逻辑怎么写更稳妥
这一课会把温度上下限、液位区间、压力报警、数值联锁这些最常见的逻辑讲清楚。
它和这一讲是直接连着的,因为只要比较,背后就一定涉及数据寄存器和数值判断。
推荐阅读:
PLC 基础课 第16讲 程序分段与结构化:主程序、子程序、功能块,怎么让程序更好维护
PLC 基础课 第14讲 掉电保持、上电初始化、首次扫描:设备重启后,程序为什么会乱?
PLC 基础课 第10讲 比较指令与区间判断:大于、小于、等于,现场逻辑怎么写更稳妥
PLC 基础课 第9讲 PLC 数据类型与寄存器:位、字节、字、双字,M X Y D T C 怎么分工
PLC 基础课 第 8 讲|一个完整小项目:水泵控制柜,从电气原理图到 PLC 梯形图
PLC 基础课 第 7 讲|报警与状态:怎么写出一个好用的报警逻辑 + 保留最后一次故障