
上个月刚收尾的一套配料称重设备三菱FX3U做主控16个原料仓位按产品配方自动落料。这套程序最核心的部分就是16仓位配方管理从需求梳理到最后调试交付前后改了两版中间还踩了几个印象很深的坑。今天把这套配方程序的整体思路、寄存器规划、关键指令段和调试过程整理出来给正在做同类设备的工程师一个参考。这套设备其实不算复杂但配方程序一旦出问题后果非常直接配比错、批次报废、客户现场停机。所以我把这部分的可靠性和操作性放在第一位。如果你也在做配料、分装、多工位参数切换这类项目这篇记录应该能帮你少走不少弯路。1. 项目背景与需求拆解设备要什么程序才写什么写程序最怕客户只说一句“做个配方功能”然后就撒手不管。配方功能听着简单但具体到现场就全是细节。所以我习惯先把工艺拆清楚再对着拆解结果确定程序架构。1.1 工艺现场16个仓位到底怎么来的这台设备是一条小型配料线核心是16个原料仓每个仓下面有独立的落料阀门和称重模块。生产时按照产品要求把对应仓位的原料依次放进中间秤达到目标重量后关闭阀门进入下一仓最后混合出料。关键点在于不同产品对应的16个仓参数完全不同。每个仓至少有三个参数要管目标值、粗加料提前量、允许误差。粗加料提前量就是快到目标重量时提前关阀的提前量用来抵消阀门关闭滞后和落料冲击带来的过冲允许误差则是判定这一仓投料是否合格的容差范围。所以一台设备要生产多个产品就是在切换16组参数。16个仓乘以每仓3个参数一共48个参数这还只是最基础的。实际项目里还会加上每仓的投料顺序、提前量修正系数、超差后的补料次数参数会更多。1.2 原始方案是怎么被推翻的设备厂原来的方案很直接触摸屏上放48个数值输入框换产品时工人手动改。听着也能用但实际上问题很大。首先是效率问题。48个参数挨个改一遍熟练工人也要十五到二十分钟期间设备得停机等待。其次是出错率问题。参数多现场噪音大工人看错行、输错数字是家常便饭尤其粗加料提前量这类参数改错一个数字整批料的重量精度就废了。最头疼的是责任界定出问题后厂商说是工人改错了工人说是触摸屏自己跳的两边扯皮。所以设备厂最终提的需求很明确参数不能靠人肉输入必须做进配方里工人只需要选产品号剩下的事情交给PLC。1.3 最终需求清单写进程序前先写清楚这个项目我梳理出来的需求清单是这样的支持多个产品配方现场暂定16个产品但程序内部要预留扩展空间。每个配方包含16个仓位、每仓3个配方参数即48个数据字。一键切换配方切换动作要快且不能影响配料过程中正在执行的动作。配方数据必须掉电保持不能因为断电就清空。支持在HMI上修改参数并保存回配方但要有防误操作机制。配方数据要有校验逻辑加载时发现数据异常立刻报警不能带着错误数据生产。需求看起来不多但每一条落到实处都是程序结构设计上的约束。比如“不能影响配料过程”就逼着我在主流程里做互锁逻辑再比如“预留扩展空间”又逼着我用变址和偏移量来计算存储地址而不是傻傻地把16组配方挨个写死。2. 硬件选型与寄存器规划FX3U如何承载16组配方为什么选三菱FX3U而不是别的型号这是设备方早期就定下来的事情但我自己评估完之后也认可这个选择。FX3U在这个场景下其实很合适原因有三个。2.1 为什么是FX3U而不是FX3G或者更大系列FX3U在三菱小型PLC里属于性能比较能打的那一档。FX3G虽然是更便宜的替代品但D寄存器数量、变址修饰、FOR/NEXT循环这些指令的支持上FX3U更完整。后面如果这台设备要接入称重仪表走MODBUSFX3U的通讯扩展能力也更从容。再有一点是I/O点数。这套设备本身I/O不算多但带了4路模拟量输入和2路模拟量输出还要预留几个备用点位。FX3U-32M基本单元再加上两个扩展模块点数正好覆盖还有余量。选型的时候我习惯留至少10%的余量不然电气装配阶段发现缺一个输入点改起来就难受了。2.2 寄存器分区方案D区怎么分配FX3U的D寄存器总量不少但用起来必须规划清楚不然程序写到后面就成浆糊了。我这套程序的D区分配是这样的地址范围用途说明D0-D49系统公共区秤状态、阀门状态、班产累计、手动/自动标志D50目标产品号HMI写入范围1-16这是配方切换的入口D51当前产品号PLC内部维护切换完成后更新D52-D59偏移计算中间变量计算配方的存储起始地址D60-D99子程序局部变量校验累加器、循环计数器等D100-D147当前配方工作区16仓位×3参数主流程直接读取这一块D148当前配方校验和加载校验时使用D150-D199称重数据区当前秤的毛重、净重、目标量、落差量等D500起配方存储区每个配方49字最多可放26个产品配方这里有个很关键的设计思路当前配方工作区D100-D147是主流程唯一会去读取的数据区域。配方切换本质上是把存储区的数据成批搬进D100-D147主流程根本不需要知道自己正在生产什么产品它只需要按照D100-D147里的参数去做控制。这样做的好处是程序解耦配方管理逻辑和配料控制逻辑互不干扰。后期要改配方逻辑不会碰到主控制程序。2.3 掉电保持设置最容易忽略的细节FX3U的D区默认有一块锁存区域但范围不是你想要的那么多。默认情况下D512-D7999是锁存区域而D500-D511并不在锁存范围内。我这套程序配方存储区从D500开始如果直接把D500-D511的数据当配方存储区用而不做任何设置那就完蛋了掉电之后前12个字的数据全丢。解决方案是在PLC参数里的“软元件”页面把D500-D1299全部设为锁存区域。这里的教训是不要想当然认为“D区都是断电保持的”。FX3U的D0-D511默认是非锁存的除非你改参数。而且这个设置不在程序里在PLC参数里很多人改了程序忘了改参数现场一断电之前保存的配方全部归零。另外一个细节是FX3U的电池。锁存区域靠电池供电维持电池寿命一般五到七年但设备在高温高湿环境会缩短。三菱有个特殊继电器M8016电池电压低的时候会置ON这个信号一定要接到HMI报警画面上不然电池没电了配方数据悄悄丢失排查起来非常被动。3. 配方数据结构设计产品号、仓位号与地址的映射关系配方程序的核心说白了就是一张表产品号在表中对应哪一段D寄存器偏移量怎么算。这个搞清楚了程序里那些指令就是机械执行。3.1 配方表的结构每仓位3参数每个配方49字先看一下单个配方的内部结构。每个仓位3个参数16个仓位就是48个字。再加上一个校验字所以每个配方占49个D寄存器。相对偏移含义示例01号仓目标值D100单位g11号仓粗加料提前量D101单位g21号仓允许误差D102单位g32号仓目标值D10342号仓粗加料提前量D10452号仓允许误差D105.........4516号仓目标值D1454616号仓粗加料提前量D1464716号仓允许误差D14748校验字D148为什么校验字要占一个字放在最后面而不是单独开一块区域因为这样可以直接把整个49字一起搬进工作区加载完成之后用同一个基地址做校验逻辑非常顺。校验算法用的是经典的和校验把前面48个字的数值全部累加得到一个总和存到第49个字里。加载的时候重新算一遍前48字的累加和和校验字比对一致就说明数据没被破坏。3.2 地址映射产品号如何换算成存储区偏移配方存储区从D500开始每个配方49字那么产品号n的起始地址就是起始地址 500 (n - 1) × 49举个例子产品号起始地址结束地址校验字位置1D500D548D5482D549D597D5973D598D646D64616D1235D1283D1283为什么要用变址寄存器而不是直接把16个地址全部写死因为这个配方表一旦定义好后期要扩展产品数量只需要改一个常数。比如程序里用K49这个常数乘以产品号将来每个仓位参数从3个变成4个那只需要把K49改成K65存储区间自动整体平移不需要逐条改程序。当然这个常数改动要非常谨慎因为配方区已经存进去的数据位置会全部变化。我一般会在程序开头做一个常量定义区把这个K值放到一个D寄存器里方便统一修改同时用注释标清楚这个数跟配方结构强相关不能随便动。3.3 主流程是怎么读取工作区的主控制程序读取的不是D500后面的大表而是D100-D147这块工作区。比如1号仓的配料逻辑大概是目标值是D100粗加料提前量是D101允许误差是D102。配料开始后称重数值到了D100-D101的位置粗加料电磁阀关闭进入慢加料到了D100附近开始精调最终落在D100±D102的范围内判定合格。这套结构的优点非常明显主流程完全感知不到配方的存在。它只是按D100-D147当前的内容执行控制逻辑。至于D100-D147的内容是从哪个产品配方里加载进来的那是配方管理程序的事情两者之间通过工作区解耦。后期如果要加一个功能比如“临时修改当前配方的某个参数但不保存”也只需要在HMI上修改D100-D147对应的字主流程立刻生效。方便得很。4. 核心程序逻辑实现加载、保存、校验的完整流程接下来是重头戏实际的梯形图逻辑。我按加载、保存、校验三个部分来讲每段都会附上关键指令的写法以及我为什么这么写。4.1 配方加载流程一键切换到底发生了什么先明确触发方式。HMI上放一个“切换配方”按钮对应PLC的M100。按下按钮后PLC检测到上升沿才执行加载而不是一直执行。用上升沿的原因很朴素M100如果一直是ON程序就会反复执行加载逻辑BMOV指令不断往外搬数据还可能把正在运行的参数改掉。用PLS指令把按钮脉冲化一次性执行干净利落。核心指令段是这样写的LD M100 PLS M101 // 范围校验产品号必须在1-16之间 LD M101 ZCP K1 K16 D50 M20 ANI M22 AND M20 // 范围OK继续执行加载 MOV D50 D60 SUB D60 K1 D60 MUL D60 K49 D52 MOV D52 Z0 BMOV D500Z0 D100 K49 CALL P0逐行解释一下。第一步把D50里的目标产品号读出来减1再乘以49得到偏移量。这个偏移量送进变址寄存器Z0。变址寄存器的意义在于D500Z0这个地址会随着Z0的值动态变化。Z0735时D500Z0实际指向D1235正好是16号产品的起始地址。第二步BMOV是成批传送指令一次把49个字从配方存储区搬到工作区。这里注意BMOV的源地址D500Z0是变址后的地址目标地址D100是工作区起点传送数量K49。第三步CALL P0是调用校验子程序。加载完成后必须马上校验防止搬过来的数据本来就是坏的。校验子程序P0的逻辑是这样的P0: MOV K0 D70 MOV K0 Z1 FOR K48 ADD D100Z1 D70 D70 INC Z1 NEXT CMP D70 D148 M30 // M30: 相等, M31: D70D148, M32: D70D148这段是标准的求和校验。Z1从0循环到47每次把D100Z1对应地址的值累加到D70。循环结束后D70就是前48个字的累加和再用CMP和D148比较。比较结果放到M30-M32M30导通代表校验通过。校验通过后把D50的目标产品号更新到D51当前产品号同时复位加载状态。校验不通过M30不导通D51保持原来的产品号同时置位一个校验错误报警M33HMI上弹窗提示操作工。这里有一个非常重要的细节校验不通过时不会中断当前正在使用的配方。也就是说旧参数继续生效设备可以保持运行只是HMI会提示配方数据异常。如果校验不通过就直接清空工作区设备立刻失控那才是真正的灾难。4.2 配方在线修改与保存调试模式下的安全机制配方保存的逻辑比加载稍微复杂一点因为涉及“防误操作”。我的做法是给保存操作加三重保险。第一重保险是“调试模式”标志。M130是调试模式开关只有设备进入调试模式保存按钮才有效。普通操作模式下HMI上的保存按钮是灰色的PLC侧也不响应。第二重保险是二次确认。HMI上点“保存配方”按钮后会弹出一个确认框提示“确认将当前参数保存到产品号X的配方中”操作工必须再点一次“确认”才真正触发M102。第三重保险是脉冲触发。和加载一样保存也用上升沿触发执行完成后自动复位防止按钮卡住导致反复写入。保存的核心指令段LD M102 PLS M103 ANI M130 // 不在调试模式禁止保存 LD M103 AND M130 // 先计算当前工作区D100-D147的累加和 MOV K0 D70 MOV K0 Z1 FOR K48 ADD D100Z1 D70 D70 INC Z1 NEXT MOV D70 D148 // 计算目标地址偏移并写回 MOV D50 D60 SUB D60 K1 D60 MUL D60 K49 D52 MOV D52 Z0 BMOV D100 D500Z0 K49和加载相比保存多了一步先把工作区的48个参数累加求和结果写入D148然后再整体BMOV回配方存储区。这样保存之后配方区的校验字一定是和当前48个参数匹配的。这个顺序不能反。如果先搬运参数再算校验和BMOV搬过去的49个字里校验字是上一次的旧值跟新参数不匹配下次加载的时候一定会校验报错把自己给坑了。4.3 数据校验与容错不能只做加法还得做上限保护和校验虽然简单但有一个天然弱点如果两个参数同时发生相同数值的错误比如一个参数从100变成101另一个参数从200变成199累加和不变校验就漏过去了。大多数情况下这无所谓因为D区数据损坏通常是整片异常不太会出现“两个参数刚好互补”的巧合。但如果项目对安全性要求高我会再加上两个保险。一是给每个配方增加一个固定的特征字。比如在第48个字的位置存一个固定的十六进制数0x5A5A加载时校验这个字如果特征字不对说明配方区根本不是预期格式直接报警。特征字在程序初始化的时统一写入。二是给参数做上下限检查。加载完成之后逐个判断48个参数是否在工艺允许的范围内比如目标值不能为0不能大于设备最大量程。任何一个参数越界都按校验失败处理。这个检查用区间比较指令ZCP逐项做就行虽然程序长一点但能拦住大部分异常情况。项目刚交付的时候我总觉得校验逻辑做到“累加和一致”就够了直到有一次现场真的出现了一个参数被写成0的情况是和校验发现不了的。从那以后特征字和上下限检查就成了我配方程序的标配。5. HMI画面设计与联调细节程序写得再好人机界面一塌糊涂现场照样没法用。这套项目的HMI用的是三菱GT系列触摸屏和FX3U走编程口直接通讯。画面设计上没有做得很花哨但每个元素都有明确的功能定位。5.1 配方画面布局操作工与调试员各司其职HMI上我分了三层画面。第一层是“生产操作画面”给操作工用的。上面只有一个产品号选择输入框D50、一个当前产品号显示框D51、一个“切换配方”按钮M100以及当前配方校验状态指示灯。操作工要做的动作就三个选产品号、按切换、看状态没有任何多余的参数入口。第二层是“配方参数画面”给调试员用的。16个仓位分成4页显示每页4个仓位每个仓位显示3个参数对应D100-D147里的值。画面上有保存按钮、加载按钮、调试模式开关。这一层默认隐藏需要通过权限密码才能进入。第三层是“配方状态画面”给我自己调试用的。实时显示D52偏移量、Z0变址值、D70累加和、D148校验字、M30-M32校验结果位。现场排查问题的时候这一页能告诉我程序到底在哪一步出了问题。5.2 地址对接与数据格式HMI和PLC地址对接时最容易踩的坑是数据类型不一致。三菱GT Designer里数值输入/显示有“16位整数”和“32位整数”选项。我配方里的参数全部是16位带符号整数所以D100-D147的输入框全部选16位。但有一个地方需要特别注意D52-D53是MUL乘法指令的32位结果区D52是低16位D53是高16位。当偏移量小于32767时D53始终为0所以画面状态里显示D52就够。但你不要因为这个就去把D52的显示改成16位无符号因为偏移量算出来永远是正数用16位整数显示没问题只是在做边界测试时发现如果产品号被错误写入一个32767以上的大数Z0就会变成负数BMOV的源地址直接跑到D500之前。所以范围校验永远不能省。5.3 为什么不用HMI自带的配方功能用GT Designer做HMI的人都知道触摸屏本身也自带配方功能可以建立配方表、批量写入PLC。但我在这个项目里坚持用PLC侧做配方管理主要考虑了四点对比项HMI自带配方PLC侧配方程序数据存储位置HMI内部存储PLC锁存D区换屏迁移配方数据要重新录入PLC程序不动换屏只做画面校验逻辑基本没有可以加和校验、特征字、范围检查互锁逻辑很难实现可以无缝接入主流程互锁调试观察类似黑盒在线监视一目了然最关键的是换屏问题。现场万一触屏坏了临时换一块同型号的新屏HMI自带的配方数据可能因为存储格式不一致读不出来。而PLC侧方案里配方数据全在PLC里新屏只要通讯地址对上画面重画一遍就能恢复使用工厂不会因为一块触摸屏的损坏导致整套配方丢失。6. 调试中踩过的坑与避坑建议每个项目都是踩坑踩过来的这套配方程序也不例外。整理几个印象最深的给大家做个参考。6.1 产品号被写入0或超大数配方区直接错乱第一次联调的时候我在HMI上无意中把产品号输入框清空了结果D50变成0。程序里的偏移计算是(D50-1)×49算出来是-49变址寄存器Z0变成负数BMOV D500Z0读出来的数据是D500之前的地址内容整个工作区瞬间变成一团乱码。要不是校验子程序拦住了设备直接按错误参数投料后果不堪设想。这个问题的根子在于HMI输入框允许输入任意数值而程序没有做输入边界限制。后来我在程序里加了ZCP K1 K16 D50 M20的范围校验把0和大于16的数值全部拦在加载逻辑之外并且HMI输入框也设置了最小值和最大值1到16。两边一起做限制即使有误操作程序也不会执行异常逻辑。6.2 切换配方时设备正在运行参数瞬间变化这个坑是设备方在试生产时发现的。工人趁着一批料正在配料的过程中随手切换了产品号。D100-D147被瞬间更新当前批次的称重目标值突然变了一批料直接报废。解决方式是加互锁配料进行中标志M120为ON时M101加载脉冲被M120的常闭触点串联阻断切换动作执行不了。HMI上再做一个条件M120为ON时切换按钮置灰操作工看得到原因。不过完全禁止切换也有问题如果设备刚好处于批次间隔切换动作还得等配料结束才能做工人会觉得麻烦。后来我改成“预切换”模式配料过程中允许选择产品号并暂存但真正的BMOV传送要等本批次结束后自动执行。这样既不干扰生产也不耽误换产。6.3 误保存把好配方覆盖了有一次在现场调试配比参数技术员改了几个参数试生产觉得效果不错本来想“保存一下”结果手一抖点到了旁边的“加载配方”按钮把刚才调好的参数全部覆盖回旧值。这还不是最惨的最惨的是有人在保存时连点两下确认把没改完的半成品参数也存进了配方。我的解决思路是场景分离保存按钮只出现在配方参数画面并加上调试模式标志和二次确认。加载按钮放在生产操作画面两个按钮不在同一个页面极大减少误触概率。另外PLC侧无论加载还是保存都用脉冲触发且执行完自动复位即使画面按钮状态异常也不会重复执行。6.4 锁存区边界问题导致的配方数据丢失这个必须单独拿出来讲。项目初期有客户反馈配方数据偶尔会丢而且丢得很奇怪都是前两组的配方内容丢后面的配方安然无恙。查到最后发现配方存储区从D500开始而FX3U默认的锁存区域是从D512开始的。D500-D511这12个字根本没在锁存范围内断电就丢。因为每个配方占49字前两个配方的后半段正好越过D511表现就是“部分配方丢失”。如果设备经常停电或者有人直接拉闸这个问题几乎必现。排查方法也很简单在PLC参数里查看软元件锁存范围把D500-D1300全部设为锁存。这里特别提醒一句不同版本的GX Works/GX Developer锁存范围设置的位置和确认方式略有不同改完之后一定要在线读取PLC参数确认不能只看编程软件界面上的勾选。6.5 配方数据正常校验却报警的离奇现象最后一个小坑校验偶尔误报。明明HMI上看到的参数都是正常的加载时却报校验失败。查了半天发现问题出在HMI的数值显示格式上。画面里某个参数框用了“显示小数点”功能显示的是10.5实际PLC里存的是105。操作工在HMI上把10.5改成11.0PLC收到的是110看起来正常但操作工以为改了1个单位实际改了5个单位配方数据本身没问题人的判断被画面误导了。这提醒我配方参数类的数值显示要么全部不带小数点要么小数位固定一致千万不能混合格式。否则现场的人看着很正常数据的实际含义已经偏了。这套16仓位配方程序整体开发下来最大的体会是配方功能的核心不在“存数据”而在“管数据”。地址规划、校验机制、互锁逻辑、防误操作每一样都比单纯执行一条BMOV指令要花更多心思。项目交付之后客户那边换产品从原来的人工改参数20分钟变成现在30秒一键切换而且再没出现过错改参数导致的批次报废。我做配方程序这些年慢慢形成了一个习惯凡是和配方相关的地址一律在程序开头集中定义旁边写清楚偏移计算规则。程序将来交到别人手里维护人家一眼就能看明白结构不用靠猜。