资讯动态

Sicar标准程序架构分层与报警诊断工程规范

发布时间:2026/10/27 11:37:49 来源:尧图企业网站定制
简介面向自动化工程师与工控学习者的Sicar标准程序培训示例包适合希望系统理解Sicar程序架构、模块组织及设备组态配置的初中级读者。压缩包共106个文件约38.19MB主要由xml、ini等配置与参数文件bmp、png等设备及界面图像素材以及cfs、dat等工程数据文件组成兼顾工程结构还原与组态素材查阅。已有654人学习说明其在Sicar标准程序入门与对照实践中具有一定参考价值。包内提供培训演示工程及配套组态资源可用于梳理标准程序的目录层次、理解配置项之间的对应关系并借助图像与数据文件辅助分析设备组态和界面呈现通过配置文件还可观察模块参数、变量映射与通信设置适合作为学习Sicar标准程序、开展二次开发或项目移植时的对照材料。1. 从一份模板到一套工程秩序Sicar 标准程序的整体地图Sicar 标准程序给人的第一印象往往是“一套现成的 PLC 程序”但把它的骨架摊开来看真正值钱的部分其实是一组约束程序分几层、块怎么命名、设备对外暴露哪些接口、报警字怎么排布、库和模板怎么升级。功能代码谁都能写能让十个人接手同一个项目还不打架的是这些约束。梳理下来会发现它更像一份“车间排版规范”而不是一本“设备说明书”。这套东西适合两类人已经能独立写结构化文本、但项目一多人协作就开始失控的工程师以及需要在复习里把标准化编程讲成体系、而不是背几个名词的人。后面按架构、命名、报警、易错点、自检清单的顺序走一遍尽量把地图画到能直接照着核对的程度。2. 架构分层单元、设备、功能块的三级拆解Sicar 标准程序的第一个硬约定是分层。它不允许你把一段逻辑随手塞进主循环而是强制把程序拆成“单元—设备—功能”三级每一级只对自己那一层负责。这个设计单独看很朴素落到几十台设备的产线上就是生死线换一台同型号设备只需要换一个实例改一条工艺路线只动单元层的调度设备层一行不改。2.1 三级分层各自的职责边界单元层Unit对应一条产线或一个工位群负责工序编排、上下游握手、节拍调度设备层Equipment对应一台具体设备比如一台拧紧机、一个转台、一套输送负责自己的启停、状态、报警功能层Function是最底层的可复用逻辑比如一个延时确认、一个双边沿检测、一个模拟量换算只做纯粹的输入输出变换不持有工艺语义。三层的调用方向是单向的主循环调用单元单元调用设备设备调用功能块。反过来绝对不允许——功能块里出现某个具体设备的变量名就是分层被击穿的第一个信号。层级典型块类型职责变更频率复用范围单元 UnitFB 背景 DB工序编排、节拍、握手低同工艺可复用设备 EquipmentFB 背景 DB单机启停、状态机、报警中同型号可复用功能 FunctionFC / FB通用逻辑、换算、滤波极低全局复用基础数据DB参数、配方、映射中随项目梳理下来最容易忽略的一点是“变更频率”这一列。很多项目的分层看起来是对的但一查改动记录发现设备层天天在动、功能层也在动说明边界划错了——本该待在功能层的通用逻辑被写进了设备层本该待在单元层的工序判断被下沉到了设备层。单元层还有一个容易被跳过的动作调度表。标准做法是在单元 FB 里维护一张设备调用表按工艺顺序显式调用而不是靠扫描顺序“碰巧”对。这样新增设备时是在表里插一行而不是在主循环中间插一段后面接手的人一眼能看出工序顺序。2.2 标准接口与设备状态机设备层的核心不是它干了什么而是它对外承诺了什么。Sicar 标准程序要求每个设备 FB 拥有同一套输入输出接口命名、类型、含义都固定。这样上位机、单元层、诊断程序面对的永远是同一张脸不需要为每台设备写一套适配代码。// 设备功能块标准接口结构化文本风格IEC 61131-3 FUNCTION_BLOCK FB_EquipmentStd VAR_INPUT xEnable : BOOL; // 使能FALSE 时设备强制回 Idle且不允许启动 xReset : BOOL; // 复位上升沿清故障持续为 TRUE 不重复触发 iMode : INT; // 模式0 空 1 手动 2 半自动 3 全自动 xStart : BOOL; // 启动请求仅在半自动/全自动下有效 xStop : BOOL; // 停止请求按模式决定是快速停还是循环停 END_VAR VAR_OUTPUT iState : INT; // 状态字0 Idle 10 Starting 20 Running 30 Stopping 90 Fault xReady : BOOL; // 就绪无故障且已使能 xBusy : BOOL; // 忙处于 Starting/Running/Stopping wAlarm : WORD; // 报警字按位对应本设备的报警号 END_VAR VAR tonStart : TON; // 启动超时监控 rtReset : R_TRIG; // 复位上升沿 END_VAR rtReset(CLK : xReset); CASE iState OF 0: // Idle等待使能与启动条件 xReady : xEnable; xBusy : FALSE; IF xEnable AND xStart AND (iMode 2) THEN iState : 10; END_IF; 10: // Starting启动过程带超时保护 xBusy : TRUE; tonStart(IN : TRUE, PT : T#5S); IF tonStart.Q THEN wAlarm.0 : TRUE; // 位 0启动超时 iState : 90; ELSIF xStarted THEN // xStarted 由设备内部逻辑置位 tonStart(IN : FALSE); iState : 20; END_IF; 20: // Running正常运行故障与停止请求优先判断 IF xFault THEN iState : 90; ELSIF xStop OR NOT xEnable THEN iState : 30; END_IF; 30: // Stopping等待设备回到安全位 IF xStopped THEN iState : 0; END_IF; 90: // Fault只有复位上升沿能退出 xBusy : FALSE; xReady : FALSE; IF rtReset.Q AND NOT xFaultActive THEN wAlarm : 16#0; iState : 0; END_IF; END_CASE;这段代码的逻辑很直白状态只在一个 CASE 里跳转任何外部输入都不能直接改iState只能通过xEnable、xStart、xStop、xReset这几个“合法入口”影响状态。参数上要注意三处iMode用整数而不是布尔是为了给手动、半自动、全自动留扩展位tonStart的超时时间必须是可配的写在常量里等于把调试成本转嫁给现场wAlarm在退出故障时必须整字清零只清当前位会留下历史脏位这是后面报警章要展开的坑。标准接口真正的价值在于“替换成本”。接口统一之后一台设备换成另一台单元层的调用不用动上位机的变量绑定不用动诊断程序的解析逻辑也不用动。反过来如果每个设备 FB 的输入输出各写各的那么每加一台设备就是一次小型集成项目越大越难收尾。状态机还有一个常被忽略的细节停止要分类型。快速停急停、安全门和循环停正常换型走同一条路径现场就会出现“按了停止还在动一下”的争议。标准做法是在设备层区分xStopFast与xStopCycle两条路径都收敛到状态 30但内部动作不同。2.3 块命名与程序目录约定分层之后紧接着就是命名。Sicar 标准程序对块的命名有明确结构类型前缀 单元号 设备号 功能词。比如一台设备的功能块名字里应该能直接读出“这是哪个单元的、第几号设备、干什么的”。功能块编号通常按区间分段单元级、设备级、功能级各占一段这样在块列表里一排序层级关系就出来了。程序目录同样按层划分单元程序、设备程序、公共功能、通信、诊断、数据块各占一个文件夹不按“谁写的”分。按人分目录是协作项目里最常见的管理混乱人一离职半个项目的代码成了无人区。注意命名规则如果不能被工具强制执行就一定会退化。比较现实的做法是把命名检查做成提交前的一道自动校验或者在代码评审清单里固定一条“新增块是否符合前缀与分段约定”靠人盯迟早会松。3. 命名与接口规范变量、块、IO 映射的硬约束命名这件事单独看是鸡毛蒜皮放到三年期的项目里就是最大的技术债。Sicar 标准程序把命名当成接口的一部分变量名不只是给人看的注释它决定了别人能不能在不问你本人的情况下读懂这段逻辑。这一章把命名、IO 映射、库版本三件事拆开说它们共同构成“程序能不能被别人接手”的地基。3.1 变量前缀一套能被检查的命名表标准做法是“类型前缀 语义名”前缀固定、语义名用英文或拼音全拼不允许混用、不允许缩写到看不懂。前缀的作用不是好看是让人一眼知道这个变量的位宽和取值范围减少“拿 INT 当 BOOL 用”的低级错误。前缀数据类型典型用途常见误用xBOOL开关量、请求、标志用 x 开头却是 INTiINT模式、计数、索引与 di 混用diDINT累计量、大计数与 i 混用导致溢出rREAL模拟量、速度、温度与 i 直接比较sSTRING文本、批号长度未定义tTIME延时、超时直接写常量wWORD报警字、状态字按位访问越界aARRAY通道数组、配方上下界不固定这张表的价值在“常见误用”那一列。整理下来会发现现场百分之八十的类型问题不是算错了而是前缀和实际类型对不上声明成i的变量装着累计产量跑了半年溢出成负数声明成r的温度值和整数常量直接比较永远不相等。前缀制度能生效的前提是它被当作编译期约束而不是书写习惯。除了前缀还有两条容易被跳过的规则。第一条是“一个变量只表达一件事”xStartAndReady这种复合语义的名字后面一定会有人只想要其中一半的含义。第二条是“临时变量也要命名”temp1、temp2在调试期看着省事接手的人要在几十行里反推它的含义。3.2 IO 映射的三层结构与硬件组态模板化IO 映射是标准化程序里最容易被低估的一块。Sicar 标准程序通常把 IO 分成三层物理地址层模块通道地址、映射数据层通道 DB、逻辑变量层设备 FB 的输入输出。三层之间是单向映射逻辑程序只认第三层永远不直接读物理地址。这样做的直接好处是硬件换型。模块从左边挪到右边、通道从第 3 个换到第 7 个只需要改映射层的一张表设备逻辑一行不动。如果逻辑里直接写死物理地址一次硬件改版就是一次全项目搜索替换漏一处就是一次现场停机。// IO 映射层物理通道 - 逻辑变量只在这一处出现物理地址 // 新增或变更硬件时只改这一段设备逻辑不动 DB_IO_Map.xStation1_PartPresent : DI_Module1.Channel_03; // 工件到位 DB_IO_Map.xStation1_ClampClosed : DI_Module1.Channel_04; // 夹紧到位 DB_IO_Map.xStation1_ClampCmd : DO_Module2.Channel_01; // 夹紧输出 DB_IO_Map.rStation1_Pressure : AI_Module3.Channel_00; // 压力反馈这里的关键是“只在一处出现物理地址”。映射段之外任何地方再出现Channel_xx都应该被视为违规。参数上要注意模拟量的处理映射层只做搬运量程换算放在功能层否则换一个传感器就要改映射表映射层就失去了“稳定层”的意义。硬件组态同样要模板化。标准做法是给每类设备预留固定的通道数量比如一台典型设备固定占 8 入 4 出 2 模拟量即使当前只用了 3 个输入也把位置留出来。这样后续加传感器不用重新排布地址映射表也不用整段重编。预留会浪费一点地址空间换来的是改版时不用动别人的部分。提示映射表要配一份“地址占用清单”记录每个通道被谁占用、备用多少。没有这份清单两年后没人敢动任何一个通道。3.3 库、主模板与版本管理标准化程序真正的载体是库和主模板。库放的是跨项目复用的设备功能块和通用功能主模板放的是一套已经配好架构、命名、映射、报警框架的空壳项目。新项目从主模板复制一份开始而不是从零搭。版本管理是这一块的重点也是最容易做成形式主义的地方。可行的做法有三条库有明确的版本号主模板记录它依赖的库版本每次库变更写变更说明说明里写清“接口是否变化”项目升级库版本时先比对接口差异再决定是整体替换还是保留旧实例。接口变化是最危险的一类变更。给一个设备 FB 增加一个输入引脚看起来无害但如果这个引脚没有默认值所有调用点都会编译不过如果给了默认值但语义变了编译能过、行为变了这种问题在现场最难查。所以标准做法是新增引脚必须给安全的默认值删除或改义引脚必须升主版本号并在变更说明里单独列出来。4. 报警与诊断体系从报警字到可读故障信息报警是标准化程序里“平时没人看、出事全靠它”的部分。Sicar 标准程序对报警的要求不只是“能报出来”而是“能定位到具体设备和具体原因”。这一章按报警分层、报警字编址、诊断链路三步走最后落到一个最现实的场景设备不动了操作工看到的应该是一条能指导动作的信息而不是一个红点。4.1 报警分层四类报警各管什么标准做法是把报警分成四类各自有独立的产生源和处理路径。混在一起是报警系统失效的头号原因所有报警都进同一个列表优先级一样结果就是重要的被淹没了。报警类别产生源典型示例处理方式过程报警单元层工艺判断节拍超时、物料未到位提示可自动恢复设备故障设备层状态机启动超时、动作未到位停机需复位通道诊断IO 映射层断线、短路、超量程停机需检修系统诊断控制器与总线模块丢失、通信中断停机需专业处理分类之后每一类报警要有自己的确认与复位路径。过程报警可以自动恢复设备故障必须人工复位通道诊断要修好硬件才能复位。如果全都用同一个复位按钮操作工就会养成“按一下再说”的习惯真正的故障被反复掩盖。分类还决定了报警的展示位置。设备故障应该在设备本体的操作面板上就能看到通道诊断应该进维护界面过程报警可以只在上位机提示。全都堆到主界面等于没有优先级。4.2 报警字编址与打包逻辑报警字是设备层与上位机之间的契约。常用做法是每台设备分配固定数量的报警字字内按位对应报警号位号与报警文本一一对应不允许临时插位。编址规则一般是“设备号 字偏移 位号”这样从报警位能反推出设备从设备能查出全部报警位。// 报警打包设备内部故障位 - 对外报警字 // 位号一旦发布不得复用废弃的位保留为空位 wAlarm : 16#0; // 先整字清零避免历史位残留 wAlarm.0 : xStartTimeout; // 位 0启动超时 wAlarm.1 : xActionNotInPos; // 位 1动作未到位 wAlarm.2 : xPressureLow; // 位 2压力低 wAlarm.3 : xChannelFault; // 位 3通道诊断故障 // 位 4~15 预留给后续扩展不得随意占用 // 报警文本由上位机按 设备号位号 查表不在 PLC 内拼字符串这段逻辑有两个必须遵守的点。第一是每周期整字重算而不是“置位后一直保持”后者会让已经恢复的故障一直亮着操作工逐渐不信报警。第二是位号只增不改某个报警废弃了就留空位绝不能让位 5 从“气压低”变成“门未关”否则老程序、老图纸、老维修记录全部失效。报警文本的处理也有讲究。文本不要放在 PLC 里拼PLC 只负责给出设备号和位号文本由上位机查表。这样多语言切换、文本修订都不用下装 PLC改动成本差一个数量级。4.3 诊断链路从“设备不动”到“第几个点坏了”诊断链路的目标是把“设备不动”这一句模糊描述逐层收敛到具体原因。标准做法是三层递进硬件层看模块与通道状态映射层看信号是否到达逻辑层看时序是否满足。第一层是硬件诊断。模块是否在线、通道是否断线短路这类信息由控制器和 IO 模块直接提供程序只需要把它们收集到诊断数据区不需要自己判断。第二层是映射诊断检查物理信号是否真的传到了映射变量这一层能区分“传感器没给信号”和“程序没读到信号”。第三层是逻辑诊断也就是时序判断给了输出规定时间内没收到反馈就判定为动作超时。三层诊断的价值在于定位速度。只有第一层你只知道模块是好的只有第三层你只知道动作没完成。三层串起来才能回答“是传感器坏了、线断了、还是机械卡了”。// 时序诊断输出给出后监控反馈超时则记录到诊断区 tonFeedback(IN : xClampCmd AND NOT xClampClosed, PT : tFeedbackLimit); IF tonFeedback.Q THEN xActionNotInPos : TRUE; // 触发设备故障位 DB_Diag.iLastFailStep : 12; // 记录失败步号供追溯 DB_Diag.tLastFailTime : Clock.LocalTime; // 记录时间戳 END_IF;参数上tFeedbackLimit必须按动作类型分别配置夹紧和旋转的时间常数差一个数量级统一写死必然误报。诊断区里记步号和时间戳这两项是后面复盘的全部依据缺了它们报警就只是一个结果查不到过程。注意诊断信息要有上限。无限追加诊断记录会把数据区撑爆也会让维护界面变成日志瀑布。按“最近 N 条 关键步号”保留即可。5. 易漏易错点Sicar 标准程序落地时最容易翻车的几处标准化程序的坑很少在语法层面几乎都出在“约定被绕过”和“默认值被信任”这两件事上。整理下来翻车点集中在设计和调试两个阶段且大多有共同特征当时看着没事半年后才发作。下面几条按“易漏点 → 为什么漏 → 怎么补”展开都是可以直接拿去核对自己项目的。5.1 设计期埋下的三个坑第一个易漏点是接口默认值。给设备 FB 新增一个输入引脚时为了“先跑起来”很多人会给它一个看起来无害的默认值比如把“允许启动”默认为 TRUE。为什么漏编译能过仿真能过现场第一次上电也没事因为当时所有调用点都恰好满足条件。怎么补新增引脚的默认值一律取“最保守”的那个——使能类默认 FALSE模式类默认 0超时类默认一个明确的上限值同时在变更说明里单列“新增引脚及其默认值”评审时逐条确认。第二个易漏点是报警位复用。项目做到后期位不够用把某个废弃报警的位挪给了新报警。为什么漏废弃报警“反正不用了”改动当时没有任何现象。怎么补位号一经发布就冻结废弃位保留为空位并加注释说明“此位已废弃不得复用”如果确实需要扩容追加新的报警字而不是回收旧位。老图纸、老维修记录、老上位机配置全都按旧位号写的复用一次历史数据全部失真。第三个易漏点是 IO 预留不足。硬件组态时按当前需求排满通道没有留备用。为什么漏设计阶段觉得“需求已经定了”加传感器是以后的事。怎么补按设备类型定固定通道配额每类设备固定预留一定比例的备用通道映射表同步预留并标注“备用”备用通道在映射层也要有对应变量避免后期加信号时被迫改结构。5.2 调试与交接期的两个坑第四个易错点是复位逻辑写成“持续有效”。故障复位按钮按住不放或者上位机复位信号一直给着导致故障刚清又立刻重新触发或者故障根本清不掉。为什么漏单次点动测试时按钮是点一下就松看不出问题。怎么补所有复位逻辑统一用上升沿触发R_TRIG之后再用同时给复位加一个最短间隔保护防止连点导致状态机抖动。第五个易错点是分层被悄悄击穿。调试赶进度时为了绕过一个时序问题在设备层里直接写了单元层的工序判断或者功能块里出现了具体设备名。为什么漏当场问题解决了代码也能跑评审时只看功能不看结构。怎么补把“反向引用检查”做成固定动作——功能块里出现设备名、设备层里出现工序号都算违规每次提交前扫一遍跨层引用发现就地重构不要留到“以后统一整理”。提示这五个坑有一个共同点——它们在发生的当天几乎都不产生任何可见症状。判断一个标准化项目做得好不好不看它跑起来多顺看它半年后加设备、换硬件、换人的成本。6. 复习与自检把标准程序过成一张能勾选的表学到这里知识点其实已经齐了剩下的是“怎么确认自己真的掌握”。我的做法是不背概念改成拿一张表去核对一个真实项目能勾上的算过勾不上的就是漏洞。这张表按前面几章的顺序排从上往下走一遍基本能把架构、命名、映射、报警四块的薄弱处暴露出来。检查项判断标准不合格的典型表现分层是否完整单元、设备、功能三级齐全调用单向功能块里出现设备名接口是否统一所有设备 FB 输入输出结构一致每台设备一套接口状态机是否收敛状态跳转只在一处外部只经合法入口多处直接改状态字命名是否可读前缀与类型一致名字能读出层级出现 temp1、flag2IO 是否三层物理地址只出现在映射层逻辑里直接写通道地址报警位是否冻结位号只增不改废弃位保留旧位被新报警复用诊断是否分层硬件、映射、时序三层齐全只有一句“设备故障”库版本是否可追有版本号、有变更说明、接口变更单独标注库直接覆盖无记录光有表还不够还要有一个能跑起来的动作。我通常挑一条最典型的设备链从物理输入一路跟到设备状态、再到报警字、再到上位机文本全程只允许在映射层和接口层停留中途任何一次“这里直接读一下物理地址更快”都记下来那多半就是结构上的松动点。跟完一条链比通读十遍代码更能发现问题。另一个实用技巧是“反向出题”假设现在要新增一台同型号设备问自己需要改几个地方。合格答案是加一个设备实例、加一段映射、加一组报警位单元层调度表插一行功能层不动。如果需要改的地方超过这个范围说明分层或接口还有耦合早改比晚改便宜得多。还有一个经常被跳过但极其省事的动作给自己留一份“改动影响面”记录。每次动库或者动接口写清动了什么、哪些项目受影响、需要重新验证哪几条链。这份记录不用很正式几行字就够但它在半年后能省掉大量“这个块为什么和文档不一样”的排查。说个自己的教训。早些年接手一个改造项目图省事把几台设备的报警位压缩到了同一批字里当时觉得位够用、逻辑也跑通了交付得很顺。结果一年后扩容新报警没位可用就顺手回收了几个“看起来没人用”的位。后面的事可想而知老图纸对不上、维修记录对不上、上位机文本对不上排查花了整整两周最后还是把位号全部重排才收场。从那以后我每次动报警字都强制走一遍“位号冻结检查”宁可留空位也不回收。希望这份梳理能帮你在自己的项目里少走一遍这条弯路。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑