1. 计数器基础从“数数”到工业控制的桥梁很多刚接触PLC的朋友一听到“计数器”可能会觉得这不就是数数嘛有什么复杂的我刚开始也是这么想的直到在项目现场踩了几个坑才明白工业现场的“数数”和咱们日常的“数数”完全是两码事。想象一下一条高速灌装线每分钟有300瓶饮料飞驰而过你要准确无误地记录每一瓶并且在数到第10000瓶时自动触发一个换箱或者停机信号不能多一个也不能少一个。这背后就是PLC计数器在默默工作。简单来说PLC计数器就是一个内置的“电子累加器”。它专门用来记录外部输入信号比如传感器检测到产品通过的信号从“无”到“有”的那个跳变瞬间我们称之为上升沿的次数。它有两个非常重要的组成部分这也是新手最容易混淆的地方计数器位和当前值。你可以把计数器想象成一个带显示屏和指示灯的小盒子。当前值就是显示屏上不断变化的数字比如“已计数9527”。而计数器位就是旁边的一个小灯泡它只有亮1和灭0两种状态。这个灯泡什么时候亮呢这就取决于我们给计数器设定的目标也就是设定值PV。当显示屏上的数字当前值达到或超过我们设定的目标时小灯泡“啪”一下就亮了。这个亮起的灯泡计数器位为1就可以去控制PLC的输出点比如让一个气缸动作、一个电机停止或者点亮一个“批次完成”的报警灯。这里有个关键点当前值可以一直往上加甚至超过设定值但计数器位一旦被点亮除非被复位否则它会一直保持亮的状态。这就像你设了个闹钟早上7点响计数器位置1之后时间走到8点、9点当前值继续增加闹钟的“响过”状态依然是存在的。理解“位”和“值”的分离是玩转计数器的第一步。在PLC里每个计数器都有一个唯一的编号比如C0, C1, C2... 这个编号就代表了那个“小盒子”。当你编程时写C10可能指的是读取它的当前值比如用于显示也可能指的是判断它的位状态比如IF C10 THEN ...。具体是哪种取决于你把它用在什么指令里。这种设计非常巧妙一个资源两种用途让我们的程序逻辑可以写得既简洁又强大。2. 核心三剑客CTU、CTD、CTUD深度拆解PLC的计数器指令主要有三种类型我把它们叫做“核心三剑客”。它们各有各的脾气和适用场景用对了事半功倍用错了调试起来能让人抓狂。2.1 增计数器CTU最经典的“加法大师”CTU是应用最广泛的计数器它的逻辑最直观只加不减。它有两个关键输入计数输入CU和复位输入R还有一个参数是设定值PV。我习惯用一个快递分拣线的例子来理解它。假设一个光电传感器接在CU端每检测到一个包裹通过就发出一个脉冲信号。我们的CTU计数器比如C1就负责数这个脉冲。设定值PV我们设为100意味着每100个包裹打成一个包。工作流程系统启动C1当前值为0位状态为0灯灭。第一个包裹通过传感器信号从0变1上升沿C1当前值变成1。第二个包裹通过变成2... 就这样一直累加。触发动作当第100个包裹通过C1当前值变成100等于设定值PV。这时C1的计数器位立刻从0变成1灯亮。这个“1”信号就可以触发后续动作比如控制一个推杆动作将这100个包裹推入打包区或者启动打包机。复位与溢出打包动作完成后我们需要一个复位信号比如一个按钮或打包完成传感器接在R端给C1。当R端信号为1时C1的当前值会被瞬间清零位状态也复位为0灯灭准备下一轮的100个计数。如果复位信号没来传送带还在运行C1的当前值会继续增加101, 102... 直到最大值32767对于16位整数。但请注意位状态在达到设定值后就已经是1了之后会一直保持为1不会因为当前值继续增加而改变。新手常踩的坑很多人以为CU端有信号一直为1就会一直计数。错CTU只认上升沿也就是信号从0跳到1的那个瞬间。如果传感器一直挡着物体信号持续为1那么无论持续多久都只会计数一次。必须等信号消失变0再出现变1才会产生下一个计数脉冲。这是边沿触发的精髓。2.2 减计数器CTD逆向思维的“减法专家”CTD的逻辑和CTU正好相反它是先装载再递减。它的核心输入是装载输入LD和计数输入CD参数同样是设定值PV。最适合它的场景是仓库物料管理。假设一个料箱初始有50个零件机械手每次取走一个。初始化装载系统上电或换上新料箱时我们触发一个LD信号比如一个“料箱就位”传感器。这个上升沿信号会将设定值PV50直接装载到计数器的当前值。此时当前值50位状态为0。递减计数机械手每取走一个零件会触发一个CD信号上升沿。CTD的当前值就减149, 48, 47...零位报警当零件被一个个取走当前值减到0时意味着料箱空了。此时CTD的计数器位状态从0变为1灯亮。这个信号可以立刻触发警报通知上料机补充新料箱或者亮起红灯。重新装载新料箱补充到位再次触发LD信号当前值又被重置为50位状态清零开始新一轮的递减计数。CTD和CTU一个关键区别在于初始值CTU从0开始往上加CTD则需要你用LD信号将一个预设值PV“灌入”当前值然后从这个数开始往下减。它的“目标”通常是0。这个特性在需要倒计数或余量监控的场景中非常有用。2.3 增减计数器CTUD能进能退的“全能选手”CTUD是功能最强大的计数器它同时支持增加和减少。它有三个关键输入增计数输入CU、减计数输入CD和复位输入R。一个经典的案例是立体仓库的货位管理。一个提升机在货架前上下运动我们需要实时知道它所在的层数。双向计数提升机每向上移动一层上限位传感器发出一个脉冲给CU端层数当前值1。每向下移动一层下限位传感器发出一个脉冲给CD端层数当前值-1。这样CTUD的当前值就实时反映了提升机所在的楼层比如当前值5就在第5层。边界触发我们可以设定一个PV值比如10代表最高层。当提升机上升到第10层当前值≥10时计数器位置1。这个信号可以用来限制继续上升或者触发顶层的操作。同样我们也可以关注0或负值当下降到地下室当前值≤-1时触发另一个动作。CTUD的位状态在当前值大于等于PV时置位复位信号R则拥有最高优先级无论当前在计数还是触发状态一个R信号就能让当前值和位状态全部归零。循环与溢出这是一个高级特性。CTUD的当前值是一个有符号整数通常-32768到32767。如果当前值已经是32767再来一个CU脉冲它会变成-32768下溢。反之当前值是-32768时来一个CD脉冲会变成32767上溢。这就像一个圆环到了头就绕回来。在大多数常规应用中我们要避免这种情况但在一些特殊的环形位置编码或超大范围计数中这个特性可能被利用。实际调试心得在使用CTUD时一定要处理好CU和CD信号的防抖动和互锁。特别是在机械振动大的环境传感器可能会产生多个抖动脉冲导致计数错误。我通常会在程序里对输入信号做一下滤波处理或者确保在一个扫描周期内CU和CD不会同时有效避免逻辑混乱。3. 从梯形图到语句表两种编程视角的实战解析理解了三种计数器的功能我们来看看如何在PLC程序中把它们“画”出来和“写”出来。主流的方式有两种梯形图LAD和语句表STL。梯形图像电路图直观语句表像汇编代码高效。我们以西门子S7-200/200 SMART为例。3.1 梯形图LAD中的计数器梯形图是电工和初学者最喜欢的形式因为它和继电器电路图几乎一模一样。CTU的梯形图你会看到一个标有“CTU”的方框。上面有“CU”端口接计数脉冲“R”端口接复位信号方框内写着“C0”计数器编号下方写着“PV”和设定值比如100。当CU前面的触点比如I0.0从断开到闭合就产生一个上升沿C0的当前值加1。当R前面的触点比如I0.1闭合C0被复位。当C0的当前值PVC0这个“线圈”本身就会“得电”你可以用另一个触点C0去驱动一个输出点Q0.0。CTD的梯形图方框标有“CTD”。“LD”端口接装载信号“CD”端口接减脉冲。上电后或LD有效时PV值比如50被装入C1的当前值。之后CD端的每个上升沿使当前值减1。减到0时C1的位状态置1。CTUD的梯形图方框标有“CTUD”。它有CU、CD、R三个输入端口。CU加CD减R复位。逻辑一目了然。画梯形图的关键是理解“能流”。信号从左边的母线流向右边的线圈途径的触点开关和功能框如计数器决定了最终结果。它非常适合描述逻辑关系清晰的顺序控制。3.2 语句表STL与执行堆栈的奥秘语句表更接近PLC底层执行逻辑理解它有助于你写出更紧凑、高效的程序尤其是在处理复杂逻辑时。STL操作依赖于一个叫做“堆栈”的数据结构你可以把它想象成一摞盘子最后放上去的栈顶最先被取用。对于计数器指令信号压栈的顺序至关重要它直接决定了哪个信号对应哪个功能端口。// 这是一个CTU的STL程序示例 LD I0.0 // 将I0.0的状态0或1装入栈顶这是计数脉冲CU LD I0.1 // 将I0.1的状态装入栈顶原来的栈顶I0.0被压到下一层这是复位信号R CTU C0, 100 // 执行CTU指令。它从栈顶开始取参数栈顶是RI0.1下一层是CUI0.0。 // 如果I0.11则复位C0。 // 如果I0.10则检查I0.0是否有上升沿有则C0当前值加1。 // PV设定值为100。顺序绝对不能错如果你写成LD I0.1LD I0.0CTU C0,100那就变成了I0.0是复位端I0.1是计数端整个逻辑就反了。CTD和CTUD同理必须严格按照LD CDLD LDCTD Cx, PV和LD CULD CDLD RCTUD Cx, PV的顺序来编写。这个“坑”我早期调试时没少掉进去程序死活不计数查了半天才发现是STL顺序写反了。4. 工业现场实战计数器应用案例精讲理论说得再多不如看几个我实际干过的项目。计数器用得好能解决很多看似复杂的问题。4.1 案例一流水线包装机产量统计与批次控制这是一个典型的CTU应用。一条饼干包装线每8包饼干装入一个小盒。我们用对射式光电传感器检测通过的饼干包。硬件连接光电传感器输出接PLC的I0.0作为CTU的CU输入。包装机完成一个空盒填充后有一个“盒满”信号接I0.1作为复位R输入。一个气缸推杆由Q0.0控制。程序设计使用CTU C10设定值PV8。I0.0每个上升沿一包饼干通过C10当前值加1。当C10当前值达到8C10位状态为1。用C10的常开触点驱动Q0.0并启动一个定时器比如延时0.5秒确保推到位。Q0.0动作的同时也触发一个内部位M0.0。用M0.0去复位C10或者直接用I0.1的“盒满”信号复位C10。进阶优化我们还需要统计总产量。可以再增加一个CTU C11PV设为一个很大的数如99999。用C10的位状态每满8包触发一次作为C11的计数脉冲。这样C11的当前值除以8就是总盒数C10的当前值显示当前盒内已装包数。一个简单的两级计数器就实现了产量和进度的双重监控。4.2 案例二立体车库车位计数与状态指示这是一个CTUD的完美应用场景。一个地下两层、地上三层的简易升降横移车库我们需要知道当前空闲车位总数。硬件连接每个车位都有一个车辆检测传感器地磁或超声波。车辆驶入传感器信号从0变1上升沿车辆驶出信号从1变0下降沿。但CTUD需要上升沿脉冲。我们需要用边沿检测指令将传感器的变化转换成脉冲。车辆驶入脉冲 - 连接到CTUD的CD端减计数因为车位被占用了空闲数减少。车辆驶出脉冲 - 连接到CTUD的CU端增计数因为车位空出来了空闲数增加。程序设计使用CTUD C30。假设总车位是50个系统初始化时上电或手动复位我们需要用MOV指令将50传送到C30的当前值寄存器如MOV 50, C30的当前值地址。注意CTUD本身没有LD端所以初始值需要用传送指令设置。每个车位的传感器信号经过边沿检测后分别汇总到CD和CU的总线上。C30的当前值实时显示空闲车位数。我们可以设置几个阈值当C30当前值5时点亮“车位紧张”的红色指示灯Q1.0当C30当前值0时点亮“车位已满”的红色指示灯并放下栏杆Q1.1。调试要点这里最大的挑战是信号防重。车辆进出时传感器可能会抖动产生多个脉冲。必须在程序里对每个传感器信号做滤波和单脉冲化处理确保一进一出只产生一个可靠的计数脉冲否则车位计数会乱套。4.3 案例三绕线机圈数控制与断线检测这个案例结合了CTD和高速计数器的概念虽然我们用普通计数器模拟一个思路。一台绕线机需要绕制固定圈数的线圈。传统CTD思路在转轴上安装一个接近开关每转一圈发出一个脉冲。使用CTD C40设定值PV需要绕制的圈数如1000。启动时用一个“开始绕线”信号I0.2作为LD信号将1000装入C40当前值。转轴每转一圈I0.3上升沿C40当前值减1。当C40当前值减到0位状态置1控制电机停止Q0.2断电。断线检测的巧用如果绕线过程中线材断裂转轴会空转。我们可以在程序中加入一个监控如果电机在运行Q0.21但在超过正常一圈所需的最大时间内用一个定时器T33设定没有收到计数脉冲I0.3无上升沿则判定为断线立即停机报警。这里计数器监控圈数是否在减少和定时器监控脉冲间隔是否超时联合工作实现了简单的故障诊断。高速场景考量如果绕线机转速非常快普通计数器可能会因为PLC扫描周期而漏计脉冲。这时就需要用到高速计数器HSC。高速计数器不依赖程序扫描由硬件直接处理脉冲频率可达几十甚至上百kHz。其编程思想和普通CTU/CTD类似但需要配置专门的硬件通道和中断事件这是更进阶的内容了。5. 编程技巧与避坑指南掌握了基本应用再来聊聊那些能让你的程序更稳健、更专业的技巧以及我踩过的那些“坑”。5.1 初始化与复位策略计数器不工作十有八九是初始化或复位逻辑没处理好。上电初始化一定要在PLC第一个扫描周期通常用SM0.1将计数器的当前值清零并将控制复位的内部中间继电器如M0.0复位。对于CTD可能还需要初始化装载预设值。复位信号设计复位信号R或LD要干净、可靠。避免使用长信号最好用脉冲。例如可以用“停止按钮”的上升沿去触发一个M位再用这个M位去复位计数器然后立即复位这个M位。这样可以防止复位信号一直有效导致计数器无法开始计数。多重复位在复杂的自动线中一个计数器可能需要在“急停”、“批次结束”、“故障复位”等多种情况下清零。确保这些复位信号是“或”的关系并且优先级高于计数信号。5.2 防止误计数与信号处理现场干扰和机械振动是计数不准的元凶。边沿检测是必须的除非你的信号源本身就是完美的脉冲如伺服驱动器的分频输出否则对于普通的行程开关、光电传感器一定要在程序里对输入点做上升沿P或下降沿N检测再用检测后的中间位去触发计数器。这是保证“一事一计”的铁律。软件滤波对于抖动严重的信号可以结合定时器做简单的软件滤波。例如检测到信号后启动一个50ms的定时器定时器时间到后如果信号依然有效才认为是一个有效信号。这能滤除大部分接触抖动。互锁逻辑对于CTUD要确保在机械结构上或程序逻辑上CU和CD信号不会在极短时间内同时发生比如一个物体同时触发两个传感器。如果无法避免需要在程序里加入互锁或者采用更可靠的编码器信号。5.3 当前值的读取与设定值修改读取当前值用于显示在触摸屏上显示剩余数量、当前产量需要读取计数器的当前值。不同PLC的寻址方式不同例如西门子S7-200中C0的当前值地址可能是HC0或C0取决于指令而三菱FX系列中C0的当前值存储在数据寄存器D中。一定要查手册搞清楚地址。动态修改设定值有时我们需要根据生产规格动态改变计数目标。可以将设定值PV设置为一个变量如VD100而不是常数K100。然后通过触摸屏或上位机修改VD100的值。但要特别注意对于CTU/CTUD修改PV值不会立即影响位状态位状态只在当前值达到或超过原PV值时才会置位。修改后可能需要等到当前值达到新的PV值才会触发。对于CTD修改PV值通常需要等到下一次LD信号有效时才会被装载到当前值。这些细节需要在工艺逻辑中考虑周全。5.4 计数器的“寿命”与扩展单个计数器的范围是有限的如-32768~32767。对于需要记录百万次甚至更多的大产量统计怎么办计数器级联这是最常用的方法。用低位计数器的位状态溢出信号作为高位计数器的计数脉冲。例如C0计满1000次后其位状态触发C1计1次。那么总次数 C1当前值 * 1000 C0当前值。这样理论上可以无限扩展。结合数据寄存器对于超长周期的统计如月度、年度产量可以在计数器计满一定次数后如每天零点将其当前值累加到一个32位或浮点数的数据寄存器中然后将计数器清零。这样数据寄存器中保存的就是历史累计值。玩转PLC计数器就像给自动化系统装上了“眼睛”和“记忆”。从简单的产品计数到复杂的双向定位、余量监控它都是最基础也最核心的功能之一。我刚开始也觉得就那么几条指令能有多难真正在嘈杂的现场面对闪烁的指示灯和不听话的设备才明白每一个上升沿的捕捉、每一个复位信号的时机都至关重要。多动手写程序多模拟仿真再到现场去调试和观察你会慢慢体会到这种“用逻辑驯服物理世界”的乐趣。记住好的程序不是一次写成的而是在不断的调试、优化和与设备“对话”中打磨出来的。当你看到生产线按照你设计的计数逻辑精准、流畅地运行时那种成就感就是技术带给我们的最大快乐。