说实话看到“西门子AF框架翻译-第十四章”这个标题我第一反应是——这哥们儿终于啃到硬骨头了。AF框架全称SIMATIC Automation Framework简单讲就是西门子基于TIA Portal做的一套标准化设备自动化框架。它不像普通库文件那样丢几个FB给你用它提供的是从PLC数据结构、程序块架构、HMI画面模板到报警诊断体系的一整套工程方法论。很多人刚开始接触AF框架时都挺兴奋觉得终于有官方“最佳实践”可以抄作业了。但真翻到第十四章情绪往往从兴奋变成抓狂——这一章讲的不是基础库怎么用、UDT怎么建而是整个框架中最绕、最考验全局观的部分报警诊断与设备状态管理。为什么这一章难因为AF框架的报警体系不是简单地在WinCC里拖一个报警控件它要求你在PLC侧就把报警文本、设备状态、HMI显示规则、甚至操作员权限全部用数据结构串起来。你前面几章学到的UDT、FB封装、多实例调用全在这一章汇合。这篇文章我就结合自己用AF框架实际做项目的经验把第十四章涉及到的报警体系搭建思路、PLC侧设计方法、HMI联动配置和踩坑记录完整拆一遍。既照顾刚翻到这一章的初学者也给已经在用AF框架的老手一些排查思路。1. 先把AF框架第十四章的定位搞清楚1.1 这一章在整个框架里处于什么位置AF框架的文档结构有它自己的内在逻辑。前面章节你会先认识框架的库结构理解它为什么把PLC程序分成设备层、单元层、工厂层然后学UDT的定义方式——AF框架的UDT不是简单地堆几个变量而是带着明确的命名规范和数据分类哲学。到了第十四章框架开始解决一个非常实际的问题设备装了、程序跑了、HMI画面也有了但现场一开机报警铺天盖地操作工根本分不清哪个要紧。AF框架给的标准答案是报警也要分层、分级、标准化。这一章直接把报警诊断和整个自动化体系绑在一起讲核心就三个词结构化、文本外置、状态联动。我见过不少工程师用AF框架翻到这一章直接跳过去觉得“报警嘛WinCC里配一下就行”。结果项目调试后期光整理报警文本就花了两周因为报警信息散落在几十个FB里现场改一次IO点报警描述就得翻半天代码。第十四章真正要教你的是报警不要事后再补要在设计设备程序时就给报警留好“接口”。1.2 报警体系的三个设计维度AF框架里看报警从来不是孤立地看“某个位触发了”。它把报警拆成三个维度同时设计维度核心关注点落地方式数据层报警的条件、状态、时间戳从哪来PLC侧报警DB、报警FB、系统诊断文本层操作工看到的是什么内容报警文本、文本列表、多语言切换呈现层报警怎么显示、怎么操作WinCC报警控件、画面模板、确认规则这三个维度必须在项目一开始就对齐。AF框架的做法是把报警相关的UDT和FB做成一套标准装备哪个设备需要报警直接套模板而不是每个程序块自己发明一套报警逻辑。1.3 为什么AF框架把报警提到这么高的优先级做过现场调试的人都懂一个道理设备运行正常时程序怎么写都行出故障时能不能快速定位才是衡量一套程序好坏的硬指标。AF框架把报警诊断单独列为一章而且放在框架文档靠后的位置恰恰是因为它需要你具备前面全部的基础知识之后才能驾驭。第十四章开头一般会强调一个观点操作员看到的报警、维护人员看到的诊断信息、程序员看到的程序状态实际上应该是同一套数据的三个投影。如果做到这一点现场反馈问题时三方对话就不需要互相翻译直接对着同一个报警号沟通效率翻倍。2. AF框架报警体系的核心设计思路拆解2.1 报警为什么需要“结构化”很多非标设备厂自己做报警最常用的做法是程序里每个FB内部写一个QAlarm输出然后HMI上对应画面放一个指示灯。刚开始设备少还好设备一多就乱了——三号工位的报警和七号工位的报警同时弹出来操作员根本分不清优先级电工也只能一个一个查。AF框架解决这个问题的核心手段是报警UDT标准化。所有设备报警都放进一个统一结构里包含报警编号、报警触发位、报警确认位、报警时间戳、报警优先级这几个基本字段。你在程序里建的每个报警实例都长一个样。我做的项目里最直观的好处体现在画面组态上因为所有报警的UDT结构一致HMI侧写一个通用的报警变量映射规则就能覆盖全厂设备换新设备时不用再重新画报警画面。2.2 报警文本为什么要“外置”AF框架的报警文本设计一直坚持一个原则PLC程序里不写人类语言只写报警代码。第十四章里就对这个问题做了非常详细的说明——报警文本放到HMI侧的文本列表里集中管理。这个设计很多人一开始不理解“我FB里直接写个‘电机过载’不好吗非要在HMI里再配一次多此一举。”但实操过就明白好处程序统一用报警编号调试时改描述不用重新下载PLC程序中英文切换只需要维护HMI文本列表不用动PLC逻辑的一根汗毛报警描述可以写得更长更详细不受PLC程序注释的限制说白了报警文本外置的本质是把“事实数据”和“人类解释”解耦。这一招不仅在西门子体系里是标准做法在DCS、机器人、物联网平台里也是通用的设计哲学。2.3 优先级和确认机制怎么定AF框架的报警优先级通常分四到五级但我在实际项目里发现分级的粒度取决于你给操作员多大权限。分级太粗所有报警都变成“重要”等于没有分级分级太细操作员每次报警都要做选择题反而拖慢响应。我常用的分级策略是1级直接停机类保护报警比如急停、安全门、电机过载跳闸2级设备无法自动运行但未造成停机比如气源压力低、料位检测异常3级需要维护关注但不影响当前生产比如过滤器堵塞趋势预警、通信瞬断计数超限4级纯提示类信息比如设备运行时长为0的首次启动通知确认机制上AF框架的做法是区分“确认报警”和“复位报警”。确认表示操作员已经看到了不表示故障已经排除。所以报警结构里必须同时保留触发位和确认位HMI上才能做出“闪烁着报警、常亮着已确认”的经典行为。3. 实操照着AF框架的思路搭建一套报警管理功能块3.1 报警UDT的结构设计先定义报警的基本数据单元。以下是我在TIA Portal里建的UDT结构跟AF框架推荐的基本一致工程上可以直接用TYPE UDT_Alarm VERSION 0.1 STRUCT iAlarmID : INT; // 报警编号全局唯一 xAlarmCondition : BOOL; // 报警触发位来自FB内部逻辑 xAlarmAck : BOOL; // 报警确认位来自HMI操作 xAlarmActive : BOOL; // 报警当前激活状态组合输出 tAlarmTime : LDT; // 报警触发时间戳 iAlarmPriority : INT; // 优先级 1-4 iAlarmState : INT; // 状态0正常 1触发 2已确认 3恢复 sAlarmText : STRING; // 供HMI直接读取的文本仅调试用 END_STRUCT END_TYPE注意几个细节xAlarmActive不是简单等于触发条件的它要经过延时滤波处理否则现场信号闪一下就会产生一条假报警。我一般会给报警加一个200~500ms的确认延时用TON实现可以根据设备类型调整。iAlarmState这个状态字很重要它是HMI侧做颜色动态化的依据。状态0显示绿色正常状态1红色闪烁状态2红色常亮状态3需要在HMI上保持显示直到操作员复位。3.2 报警FB的SCL实现报警管理功能块我建议用SCL写因为逻辑简单清晰FB内部需要进行状态迁移判断。下面是我实际项目里精简过的SCL代码适合直接参考FUNCTION_BLOCK FB_Alarm TITLE : Standard Alarm Block VERSION : 0.1 VAR_INPUT xCondition : BOOL; // 报警触发条件来自设备逻辑 iPriority : INT; // 报警优先级 iAlarmID : INT; // 报警编号 END_VAR VAR_OUTPUT xAlarmOut : BOOL; // 组合后的报警输出用于HMI闪烁等 iState : INT; // 当前状态 tStartTime : LDT; // 触发时间戳 END_VAR VAR_IN_OUT udtAlarm : UDT_Alarm; // 报警数据结构 END_VAR VAR tonDelay : TON; // 延时滤波 tTriggerTime : LDT; // 内部时间记录 END_VAR BEGIN // 延时滤波消抖 tonDelay(IN : xCondition, PT : T#300MS); // 状态迁移逻辑 IF tonDelay.Q AND NOT udtAlarm.xAlarmActive THEN udtAlarm.xAlarmActive : TRUE; udtAlarm.iAlarmState : 1; udtAlarm.tAlarmTime : TON_Delay_Time(); // 记录触发时间 ELSIF udtAlarm.xAlarmActive THEN // 恢复判断 IF NOT tonDelay.Q THEN udtAlarm.iAlarmState : 3; END_IF END_IF; // 确认逻辑只有激活或恢复状态允许确认 IF udtAlarm.xAlarmAck AND (udtAlarm.iAlarmState 1 OR udtAlarm.iAlarmState 3) THEN IF udtAlarm.iAlarmState 1 THEN udtAlarm.iAlarmState : 2; // 已确认但未恢复 ELSE udtAlarm.iAlarmState : 4; // 已确认且已恢复 END_IF; END_IF; // 输出组合 CASE udtAlarm.iAlarmState OF 0: xAlarmOut : FALSE; 1: xAlarmOut : TRUE; 2: xAlarmOut : TRUE; 3: xAlarmOut : TRUE; 4: xAlarmOut : FALSE; END_CASE; udtAlarm.xAlarmCondition : xCondition; udtAlarm.iAlarmPriority : iPriority; udtAlarm.iAlarmID : iAlarmID; iState : udtAlarm.iAlarmState; END_FUNCTION_BLOCK这个FB写得比较精简关键状态迁移全部覆盖到了。实际项目中你还可以加上报警计数器、历史触发次数记录方便做设备维护趋势分析。3.3 报警DB的规划方式AF框架推荐的做法不是给每个报警单独建一个DB而是用一个大DB装所有设备的报警实例。这样做的优势有三个HMI变量连接只需要做一次后续新增报警只改PLC侧可以给所有报警做统一的批量扫描和状态汇总上位机做数据采集时只连一个DB区域就够了我在项目里通常这样组织报警DBDB_Alarm_Global ├── Device01_Alarms │ ├── Alarm_MotorOverload : UDT_Alarm │ ├── Alarm_PressureLow : UDT_Alarm │ └── Alarm_TempHigh : UDT_Alarm ├── Device02_Alarms │ ├── Alarm_VFD_Fault : UDT_Alarm │ └── ... └── Device03_Alarms └── ...每个UDT_Alarm实例对应HMI画面上的一个报警条目。注意报警ID在全局范围内唯一不要每个设备单独编号再从1开始否则HMI侧做报警过滤时非常痛苦。3.4 通用报警扫描块为了让HMI侧逻辑更简单我加了一个FB_AlarmScan负责把报警DB里的所有实例轮扫一遍。这个块输出几组汇总信号给HMI总览画面当前激活报警数量未确认报警数量最高优先级报警编码首个未确认报警的具体信息有了这个块HMI首页那条经典的红条报警信息——“XX工位电机过载优先级1请立即确认”——就不需要HMI脚本逐条去查了PLC侧一句话说清楚。TBH很多人在自己项目里做报警汇总时喜欢在WinCC里用脚本循环数组但PLC里一个轮扫块就能实现还更稳定。这也是AF框架强调“报警诊断逻辑尽量下沉到PLC侧”的原因HMI脚本一旦挂掉至少PLC侧状态还是准的。4. HMI侧的联动配置与画面模板4.1 报警控件的基础配置这一步通常在TIA Portal的WinCC组态里完成。AF框架的HMI层面对报警有一套统一的画面模板结构你要做的是把框架里的模板复制过来替换成自己的报警DB变量。报警控件最关键的配置是报警源连接。我强烈建议你在PLC变量表里把报警相关变量整理到一个单独的文件夹命名为Alarm_Interface然后所有HMI画面只引用这个文件夹下的变量。这样后续无论是做数据采集交出去还是别人接手项目都一眼能看清报警信号的来龙去脉。报警显示方面开三列基本就够用时间列显示触发时间状态恢复后显示恢复时间文本列中文描述预留英文切换空间状态列显示“待确认 / 已确认 / 已恢复”4.2 报警颜色的动态规则WinCC里报警行颜色可以通过状态变量动态驱动。我给报警行定义了如下动态规则状态背景色显示行为状态0正常白色/透明不显示报警行状态1触发未确认红色整行闪烁状态2已确认未恢复红色常亮状态3恢复未确认黄色常亮状态4已确认已恢复灰色保留显示5分钟后自动隐藏闪烁功能别在WinCC里用动画去做我踩过坑——项目大了画面一卡闪烁就停在一半。正确做法是用PLC侧输出的xAlarmOut变量直接接到报警行的闪烁属性上变量的通断频率就是闪烁频率。4.3 报警确认按钮与操作权限报警确认按钮有两种实现思路一是每条报警弹窗配一个确认按钮操作员必须逐条确认二是做个“确认全部”按钮一次确认当前页所有报警。AF框架在操作权限上是分级的。我实际项目的经验是优先级1和2的报警必须逐条确认不能批量确认。因为一级报警往往意味着安全隐患操作员必须真正理解这条报警的原因才能确认清掉。二级及以下允许批量确认否则处理不过来。权限方面确认动作通常绑定操作员级别。普通操作工能确认二级和三级的报警班长或工程师权限才能确认一级报警。具体做法是在WinCC的用户管理里创建对应的授权等级然后在确认按钮的授权属性里勾选相应等级。4.4 报警历史归档AF框架的第十四章还会涉及报警的归档和查询因为生产事故追溯时必须能回答“当时发生了什么操作员做了什么”。WinCC里做报警归档有两种方式本地归档默认存在WinCC项目服务器上使用简单但容量有限SQL Server归档适合多台服务器、长时间存储查询速度更快我建议报警归档至少保留三个月涉及批量追溯场景的保一年。归档查询画面按时间段、报警ID、优先级三个条件过滤基本上现场任何时候问起来都能马上调出记录。归档数据如果长时间不清理会影响WinCC整体性能所以一定要在项目里加上自动清理任务。5. 实际项目中第十四章相关的坑与排查心得5.1 时间戳不准的经典原因报警触发时间应该用PLC侧系统时间而不是HMI本地时间。很多项目报警时间对不上十有八九是因为WinCC用的本地时间服务器时间没同步或者PLC跟HMI的时间基准不一致。S7-1500里读取系统时间用RD_SYS_T或RD_LOC_T指令我比较推荐在报警FB触发的那一拍直接把RD_SYS_T的结果存进UDT_Alarm.tAlarmTime。这样不管HMI那边时区怎么配、服务器时间准不准报警时间永远以PLC本地时间为准。现场还有一种情况PLC和HMI时间不一致是因为没做NTP时间同步。如果厂区有NTP服务器在TIA Portal里给PLC和HMI分别配好NTP客户端能省掉大量时间错位的破事。5.2 报警洪泛的处理报警洪泛指一个核心故障引发连锁报警比如总电源跳闸导致十几台设备同时报失电。操作员面对满屏红字第一时间根本找不到根因。处理思路是在报警管理FB里加一个“根因抑制”功能——当某一条高优先级报警触发时自动抑制相关联的低优先级报警的HMI显示。AF框架对这个功能的叫法是“报警抑制组”。我在项目里做法是AlarmSuppressionGroup ├── Group_Power │ ├── Alarm_MainPowerFail (优先级1) │ └── 抑制Device01_LossPower, Device02_LossPower... ├── Group_Air │ ├── Alarm_CompressorFail (优先级1) │ └── 抑制DeviceXX_PressureLow └── Group_Hydraulic └── ...报警抑制不是把被抑制报警彻底删除而是把它们的显示状态设为“被抑制”在后台记录里仍然显示操作员如果主动查看可以展开看到完整列表。5.3 S7-1500的Diagnostic Buffer与应用层报警的关系AF框架第十四章还会带你过一遍S7-1500的系统诊断机制。S7-1500的Diagnostic Buffer记录的是系统级事件比如模块插拔、固件更新、看门狗超时、程序块访问错误等。这些跟应用层报警是两条线。我的经验是现场排查时两条线都要查应用层报警告诉你哪个设备出了问题系统诊断告诉你PLC系统本身有没有异常比如某个分布式IO从站掉线、Profibus诊断信息报出从站故障举例说明现场报“3号工位急停触发”应用层报警能定位到具体工位但为什么会触发急停可能是安全继电器动作也可能是S7-1500 F-CPU诊断缓冲区里有安全程序停止的记录。这时你必须去TIA Portal里在线看CPU的诊断缓冲区把所有SF系统故障指示灯对应的条目截图留存再结合应用层报警一起分析。5.4 与变频器、机器人通讯状态诊断做整线自动化时AF框架的报警体系还必须覆盖通讯类诊断。比如ABB变频器通过PROFINET连到1500或者安川机器人做PROFINET交互这些设备掉线或报故障怎么在报警体系里呈现我的建议是分两层第一层在PLC侧利用I/O设备的硬件中断或DeviceStates指令定期扫描分布式IO和PROFINET设备的在线状态。S7-1500可以调用DPNRM_DIAG或者PROFINET_DeviceState获取设备状态字。一旦检测到设备掉线立即生成一条优先级为1的系统报警“PROFINET设备XX通信中断”这条报警不进设备层的报警列表而是进系统诊断列表。第二层对于变频器或机器人的内部故障比如变频器过流、机器人伺服报警通过PROFINET的报警通道或直接IO映射区读取故障代码再转换成标准报警文本。这样设计的好处是操作员在HMI上一个画面就能看到完整的故障链条机器人伺服报错→机器人通讯正常→变频器过流→变频器通讯正常。而不是只看到机器人停了却不知道是变频器引起的。5.5 WinCC报警变量连接失败TIA Portal里最常见的坑是报警变量连接指向了FB内部变量导致HMI侧报警无法正常显示或触发失灵。这通常是因为你在FB里把报警状态做成局部变量HMI根本访问不到。解决办法就一条所有需要HMI访问的报警变量一律写入共享DB实例禁止走FB的Instance DB局部变量直接连接。AF框架要求报警UDT实例全部放在全局报警DB里底层逻辑就是这个原因。另一个坑是变量连接时勾选了“仅存储器访问”选项。如果你是直接连接共享DB里的绝对地址也行但一旦用到符号寻址尽量保持“符号访问”方式避免绝对地址漂移造成报警数据错乱。5.6 报警测试怎么高效做调试阶段很多人是一个一个信号模拟过去效率极低。我分享一个实用方案做一个专门的报警测试画面上面放一个下拉框列出所有报警ID选中后点击“模拟触发”按钮PLC侧对应报警的触发条件变量强制为TRUE。具体实现是在报警UDT里额外增加一个xAlarmTest字段。报警触发逻辑改成xCondition : xRealCondition OR xAlarmTest;这样做的好处是不需要改设备实际信号生产时测试位永远为FALSE不影响正常逻辑。归档时也可以轻易识别哪些报警是测试产生的做好统计。6. 多语言报警文本的管理经验6.1 文本列表的规划设备出口项目必做中英文切换。AF框架的做法是报警文本不进PLC侧而是全部放在HMI的文本列表里。这样切换语言只需要在WinCC项目里维护一个“报警文本”文本列表不用动PLC程序。文本列表的条目名称建议直接使用报警ID号和PLC里UDT的iAlarmID一一对应。比如AlarmID_1001 电机过载 / Motor Overload AlarmID_1002 液压压力低 / Hydraulic Pressure Low AlarmID_1003 急停被按下 / E-Stop Pressed但这里有个细节容易踩坑WinCC报警控件显示的文本默认取自变量值本身而不是文本列表。你要在报警控件属性里把“显示文本”来源改为“文本列表项”并且配置好对应的列映射关系。否则报警控件显示出来的只会是报警ID的数字操作员一头雾水。6.2 HMI侧脚本切换语言的实现如果项目需要运行中动态切换语言比如操作员从中文切到英文报警控件和画面上的其他文本必须同步刷新。这个功能在TIA Portal里用系统函数SetLanguage实现比较方便。记得切换语言后报警控件里的历史报警文本可能不会立即刷新需要做一次控件的重新加载。这个在WinCC Unified里尤其明显如果是经典WinCC可以接受延迟刷新但Unified项目最好在脚本里主动触发一下报警控件的数据重新载入。7. 关于AF框架报警体系的长期维护思考7.1 报警ID的编码规范报警编码这件事AF框架文档给的是建议但真正要落地还是要结合公司内部规范。我在多年的项目对接中发现报警ID用分段式编码最实用1XXX急停与安全回路 2XXX动力系统电机、变频器 3XXX液压与气动系统 4XXX温度与压力检测 5XXX通讯与IO设备状态 6XXX工艺质量相关 7XXX维护保养提示 8XXX系统信息/提示每个设备再叠加工位号前缀比如301工位的电机过载报警ID就是20301这样从报警ID本身就能反查设备位置现场排查省掉了大量“这个报警是哪个设备的”这类问题。7.2 报警数据的上位机对接如果项目需要把报警数据交给MES或上位机系统AF框架这种把报警全部集中到全局DB的设计就非常友好。只需要将报警DB的对应区域通过OPC UA或PROFINET暴露给上位机就能实现全量报警数据采集而且自己不用写复杂的脚本解析程序。KepServer、Intouch这类软件连接西门子1500时最大的麻烦就是变量分散在几十个DB里而且每个DB的地址不连续。用了AF框架的报警集中式设计你把连续区域的报警数据整体发布出去上位机那边配置一个数据块就够了通讯负载也会低很多。另外通过OPC UA连接1500读取报警数据时要留意1500的OPC UA Server默认只暴露部分DB块如果上位机读不到报警DB要去TIA Portal里把DB块的“Publisher”属性打开或者直接使用S7协议连接KepServer用S7协议连接时没有这个问题只需确保DB不是优化访问阻止了绝对地址。7.3 S7-200 SMART这类小型设备怎么融入报警体系搜索热词里好多人问S7-200 SMART和1500的通讯顺带也会问到小型设备的报警怎么接到中央报警系统。S7-200 SMART没有S7-1500那套完整的Diagnostic Buffer体系也不能直接跑AF框架的UDT和FB结构。但如果你用了S7-200 SMART做从站设备它的报警可以走这两条路通过GET/PUT通讯把S7-200 SMART内部的报警位映射到1500的全局报警DB里由1500统一管理报警文本和优先级如果S7-200 SMART直连HMI比如威纶通触摸屏就让HMI读200SMART的V区地址直接对应报警文本我自己更推荐第一种因为1500统一管理报警便于后期数据采集和归档。S7-200 SMART侧的报警逻辑就用它自带的置位/复位指令做一个简单的报警字然后通过PUT指令先写到1500的接收DB区1500再做数据映射和状态合成。7.4 报警管理是纯技术问题还是管理问题写到这里我越来越觉得AF框架把报警管理放到第十四章是有深意的。单纯从技术角度看报警UDT、FB、HMI控件都是现成的东西拿来就能用。但真正拉开项目差距的是整个团队对报警体系的认知是否统一。我见过有的项目PLC工程师把报警写到程序里HMI工程师从不知道有全局报警DB这回事两个人当场连变量名都对不上。也见过项目经理不重视报警文本整理觉得“能弹出来就行”最后到了验收阶段被客户逐条审报警文本返工到崩溃。AF框架第十四章表面上是技术章节实际上是用技术规范倒逼你建立工程协同秩序。它在告诉你自动化项目进入后半程所有的问题最后都会汇总成一个个报警呈现在操作员面前。报警体系设计得不好哪怕程序逻辑再优秀现场评价依然是一团乱麻。我个人建议做任何项目都按这个节奏推进报警体系的建设项目启动时先定好报警ID分区、优先级定义、确认权限策略写设备FB时同步写报警逻辑不要程序调通了再补报警HMI画面组态时报警模板先行画面再丰富也不能牺牲报警可读性出厂调试完花一整天把所有报警逐个实际触发一遍截图留存作为验收资料交付后三个月内根据现场操作工反馈优化报警文本和优先级设置7.5 最后分享一个小技巧报警状态从PLC传到HMI用的周期建议单独设短一点不要跟普通画面刷新周期一样。我在项目里给报警DB专门设置了一个独立的数据刷新区间例如100到200毫秒这样HMI上的报警闪烁和状态切换比画面其他区域更灵敏操作员感受会明显好很多。如果做的是带多个远程IO站的产线还要注意报警数据跨站通讯的延迟。比如核心报警放在主站1500远程站的报警通过PROFINET传到主站的时间通常有几十毫秒级别的抖动这个正常不需要焦虑。只要时间戳以主站PLC为准报警顺序就不会乱。这些都是我在几个实际项目里磨出来的经验你照着AF框架的思路做下来会发现第十四章学完以后做报警诊断体系不再是一件痛苦的事反而会成为项目里最有成就感的部分——因为整个产线的故障状态就像被一张网兜住了一样每一个都能说清楚、查明白。