PLC停车场仿真项目实战:梯形图设计、计数逻辑与联调全记录 一个停车场PLC仿真项目听起来不算复杂等你真把16个车位的进出逻辑、栏杆时序、满位判断全部码进梯形图才会体会到什么叫“麻雀虽五脏俱全”。入口一个栏杆、出口一个栏杆、中间一排车位灯看着简单背后是计数器、顺序控制、互锁、掉电保持这一整套工控基本功。这篇就把我实际做这个仿真项目的完整过程拉出来聊聊从需求拆解、I/O规划、梯形图实现到仿真联调、踩坑记录尽量说透。这个项目特别适合两类人一类是刚学PLC、想找个完整小项目练手的初学者另一类是带学生做课程设计的老师。把重点放在控制逻辑本身不牵扯复杂设备却能覆盖PLC应用的高频核心点加减计数、边沿检测、置位复位、互锁、满位处理、仿真联调。搞懂这个之后做立体车库、仓储物流的仓位管理思路都是相通的。1. 项目概述与需求拆解1.1 16个车位的控制场景难在哪里先还原一下现场。假设某停车场共有16个车位入口处有地感线圈检测来车内部有第二个地感确认车辆驶入出口对称布置。栏杆机带上升/下降两个方向的电机控制和上下限位开关入口外还有一个空余车位显示屏。这个场景的控制任务可以拆成四件事。第一准确记录当前停车场内的车辆数入场加一出场减一。第二控制入口栏杆只在“场内未满”且“有车等待”时抬杆放行。第三满位时给出信号禁止入口再放车。第四把车位数实时显示出来给到外部屏或上位机。难点不在某个单独的点而在它们的组合。初学者最容易漏的是满位之后必须把“满位信号”串进抬杆启动回路否则即使计数已经到16只要有车压上入口地感栏杆还会抬——这在真实停车场是事故。计数环节要防抖动、防重复触发还要考虑掉电后数据保持。栏杆动作要防同时上升和下降这种输出冲突。这些都是实战里才会遇到的细节。1.2 为什么“计数逻辑”是停车场控制的主线整个系统表面上是控制栏杆内里真正的主线只有一条车位数。16个车位本质上就是用一个有上下限的加减计数器配合入口、出口两组传感器来维护一个“实时余位值”。这里要解释一个关键选型为什么用“可逆计数器”加比较指令而不是给16个车位各做一个占用位答案是成本和逻辑复杂度。你把16个车位拆成16个独立的布点儿来管理逻辑上当然可行但程序会膨胀而且“满位”的判断要从16个状态全部取反才能得出来非常啰嗦。用一个字寄存器或者计数器的数值和常数16比较一次就出来满位信号效率高得多。实际应用中我建议用“字存储区加加减法指令”而不是专用的计数器指令。原因有两个一是计数器指令在不同品牌PLC上的复位、保持行为差异大二是加计数、减计数过程中间可以随时插入比较和互锁逻辑更好处理。用一个掉电保持的字地址执行加一和减一操作满位判断就是一句比较指令的事。1.3 仿真方案的选取用什么环境搭这个系统做仿真选环境是个前置问题。我当时用的是最常见的路子PLC编程软件自带的仿真器配合一组虚拟按钮和指示灯来模拟传感器和执行器。也就是把输入点用鼠标点按模拟触发输出点用程序里的状态表监视。有条件的话再加一个组态软件做HMI画面把车位、栏杆、余位数都画出来看起来更直观。如果只验证PLC逻辑厂商自带仿真器足够。如果你后面想做比赛演示或者教学展示建议HMI联合仿真。逻辑不变只是显示层不同。我这次以软件仿真为主HMI画面辅助显示车位数和车位占用状态。该方案的优点是零硬件成本、可反复做边界测试缺点是传感器信号要用人工触发来模拟测试并发场景的时候需要手速够快或者用脚本辅助置位。2. 控制方案与I/O规划2.1 PLC选型CPU点数怎么算有人觉得停车场控制能有多复杂随便选个小PLC就行。这句话对一半但选型不是看程序量而是看I/O点数和扩展需求。先盘点一下这个项目需要的输入输出点。输入入口外部地感、入口内部地感、出口外部地感、出口内部地感、入口栏杆上限位、入口栏杆下限位、出口栏杆上限位、出口栏杆下限位再加上一个手动自动切换和急停。满打满算10个数字量输入。输出入口栏杆上升、入口栏杆下降、出口栏杆上升、出口栏杆下降、入口绿灯、入口红灯、满位指示灯再算上给外部显示屏的数据输出或者给HMI的状态位大约7到8个数字量输出。这样算下来选一款自带14点DI和10点DO左右的CPU就够了完全不用扩展模块。如果你的车位数量更多比如扩展到32个、64个车位就需要考虑带以太网接口的型号方便上位机刷数据。做这个16车位仿真项目入门级CPU在性能上绰绰有余。2.2 传感器与执行器的仿真替代方案真实停车场里地感线圈靠车辆底盘金属切割磁力线触发信号。到了仿真环境里我们不可能真造一辆车来压地感所以要用可操作的虚拟信号来代替。我的做法是给每个传感器分配一个按钮或开关变量在仿真器里通过强制或点击来手动触发。需要注意一个问题真实地感信号是持续存在的车辆停在上面期间信号一直为ON车辆开走才变OFF。而仿真时如果用普通的置位按钮会出现“你松开按钮信号就没了”的情况。这不符合真实逻辑会导致你在调试栏杆时序时对不上。解决办法是给模拟信号写一小段“自锁逻辑”让信号保持直到车辆通过后才复位。说白了仿真也要尽量贴合现场的信号行为否则你的逻辑在仿真里跑通了到了现场照样出问题。我在3.2节会把这段自锁逻辑写出来。2.3 I/O分配表从输入到输出的全景规划动手写程序之前先做I/O分配。这一步决定后面程序的可读性和扩展性也避免调试时到处找地址。表里的地址我用的是通用格式不同品牌在助记符上略有差异但思路通用。地址功能说明信号性质I0.0入口外部地感检测来车常开I0.1入口内部地感确认驶入常开I0.2出口外部地感检测来车常开I0.3出口内部地感确认驶出常开I0.4入口栏杆上限位常开水平到位接通I0.5入口栏杆下限位常开垂直到位接通I0.6出口栏杆上限位常开水平到位接通I0.7出口栏杆下限位常开垂直到位接通I1.0手动/自动切换OFF为自动I1.1急停常闭断开有效输出这边入口栏杆上升、入口栏杆下降、出口上升、出口下降、入口绿灯、入口红灯、满位指示灯、蜂鸣器。数据区用MW10存放当前车位数M0.0作为满位标志这个在HMI上直接显示比用数码管驱动再译码省事得多。关于地址规划有个心得输入输出点尽量从0开始连续排中间不跳数据区要区分普通变量和掉电保持变量。MW10建议放进保持区这样PLC重启后当前车位数还在不至于出现“明明停了半场车一断电重启计数器归零”的尴尬。3. 核心程序设计与梯形图实现3.1 加减计数器的设计怎么避免多计漏计计数这块是整个程序最重要的地基。入口车辆进入时加一出口车辆驶出时减一听起来再简单不过但实际写起来有讲究。首先触发的边沿选择必须用上升沿。如果你直接用常开触点去驱动加一指令车辆传感器信号保持的时间内CPU会反复扫描执行加一一次扫描加一次结果就是来一辆车计了十几辆。这是初学者最经典的错误。加上升沿指令后只有信号从OFF变成ON的那一瞬间执行一次加一。其次加减方向互斥。某一种极端情况下入口和出口的传感器同时被触发如果不做互锁处理可能出现同一扫描周期内既加一又减一计数值原地不动但车实际已经变了的情况。停车场管理通常以“先进后出”为原则出现并发时优先处理出口避免只进不出的情况。我用一个方向互锁变量来保证同一时刻只执行一个方向的计数操作。第三上下限钳位。车位总数是16计数器不能无限往上加最低也不能减到负数。所以加一之前先判断“当前值小于16”减一之前先判断“当前值大于0”满足条件才执行。这段判断同时承担了满位信号的核心逻辑。我把核心计数程序用通用助记符描述方便大家对照自己的PLC型号调整// 入口加一 LD 入口内部地感信号 EU(上升沿) AND 当前车位值小于16 AND 出口计数方向未激活 INC 当前车位值 // 出口减一 LD 出口内部地感信号 EU(上升沿) AND 当前车位值大于0 AND 入口计数方向未激活 DEC 当前车位值然后满位判断就一行LDW 当前车位值 I 16 OUT 满位标志这里再强调一次计数必须放在“车辆已经完全进入”之后触发。入口内部地感的作用就是确认车辆已经越过栏杆、车身完全进入场内这时候加一才准确。你用地感信号去触发计数器安装位置和触发时序要想清楚。3.2 入口栏杆机的动作时序栏杆机控制是这个项目里最体现顺序控制基本功的地方。它的完整动作时序是检测到入口外部有车等待并且场内未满系统抬杆栏杆到水平上限位后停止车辆越过栏杆进入场内触发内部地感车辆完全通过内部地感由ON变OFF延时两秒后落杆落杆到垂直下限位后停止。这段时序如果用一堆定时器、触点硬凑程序会绕到你自己都看不懂。正确的做法是用置位、复位指令配合传感器状态做状态机或者直接上顺序功能图编程。我用的是置位复位思路原因是直观、单步调试容易。关键在抬杆保持逻辑。栏杆到达上限位后必须先停止上升输出否则电机一直带着跑机械结构会损坏。停止上升用上限位信号去复位上升输出。抬杆状态要保持住不能一停就掉下来所以用一个“入口栏杆打开”的中间变量锁存。落杆的触发条件要特别小心。很多人写成“车一进入就落杆”这在实际停车场是防砸车事故的经典隐患。车辆进入过程中车尾可能还没完全越过栏杆这时候落杆会砸车顶。正确做法是等入口内部地感从ON变OFF也就是车身完全驶离内部检测区后再延时落杆。这个细节直接关系到系统是否可靠。落杆防砸的逻辑也不能少。落杆过程中如果内部地感再次被触发说明有人或车停在栏杆下方要立刻停止落杆并重新抬杆。这一段我单独写了一个联锁优先级高于一切。3.3 满位信号与车位状态显示满位信号是停车场系统里跟外部交互最直接的东西。它在停车场入口处体现为“红灯亮、绿灯灭、信息屏显示余位0”。在控制逻辑里满位信号要做的不仅仅是显示更关键的是禁止入口抬杆。所以抬杆的启动条件必须串入“未满位”这个常闭信号。这句逻辑看起来是常识但在实际调试中我见过太多项目把它漏掉——因为联调时往往是从有余位的情况下开始测满位场景容易一带而过等到真满位才发现栏杆照抬。我建议在满足全部条件之前先用仿真器强制把计数改为16专门验证这个场景。车位状态显示我用的是HMI上的16个矩形加一个数字显示。每个矩形对应一个车位的状态空位绿色占用红色。这个方案用到的不是16个独立位而是用一个字存储器的16个比特位每一位代表一个车位的占用状态。入场时找出第一个空闲的位置为1出场时把对应位清0。配合HMI的位状态显示功能不需要写很多程序画面上就能直观看到哪几个车位被占用。如果你手头没有HMI打算用数码管显示剩余车位数量那就需要做BCD转换。16这个数比较特殊——二进制占5位但用数码管现实余位数常用两位十进制需要把当前计数值拆成十位和个位。这个加一点额外的拆字逻辑不算复杂但属于“看着不起眼、忘记处理就显示乱码”的坑。4. 仿真联调与实操记录4.1 仿真环境的搭建步骤仿真联调是整个项目里最花时间的阶段也是最容易出成果的阶段。我把这个过程拆成四步。第一步把程序完整下载到PLC仿真器里先做空载检查。所有输入信号全部为OFF的条件下确认所有输出保持OFF当前车位数显示0入口绿灯亮栏杆处于垂直下限位。这一遍是排除接线和地址错位问题的最快手段。第二步逐个强制输入信号验证每个输入点对应的程序分支是否生效。比如强制入口外部地感ON观察是否触发抬杆输出。这个阶段不要急于组合测试先把单点和程序对上了再说。常见问题是在这一步发现地址写错比如上下限位颠倒了一抬杆就触发上限位导致永远抬不起来。第三步按正常流程做一次完整进出场模拟车辆到达→抬杆→车辆进入→计数加一→落杆。然后从出口再模拟一次出场确认计数减一。这一步跑通了系统的基本控制链就闭环了。第四步做边界和异常测试。连续入场到第16辆确认满位信号在正确时机触发第17辆车不来栏杆不再抬起再模拟出场到第1辆确认未满位信号恢复。还要测试急停、手动自动切换、并发进出等场景。在仿真器里模拟这些信号时我强烈建议不要直接在变量表里反复置位复位而是用一段“模拟信号发生器”程序把传感器信号做成有触发沿的中间变量再用按钮去置位这个变量。这样更接近真实地感的ON/OFF行为后续移植到实物调试时程序不用大改。4.2 关键程序的逐一验证程序写完后真正的功夫在验证。我按功能模块逐项检查每个模块都有对应的验证用例和预期结果。入口模块验证用例外部地感ON时绿灯亮、抬杆启动外部地感ON但满位标志有效时红灯亮、抬杆不启动抬杆到位后上升输出OFF内部地感由ON变OFF后两秒落杆动作到位后停止。这个模块最容易出问题的点是满位标志状态下外部地感ON红灯要亮抬杆不许动。为了确保这一点我在仿真器里专门将MW10强制为16再测而不是依赖测试过程中自然填满车位。计数模块验证用例来回跑几十次入场出场循环每完成一次循环确认MW10的数值正确且没有因为重复扫描多计数。我习惯在MW10后面挂一个比较器每次数值变化时用状态位或HMI弹窗提示这样多计漏计一眼就能发现。输出模块验证用例所有输出能否被正确驱动和复位尤其是栏杆上升和下降两个输出之间是否存在同时ON的隐患。我特意做了互锁检查上升为ON时下降即使被强制也无法接通。4.3 仿真与HMI联合调试记录如果有HMI画面联调阶段会更有意思。我在HMI上画了一个简易停车场俯视图一条入口车道、一条出口车道车库区域里摆了16个车位矩形块入口处放一个余位数显示栏杆用一个线条的旋转角度来表示。HMI联合调试的核心是变量同步。PLC侧把车位数、栏杆状态、满位标志、16个车位占用位全部公开为通信变量HMI侧按地址一一绑定。这一步最容易出问题的是地址类型不一致比如PLC里是无符号整数HMI里配置成实数画面上直接显示乱码。建议联调前先做变量一致性检查表逐项勾对。联合调试中我着重测了“余位数字刷新”的及时性。入场计数瞬间画面上的余位数要跟着变满位瞬间字体颜色从绿色变红色。如果画面刷新慢了多半是通信周期或变量更新周期设置过长把刷新周期往下调就行。另外手动自动切换时HMI上应该同步显示当前模式这个信号我用了一个中间位直接给到HMI。5. 常见问题与排查技巧实录调试过程中踩过的坑我全记下来了有些是导师指点的有些是自己摸索出来的。整理成速查表方便后面复用。故障现象根因分析排查方法车辆多次压地感计数重复累加缺少边沿检测CPU每个扫描周期都在加一给计数触发信号加上升沿指令满位后入口栏杆仍能抬起抬杆启动回路没有串联满位常闭测试用例中加入强制MW10为16的场景抬杆到位后电机不停上限位信号没有及时复位上升输出检查上限位地址映射和状态落杆砸车不停止缺少落杆过程中的防砸联锁落杆时持续监视内部地感状态掉电重启后车位数清零计数区未设置为掉电保持调整数据区属性为保持出入口同时触发时计数错乱加减计数无互锁增加方向互锁变量保证单向执行数码管显示乱码车位数未转BCD或拆字逻辑缺失检查显示驱动段加拆字程序HMI上余位数刷新慢通信周期配置过长调短刷新周期冗余扫描这里面最值得展开的是“重复计数”和“掉电保持”两个问题。重复计数不用多说上面已经解释过根源在于扫描周期和边沿的认知偏差。掉电保持则是一个更隐蔽的问题。仿真环境里你可能完全不觉得因为仿真器断电重启后内存变量往往会按照初始值重新分配看起来没问题。但到了真实现场一个停车场运营中突然停电PLC重启后如果计数值清零了入场口不知道场内有多少车满位逻辑完全失效会造成严重的车辆管理混乱。因此计数区域必须配置为掉电保持或者做上电恢复时的自动重新初始化逻辑。另一个容易被忽略的是“手动模式”的优先级。我在程序里定义了手动模式时自动计数和抬杆逻辑全部旁路直接由人工按钮控制栏杆。这个看似多余实际真有需求比如设备检修、应急疏导时自动逻辑要能一键让位。调试中要专门验证从自动切手动、再切回自动的过程中中间变量不会残留错误状态。最后一个建议做完这个仿真别急着删项目。在现有程序基础上扩展一个“预约取车”功能或者“特殊车辆优先通行”逻辑对理解PLC的复杂项目开发模式会有很大帮助。我自己的体会是16车位的仿真虽然规模不大但把它从需求一步步做到仿真通过比翻十遍教材都管用很多现场经验只能从这种完整的项目闭环里获得。另外说个细节技巧仿真调试时把所有输入信号用单独一段“仿真驱动程序”控制在变量表里做一个集中控制的“按钮区”每一个传感器对应一个置位按钮信号触发后不会因为扫描周期闪没。你后面如果换成实物接线只需把这层仿真驱动程序删掉把传感器直接接到输入点上就行主逻辑完全不用改。这个习惯能省下大量来回改程序的时间。