
1. 项目概述为什么要用两种语言写步进电机程序西门子S7-1200配合博途TIA Portal控制步进电机是当下小型自动化设备里最常见的组合之一。不管是小型贴标机、送料机构、三轴平台还是学校里的实训装置步进电机凭借成本低、控制简单、开环也能有不错精度的特点占了相当大的市场份额。而S7-1200作为西门子小型PLC的主力本体就能发高速脉冲不需要额外加定位模块这本身就是很大的成本优势。我这次要聊的程序项目是一个典型的单轴步进电机位置控制系统触摸屏设定目标位置和速度PLC输出脉冲和方向信号步进驱动器带着电机转丝杆或同步带把旋转运动变成直线位移。程序里同时用了LAD梯形图和SCL结构化控制语言两种语言LAD管逻辑联锁、急停、限位这些“硬逻辑”SCL管位置计算、运行状态切换、参数校验这些“软逻辑”。这个搭配方式在真实项目里非常普遍也值得展开讲讲。这篇文章适合刚把S7-1200基本指令学完、想往运动控制方向走的新手也适合那些一直在用纯LAD写PLC程序、想尝试SCL但不知道怎么下手的朋友。我会把程序结构、核心块怎么搭、两种语言分别承担什么角色、调试时容易踩的坑全部拆开来讲。你看着这段文字就像拿着一张完整的图纸加上旁边站着一个老工程师在给你讲“这里为什么要这样写”一样。1.1 顺起逆停为什么值得单独提热词里有一个“西门子S7-1200顺起逆停”这是很多设备的基本需求正转启动、反转启动、停止三个按钮控制电机按顺序动作或者要求在运行过程中不能直接反向切换必须先停下来才能反方向走。这个逻辑用梯形图写就是起保停电路的变体非常简单但放到步进电机场景里它不只是“正转反转”这么简单还牵扯到方向信号何时切换、脉冲输出是否已经停止、电机是否已经停稳。如果方向信号和脉冲信号同时在变化步进驱动器可能丢步甚至产生异响。SCL里写状态机LAD里做信号互锁就能把这个问题处理得很干净。1.2 整篇文章你会得到什么读完这篇文章你能掌握S7-1200加步进驱动器的硬件接线思路以及ENA这类使能信号到底该怎么接。Portal里组态轴工艺对象时几个关键参数的来龙去脉。用LAD搭建起保停、限位、急停、报警逻辑的套路。用SCL实现位置计算、自动运行状态机和顺起逆停控制逻辑的完整思路。实际调试时频率、加减速时间、脉冲当量的换算方法。常见故障比如电机不转、抖动、丢步、方向反了排查顺序是什么。2. 系统方案与硬件配置2.1 项目硬件清单以一套典型的单轴工作台为例硬件配置如下PLC西门子S7-1200 CPU 1214C DC/DC/DC固件版本V4.5以上配套博途V17或V18。步进驱动器雷赛DM542或同级别的两相混合式步进驱动器拨码电流设成电机额定电流的1.2倍左右。步进电机57系列两相步进电机保持转矩2.0N·m上下。触摸屏西门子精简系列KTP700 Basic用以太网和PLC通信。限位开关常闭型NPN三线式接近开关两个分别装在正负极限位置。原点开关常开型NPN接近开关一个装在机械原点位置。急停按钮常闭触点接到PLC的数字量输入点。这里要特别说一句PLC选DC/DC/DC型号意思就是电源直流、输入直流、输出晶体管直流。步进电机需要脉冲输出必须选晶体管输出型继电器输出的CPU发不了高速脉冲这一点新手最容易搞错。2.2 步进驱动器的接线细节步进驱动器上的PUL、PUL-是脉冲信号输入DIR、DIR-是方向信号输入ENA、ENA-是使能信号输入。S7-1200的晶体管输出是24V高电平有效所以接线时PLC的Q0.0接到驱动器PULPUL-接到0V。PLC的Q0.1接到DIRDIR-接到0V。PLC的Q0.2接到ENAENA-接0V。这种接法是共阳接法也就是把驱动器的正端接PLC输出负端统一拉低。需要注意S7-1200晶体管输出点本身有短路保护但驱动器的脉冲输入口内部一般有光耦电流大约在10mA到20mA之间必要时串一个2kΩ左右的限流电阻。不过现在多数驱动器输入阻抗已经匹配好了直接接也没问题保险起见还是看一下驱动器的说明书。ENA使能信号这里多说一句。很多人调试时电机嗡嗡响但不转首先怀疑程序其实大概率是ENA一直处于使能状态但脉冲没来或者ENA信号接反导致驱动器一直脱机。使能信号的含义要看清说明书有的驱动器是高电平使能有的是低电平使能。接反了就是你给它脉冲它根本不响应。2.3 博途组态里的关键设置在博途里新建项目添加S7-1200 CPU之后需要做的第一件事不是写程序而是组态“轴工艺对象”。路径是在左侧树形结构的“运动控制”文件夹里双击“新增对象”选择“轴”命名比如为Axis_1。轴组态里最关键的几个参数驱动器类型选“脉冲”因为S7-1200本体输出就是脉冲信号。脉冲信号选择PTOPulse Train Output即脉冲串输出。方向输出选择选择“双向”把Q0.0定义为脉冲输出Q0.1定义为方向输出。硬件输出地址脉冲输出是Q0.0方向输出是Q0.1这个要跟组态的硬件地址一致轴工艺对象会强制占用这两个输出点。电机每转脉冲数这个要根据驱动器的细分设置来填。比如驱动器拨码设成了3200脉冲/转就填3200。负载每转位移量如果电机通过同步带轮直连丝杆丝杆导程为10mm就填10.0单位mm。这就是脉冲当量计算的依据。这些参数不填对后面所有运动指令的坐标单位就全是错的。比如你填错了每转脉冲数指令目标是100mm实际可能走50mm或200mm。2.4 LAD和SCL在这个项目里怎么分工这个项目我用了两种语言不是炫技而是功能特性决定的LAD适合做“条件-动作”这种即时性强、需要一眼看明白的逻辑。急停触发马上切断使能限位触发马上停止脉冲输出这些都是安全相关的硬逻辑必须用LAD写因为梯形图的执行方式直观别人打开程序一看到常闭触点串在回路里马上就能理解保护原理。SCL适合做“算法-状态”这种流程性强、计算量大的逻辑。比如位置比较、速度规划、多段流程状态切换、数据校验这些用梯形图写会非常啰嗦动辄几十个网络看得人头大。但SCL可以用IF ELSE、CASE语句写状态机代码量小、逻辑清晰修改也方便。所以我的做法是OB1里调用一个FC做SCL自动控制逻辑再调用一个FB做LAD信号联锁逻辑两者通过全局数据块交互。自动逻辑算出来“应该给多少脉冲、什么方向”联锁逻辑再根据急停、限位、驱动报警这些信号做最终裁决决定脉冲是否真的输出。3. LAD程序解析硬逻辑是安全的最后一道防线3.1 起保停与顺起逆停的LAD实现先看最基础的启动和停止。在LAD里写一个网络正转启动按钮I0.0反转启动按钮I0.1停止按钮I0.2输出点Q0.4控制方向信号。正转和反转本质上都是让轴运动区别只是方向输出点的电平。为了防止误操作直接切换方向我在程序里做了一个互锁正转启动时先判断反转输出没有置位反转启动时判断正转输出没有置位。同时PLC内部用一个“运行中”标志位M0.0来表示轴是否正在运动在RUN状态下不允许切换方向必须按下停止后电机停稳才能换向。梯形图写出来的效果就是I0.0正转按钮按下且M0.0未激活且M0.1反转运行未激活则M0.0置位为正转运行。I0.1反转按钮按下且M0.0未激活且M0.2正转运行未激活则M0.0置位为反转运行。I0.2停止按钮按下复位M0.0、M0.1、M0.2。这套逻辑的精髓在于电机正在正转的时候你再按反转按钮PLC不会马上翻转方向信号而是忽略这次操作。这个“忽略”不是逻辑错误而是保护。因为步进电机带着负载高速运转的时候如果突然反转负载的惯性会瞬间冲击机械结构轻则丢步重则撞坏限位或丝杆螺母。3.2 限位与急停保护必须硬接线到输入限位开关我用了常闭型接近开关接入I0.3正限位、I0.4负限位。为什么用常闭而不是常开因为常闭开关在正常状态下一直有信号一旦线断了或者开关坏了信号消失程序能立刻判断出“限位异常”。而常开开关如果没有触发你根本不知道它是正常的还是坏的在安全保护上这是致命的缺陷。LAD里把正限位和负限位信号串在输出回路上当正限位I0.3被触发信号消失正转方向的运动指令立即被切断。当负限位I0.4被触发信号消失反转方向的运动指令立即被切断。同时通过一个置位指令M10.0记录“限位报警”触摸屏上弹出报警信息操作人员清除报警后并且手动把轴移到安全区域才能复位。急停按钮接I0.5常闭触点。急停按下时信号丢失LAD里用这个信号的常闭触点和所有运动指令串联确保任何状态下急停都能立即切断脉冲输出。S7-1200的MC_Power指令有StopMode参数可以设成立即停止或者斜坡停止急停这里必须用立即停止也就是“EmergencyStop”。普通的停止按钮可以斜坡停止让电机平滑减速但急停要的是快、是停止而不是保护机械。3.3 驱动报警与报警汇总步进驱动器一般会输出一个ALM报警信号集电极开路输出正常时导通报警时断开。把这个信号接到PLC的I0.6同样用常闭逻辑。只要驱动器报错比如过流、过温、欠压LAD立刻禁止所有输出动作并且把报警状态传给触摸屏。在实际项目里驱动报警还有一个容易被忽略的细节驱动器报警恢复后必须给一个复位脉冲才能清除故障。如果驱动器本身没有自动恢复功能就需要在触摸屏上加一个“复位驱动”按钮PLC检测到这个按钮按下后输出一个短暂的低电平到驱动器的RST复位端。这个RST信号一般跟ENA共用一根线或者是一个独立的复位输入具体看驱动器型号。很多项目调试半天发现驱动器一直报警其实只是没有给复位信号。4. SCL程序解析让轴按预定的流程聪明地跑4.1 脉冲当量与位置换算SCL里第一步要解决的是位置换算的问题。我在全局数据块里定义了几个变量目标位置TargetPos单位mm当前实际位置ActualPos单位mm电机每转脉冲数PulsePerRev从轴工艺对象里读出来负载每转位移量LeadScrewLead单位mm。脉冲当量的计算公式脉冲当量 负载每转位移量 / 每转脉冲数比如丝杆导程10mm驱动器细分3200脉冲/转那每个脉冲对应的位移量就是10 / 3200 0.003125mm。如果触摸屏上设定目标位置为100mmPLC需要发出的脉冲数就是100 / 0.003125 32000个。但SCL里一般不直接算脉冲数而是把坐标值直接给运动控制指令。S7-1200的运动控制指令用坐标单位来定位它内部会自动完成脉冲数换算。前提是轴工艺对象里的参数必须填对否则你给的是100mm它实际可能走成别的数。我在SCL里写了一个FC把触摸屏设定值转换成内部浮点坐标并且做了范围检查目标位置必须在正负限位对应的坐标范围内超出范围直接拒绝启动同时把“参数错误”的报警位置位。4.2 自动运行状态机的SCL实现自动运行部分我用的CASE语句状态机分为状态0空闲。状态10回原点。状态20运行到目标位置。状态30到位延时。状态40等待下一次指令。CASE语句在SCL里的可读性比梯形图高得多。比如CASE #runState OF 0: // 空闲 IF #startAuto THEN #runState : 10; END_IF; 10: // 回原点 #axisStatus : MC_Home(Axis : Axis_1); IF #axisStatus.Done THEN #runState : 20; END_IF; 20: // 移动到目标位置 #moveABS : MC_MoveAbsolute(Axis : Axis_1, Execute : TRUE, Position : #targetPos, Velocity : #targetSpeed, Acceleration : #accel, Deceleration : #decel); IF #moveABS.Done THEN #runState : 30; END_IF; 30: // 到位延时 #delayTimer(IN : TRUE, PT : T#2S); IF #delayTimer.Q THEN #runState : 40; END_IF; 40: // 完成 #finishFlag : TRUE; END_CASE;实际编程时会有更多细节比如每个状态进入时要复位输出、出错时要跳转到故障状态、急停信号要优先于状态机的任何状态判断。这种写法比一堆置位复位线圈在梯形图里绕来绕去要清晰得多。4.3 手动点动与自动模式的切换手动点动用的是MC_MoveJog指令它可以连续运行按住走、松开停。方向由参数JogForward或JogReverse控制速度由JogVelocity设定。SCL里写手动逻辑的伪结构IF #manualMode THEN // 操作员按住正转点动按钮 IF #jogFwdBtn THEN #jogExecute : TRUE; #jogDirection : 1; // 正向 ELSIF #jogRevBtn THEN #jogExecute : TRUE; #jogDirection : 2; // 反向 ELSE #jogExecute : FALSE; END_IF; END_IF;这里必须考虑一个问题手动点动和自动运行不能同时生效。如果操作员在手动模式下乱按而自动状态机检测到启动信号两者都在给轴发指令轴会乱掉。所以我在程序开头用一个互锁逻辑手动模式下不允许自动启动自动状态下屏蔽手动点动。这个互锁放在SCL的最前面作为整个运动控制的“总闸”。顺起逆停在手动模式下的处理也一样点动运行中如果按了反方向按钮程序会先输出停止等待轴停止指令完成MC_MoveJog的停止需要单独的Execute参数控制再允许反方向启动。如果你在SCL里直接切换方向参数PLC会立即执行但驱动器和机械不一定来得及响应。4.4 数据块的结构设计我用了一个全局数据块DB_AxisControl结构如下输入区来自触摸屏的目标位置、目标速度、加加速度、减速度以及按钮和模式选择。输出区运行状态、当前位置、报警代码、到位标志。内部区状态机变量、计时器临时变量、运动控制指令的背景DB变量。这样分区的意义在于触摸屏只需要读写输入区和输出区内部区对HMI不可见防止误操作。第三方工程师拿到程序后看数据结构就能理解程序的整体架构不用从头到尾翻代码。5. 实操过程从组态到调试的完整流程5.1 新建项目和硬件组态我先打开博途V17新建项目命名为“S7-1200_Stepper_Control”。在设备组态里添加CPU 1214C DC/DC/DC版本选V4.5这样能兼容大多数指令和工艺对象功能。然后添加KTP700 Basic触摸屏通过以太网连接IP地址规划好PLC是192.168.0.1触摸屏是192.168.0.2电脑是192.168.0.3。接着在PLC属性里启用系统存储器把“第一次扫描”和“诊断状态”这些系统位映射出来方便在程序里对初始化做处理以及在触摸屏上显示PLC诊断状态。双击左侧“运动控制”下的“新增对象”选择“轴”命名Axis_1。在轴组态基本参数里驱动器脉冲电机每转脉冲数3200负载每转位移量10mm方向双向硬件输出选择时系统会自动匹配可用的高速输出点。我上面说了脉冲输出选Q0.0方向输出选Q0.1。组态完保存编译下载到PLC之前要把项目里的“轴使能”先设为FALSE否则下载过程中PLC为了响应轴指令会把输出点强制占用可能造成设备误动。这是非常容易忽略的操作。5.2 运动控制指令的背景DB分配S7-1200的运动控制指令比如MC_Power、MC_MoveAbsolute、MC_MoveJog、MC_Home在使用时都需要背景数据块来保存运行数据。同一个轴的不同MC指令背景DB之间有关联关系。新建DB时类型选择“MC_Power”等对应指令的类型就能生成正确的背景DB。我习惯的做法是在程序里把指令实例化两次一次用于手动SCL内部调用一次用于自动状态机里调用这样它们的Execute参数不会被互相覆盖。如果只做一个实例手动和自动同时在逻辑上被调用指令内部状态会打架。MC_Power的使能逻辑是轴能运动的前提是Power为TRUE且StopMode设置为0立即停止或1斜坡停止。正常停止用1急停用0。实际项目中急停回路里断掉的应该不是MC_Power的Enable输入而是硬件回路里的输出电源。因为如果你在程序里用MC_Power去切断轴而CPU死机了这个切断就失灵了。硬急停必须在PLC外部把脉冲输出电源切断或者在输入回路里把信号切断。5.3 从空载调试到带载试运行硬件接线全部完成后不要急着用触摸屏操作。我建议按以下步骤逐步调试第一步用博途的在线诊断功能监控轴工艺对象的状态。在“轴调试”面板里可以看到轴的实际位置、速度、状态甚至可以直接输入一个速度值手动点动。这时候先给一个很慢的速度比如10mm/s点动一下看电机转不转。如果电机不转检查方向信号和脉冲信号是否互换检查驱动器的脉冲模式。有些驱动器默认是“脉冲方向”模式有些是“双脉冲”模式拨码开关必须设对。我在调试时遇到过一台电机怎么给脉冲都不动结果发现驱动器的拨码被前一个人调成了“双脉冲”模式方向信号被当成第二个脉冲输入了。第二步空载跑一段固定距离。给一个100mm的目标位置速度放到30mm/s看看实际走的距离和设定是否一致。如果偏差很大大概率是“电机每转脉冲数”填错了或者驱动器细分拨码和组态不一致。第三步加上负载试运行。带负载后加速度要适当调低。如果加速过猛步进电机会失步表现就是电机发出嗡嗡声但轴不走或者走了一段后停住不动。这个现象跟驱动器电流设置也有关系电流调大一点低速扭矩会更强但驱动器和电机的发热也会增加。5.4 程序下载与调试技巧调试时我习惯用“监视”功能同时看LAD和SCL但要注意博途在线监视SCL时变量的实时值不一定按代码执行顺序显示在一个画面里。如果怀疑某一行的判断条件不满足最好把关键变量加到“监看表格”里统一观察而不是在SCL界面里一行一行看那样效率很低。另一个技巧是把轴工艺对象的“状态字”拆出来在监看表格里看看当前轴处于什么状态。S7-1200的运动控制指令返回的状态字里每一位都有具体含义比如正在运行、到位、正向超程、反向超程、跟随错误等。根据状态字去判断程序卡在哪一步比盲猜快得多。6. 常见问题与排查技巧实录6.1 电机不转但PLC输出点有脉冲这种情况很常见。PLC的输出指示灯在闪但电机没动。先量一下PLC输出端的电压看看是不是24V。很多S7-1200的输出点用的电源是L端子提供的如果L没接或者保险丝烧了输出指示灯可能会亮但实际输出电压是0V。另一个原因是接线问题。脉冲信号PUL和PUL-接反了光耦不导通自然没有脉冲进驱动器。用万用表量驱动器的PUL端如果电压在脉冲时变化说明信号到了再看驱动器的拨码和指示灯。还有可能是方向信号的问题。如果方向信号没接好驱动器的方向电平不定电机可能不动或者只朝一个方向转。把方向信号线单独量一下电压确保高电平时是24V低电平时是0V。6.2 电机转动方向相反这个最简单不需要改硬件。在轴工艺对象的“基本参数”里有一个“方向”选项可以设成“反向”或者“正向取反”。也可以在驱动器上把DIR信号的极性拨码改一下。我一般不改程序因为改了程序里的方向逻辑上容易搞混尤其是回原点的方向也要跟着改一处没改对整个设备就跑飞了。改驱动器方向极性是最直接的改完用点动验证一下。6.3 电机抖动、异响、失步先说抖动。如果电机在原地嗡嗡响但不转说明有脉冲但力矩不够或者速度给定太低。步进电机在极低频率下会振动这个频率区间通常叫低频共振区在60rpm到200rpm之间。解决办法是提高起始速度或者启用驱动器的细分功能把细分调大共振现象会明显减轻。如果走的时候丢步也就是实际位置和设定位置偏差越来越大先检查加速度是不是设太高了。S7-1200运动控制指令里的加加速度单位是mm每二次方秒要结合负载惯量来算。负载惯量大加速度就调小。还有一个经验值是步进电机的启动速度不要超过300rpm加速到最高速的过程至少要0.5秒以上除非你的负载非常轻。驱动器电流设置也很关键。电流设得偏低高速时力矩不够丢步概率大增。电流设得偏高电机发热严重长期运行会退磁。一般在驱动器铭牌或说明书上有推荐电流范围取中间值偏上一点比较稳妥。6.4 回原点方向判断错误MC_Home指令回原点时轴会先朝指定方向找原点开关。如果原点开关的安装位置和回原点方向不匹配轴会朝反方向跑直接撞到限位。保护逻辑里碰到限位后MC_Home会报错但机械可能已经撞上东西了。调试回原点前先手动把轴移到原点开关的同一侧再执行MC_Home确保回原点方向是朝原点开关方向移动的。原点开关和限位开关之间的相对位置也要留出足够的减速距离不能离得太近否则轴还没减速就触发限位了。6.5 触摸屏上显示的位置和实际位置漂移这种问题几乎都是因为丢步。开环步进系统没有编码器反馈丢了多少步PLC是不知道的只能靠脉冲数累加出理论位置。一旦发生丢步显示位置和实际位置就永远对不上了。解决办法有几个方向减小负载惯量或加大电机扭矩。降低加速度。检查机械连接是否松动联轴器打滑也会引起丢步表现和电机丢步一模一样。必要时改成闭环步进驱动器带编码器反馈至少能检测丢步并报错。如果项目对定位精度有硬性要求或者长期运行可靠性要求高最好一开始就选闭环步进成本增加不多但调试省心很多。开环步进适合调试完毕、负载稳定、速度不高的场景。7. 程序结构的扩展建议与个人体会这套“LAD做硬逻辑、SCL做工艺逻辑”的思路不只适用于步进电机控制。我后来在伺服电机、变频器、气动元件组合的多个项目里都沿用了同样的程序结构LAD管安全回路和紧急操作SCL管工艺流程和状态切换。尤其是项目大了以后比如一套设备有三四个轴、十几个气缸、几十个传感器SCL状态机的优势就更加明显。梯形图写几十个网络看得头晕SCL的状态机一波CASE语句下来整个流程一目了然。触摸屏上的报警系统我建议配合报警文本库来用。PLC内部用整数型的报警代码SCL里置位报警代码触摸屏把报警代码映射成中文文本。这样程序里不需要为每个报警写一个布尔量HMI组态也简单很多。最后分享一个我自己踩过的坑。有一次设备交付后客户反映偶尔运行一次就会丢位置怎么都查不出原因。后来发现是PLC的程序扫描周期和高速脉冲输出不同步某个辅助继电器正好在扫描周期的中间被复位了导致脉冲输出被打断电机丢了一步。这种问题用梯形图排查了很久后来在SCL里加了一个心跳信号让脉冲输出只在状态机判断“允许运动”时才使能再把所有复位动作集中到状态机退出时执行问题就消失了。这类“看不见摸不着”的逻辑竞争问题往往是程序结构设计不合理引起的而不是指令用错了。你如果刚开始接触S7-1200和博途建议先拿一台上位机装好博途V17按我前面说的步骤组态一个虚拟轴不接硬件也能模拟运行。模拟运行能帮你彻底理解轴工艺对象和运动控制指令之间的关系等模拟没问题了再接真实硬件调试效率会高很多。