
简介这份文档面向自动化、电气工程及机电类专业的课程设计与毕业设计围绕西门子S7-200系列PLC搭建自动售货机监控系统可作为PLC控制类课题的参考范例。压缩包内仅1个doc文件约490KB以Word排版呈现便于直接阅读、标注与二次编辑。内容从自动售货机的发展现状与方案论证切入梳理PLC的定义、硬件组成、循环扫描原理及编程语言并落实到软元件应用、定时器与数学运算指令、I/O点分配、顺序功能图和梯形图编写等环节文中还给出硬件组成与PLC外部接线图采用STEP7编译程序并以一次交易过程为例拆分为若干程序块逐一说明。目前已有183人学习适合需要理解SFC与LAD对应关系、快速搭建控制逻辑框架或查找接线与I/O分配思路的读者参考。1. 为什么自动售货机控制器选S7-200而不是单片机自动售货机常被当成玩具级项目很多人第一反应是用单片机做成本低、体积小。但真把机器推入有直流电机、电磁阀和市电线圈的柜体后5V单片机的IO很容易被反电动势和共模干扰打乱投币计数偶尔多一个少一个就是真金白银的资损。西门子S7-200这类小型PLC的输入点本身就是24V光耦隔离输出继电器能直接带负载接线和维护难度低得多。所以基于西门子S7-200系列PLC的自动售货机设计长期是电气实训和小批量定制的常见题目它把PLC编程入门最典型的几个坑压缩在一起传感器沿触发、金额累加、状态互锁、找零算法。下面按硬件点表、梯形图、仿真调试、找零排错的顺序把它落到能复现的每一步。2. S7-200自动售货机的I/O点表与电气选型2.1 按柜体功能划出输入输出点表自动售货机的功能拆开只有四块收钱、选货、出货、找零。点表就按这四块分先把硬币检测、按键、反馈这些输入定死再分配电机和出币机构的输出。常见做法是把硬币检测做成两个独立输入点因为1元和5角在机构上通常走不同通道直接给PLC两个干接点比在程序里靠脉宽区分更省事。地址符号类型说明I0.0Coin1DI1元硬币检测光电/接近开关常开I0.1Coin05DI5角硬币检测I0.2Sel1DI1号商品按键单价1.0元I0.3Sel2DI2号商品按键单价1.5元I0.4Sel3DI3号商品按键单价2.0元I0.5RefundDI退币按键I0.6MotorFbDI出货到位反馈I0.7ResetDI故障复位Q0.0M1DO1号商品出货电机Q0.1M2DO2号商品出货电机Q0.2M3DO3号商品出货电机Q0.3DispDO金额显示刷新使能Q0.4RefundC1DO找零1元出币Q0.5RefundC05DO找零5角出币Q0.6AlarmDO故障指示灯8个输入、7个输出CPU224 的 14DI/10DO 正好够用还留了余量。如果柜体后面要加第四种商品或者加纸币模块就得直接跳 CPU226 了选型时不要卡着点数刚刚好。这里用 AC/DC/RLY 型号输入走24VDC输出是继电器触点能直接带小功率直流电机和电磁铁。2.2 传感器与输出负载的接线要点输入侧硬币检测建议用 NPN 常开型接近开关或对射光电输出接到 PLC 的 I 端公共端 1M 按源型接法接到 24V 负极。光电式检测对硬币表面脏污比较敏感靠近出币口的机械杠杆式微动开关反而更耐用这是实训里反复被验证的经验。输出侧的关键在感性负载。出货电机、找零电磁铁都是感性负载继电器触点断开瞬间会产生反电动势轻则触点拉弧烧黑重则干扰到 PLC 本体。常见做法是在每个直流负载两端并联续流二极管交流负载并联 RC 吸收回路同时输出公共端 1L、2L 要分别接对应负载电源不要把不同电压等级的负载挂在一个公共端上。注意继电器输出的 PLC 不适合高频通断找零机构如果用电磁铁驱动节奏要留出机械动作时间别用毫秒级的脉冲去点它。2.3 用一个小脚本校验点表是否冲突点表一多最容易犯的错是地址重复分配或位号越界到编程时才发现两个设备抢同一个点。可以在写程序前用一段脚本把点表过一遍把冲突提前拦下来。# 校验 S7-200 I/O 点表地址重复、位号越界、点数是否超出 CPU 上限 io_table [ (I0.0, Coin1), (I0.1, Coin05), (I0.2, Sel1), (I0.3, Sel2), (I0.4, Sel3), (I0.5, Refund), (I0.6, MotorFb), (I0.7, Reset), (Q0.0, M1), (Q0.1, M2), (Q0.2, M3), (Q0.3, Disp), (Q0.4, RefundC1), (Q0.5, RefundC05), (Q0.6, Alarm), ] seen {} for addr, name in io_table: if addr in seen: # 同一地址给了两个设备 raise ValueError(f地址冲突: {addr} 同时属于 {seen[addr]} 和 {name}) seen[addr] name bit int(addr[2:]) # 取位号 if bit 7: # 位号只能是 0~7 raise ValueError(f位号越界: {addr}) in_cnt sum(1 for a in seen if a.startswith(I)) out_cnt sum(1 for a in seen if a.startswith(Q)) assert in_cnt 14 and out_cnt 10, 超出 CPU224 点数上限 print(f点表通过输入 {in_cnt} 点输出 {out_cnt} 点)这段逻辑很直白用字典记录已出现的地址重复即报错位号超过7说明写成了 I0.8 这种非法地址最后按 CPU224 的 14 进 10 出核对总数。参数上唯一需要改的是点数上限换 CPU226 就改成 24 进 16 出。把它跑一遍再进编程软件建符号表能省掉后期一大半为什么这个点不动的排查。3. 梯形图程序投币累加、选货出货与找零的S7-200实现3.1 金额寄存器和投币累加金额用一个字寄存器 VW100 存单位取0.1元那么1元硬币累加105角累加5商品价格就是10、15、20。用整数而不是浮点是因为 S7-200 的整数运算指令I、-I执行快、不会引入舍入误差金额这种场景不需要小数。投币检测必须用上升沿。硬币落下的瞬间检测开关会有一段几十毫秒的闭合如果直接用电平做加法一个硬币会被累加几十次。S7-200 的 EU 指令就是干这个的Network 1 // 1元硬币上升沿累加10即1.0元 LD I0.0 EU I 10, VW100 Network 2 // 5角硬币上升沿累加5即0.5元 LD I0.1 EU I 5, VW100 Network 3 // 金额封顶保护超过50元不再累加防止溢出 LD SM0.0 AW VW100, 500 MOVW 500, VW100逻辑说明Network 1、2 用 EU 抓取上升沿每次只加一次参数 10 和 5 就是硬币面额换算成0.1元的数值改面额只改这个常数。Network 3 是保险措施售货机正常不会有这么大金额但寄存器溢出后会变成负数导致比较判断全部失效封顶这一句花不了几个扫描周期。SM0.0 是常闭触点性质的特殊位用它做无条件执行的入口。3.2 选货判断与出货互锁选货动作要同时满足两个条件按下按键、余额大于等于该商品价格。另外还要互锁保证同一时刻只有一个出货电机在动否则多路同时出货会撞机构。Network 4 // 1号商品1.0元余额足够且其他电机未动 LD I0.2 EU AW VW100, 10 AN Q0.1 AN Q0.2 S Q0.0, 1 Network 5 // 2号商品1.5元 LD I0.3 EU AW VW100, 15 AN Q0.0 AN Q0.2 S Q0.1, 1 Network 6 // 出货到位反馈触发停电机并扣款 LD Q0.0 A I0.6 R Q0.0, 1 -I 10, VW100这里 AW 是字比较指令把 VW100 和价格常数比大小。AN Q0.1、AN Q0.2 构成互锁只要另外两路电机在运行本路就不会被置位。Network 6 用出货到位反馈 I0.6 来停电机并扣款扣款放在停电机这一步很关键——如果放在按键那一刻电机堵转没出货也得扣钱用户会投诉放在到位反馈后只有真出货了才结算。提示I0.6 到位反馈如果用的是行程开关建议在程序里加 0.2s 滤波机械触点抖动会让 R 指令执行两次扣两次款。3.3 找零输出的节拍控制找零不能一直输出高电平否则电磁铁会长时间吸合烧线圈。常见做法是用 S7-200 自带的 1Hz 时钟位 SM0.5 做节拍每拍出一次币同时用下降沿扣减余额保证一拍只扣一次。Network 7 // 退币按键置位找零标志 LD I0.5 EU S M0.0, 1 Network 8 // 余额不小于1元时按 SM0.5 节拍驱动1元出币 LD M0.0 AW VW100, 10 A SM0.5 Q0.4 Network 9 // 在 Q0.4 的下降沿扣减避免同一拍重复扣 LD Q0.4 ED -I 10, VW100SM0.5 是 0.5秒高、0.5秒低的周期位驱动出币机构刚好够机械动作。Network 9 用 ED 下降沿抓 Q0.4 由高变低的那一刻扣款参数 10 对应1元。5角找零同法处理阈值换成5。全部找完后用一个清零网络把 M0.0、Q0.4、Q0.5 复位退出找零状态。4. 用S7-200仿真软件跑通售货流程与强制变量调试4.1 从Micro/WIN到仿真软件的程序准备S7-200 的仿真软件第三方出的那类只认语句表梯形图要先在 STEP 7-Micro/WIN 里切换成 STL 视图再导出。整条链路是Micro/WIN 里写完 LAD编译通过用查看 STL确认没有语法错再把程序文件加载进仿真软件CPU 型号选 CPU224。仿真软件启动后要做的第一件事是确认输入点默认状态。很多仿真版本上电后 I 点默认是高电平而实际柜体里常开触点是低电平有效两边逻辑相反的话程序一跑就会立刻累加金额。仿真前把输入点全部拉低再按真实电平去强制这是最容易被忽略的一步。4.2 强制I点和监视寄存器的验证顺序调试不要一上来就全流程跑按投币—判断—出货—找零四条独立用例逐个过每条用例只看一个结果。用例操作期望结果1强制 I0.0 通断一次VW100 由0变102在 VW10010 时强制 I0.2Q0.0 置位且 Q0.1、Q0.2 保持03强制 I0.6 一次Q0.0 复位VW100 减为04先投2元再强制 I0.5Q0.4 按1Hz闪烁VW100 逐步归零用例2是验证互锁是否生效用例4是验证找零节拍。如果手动的通断太慢可以在程序里临时加一个脉冲发生网络用 SM0.5 自动模拟投币Network 20 // 仅仿真调试用SM0.5 每拍累加1元正式运行前必须删除 LD SM0.5 EU I 10, VW100这个网络的作用是让金额自己涨上去方便快速观察选货判断和找零逻辑。参数 10 控制累加速度想慢一点就换成 I 5, VW100。调试完成后一定要把它删掉或改成 M0.0 常闭条件否则真实机器上会因为程序自己加钱而失控。5. 找零状态机与售货机常见故障的定位技巧前面用置位复位位写的逻辑功能点少时够用一旦加上第四种商品、纸币模块和故障退款M 位会互相踩出问题时很难判断当前到底处于哪个阶段。更省心的写法是把主流程做成状态机用一个字节 M10 存当前状态。状态值含义进入条件退出条件0待机上电或复位首次投币1收款任意硬币输入按下选货键2出货余额足够且按键到位反馈 I0.63找零退币键或结算后有余款余额归零状态转移用比较指令写在开头每个状态里只处理自己那一段逻辑与状态无关的 M 位一律不参与判断。这样做的好处是排错时只看 M10 的值就能定位比在一堆互锁里追信号快得多。用状态机重写时投币累加可以保持在状态1和状态2里都允许其他状态一律拒绝投币天然就把出货过程中又投币这种边界情况堵住了。剩下的高频故障集中在物理层和沿触发这两个点上遇到时按这个顺序查输出点有动作但电机不转先量继电器的 1L、2L 公共端是否接对了负载电源再查负载回路的续流二极管是不是装反。继电器的咔哒声只能说明触点动作不代表回路通。金额自己乱跳九成是硬币传感器抖动或电平逻辑反了。在输入后串一个 200ms 的 TON 定时器再取上升沿等于给信号做硬件级的消抖。找零停不下来检查扣减那句是不是挂在电平上而不是边沿上用 ED 抓出币输出的下降沿扣款才能保证一拍拍一次不会在同一个高电平周期里反复减。最后补一个实用技巧把 VW100 的当前值实时映射到一个输出字 QW0 上用仿真软件或触摸屏直接看数值变化比盯着几十个 M 位猜逻辑要直观得多。金额、状态字、故障码各占一个字节调试口的观察窗口一眼就能扫完这套映射留着上机也照样有用。本文还有配套的精品资源点击获取