• 正文
  • 相关推荐
申请入驻 产业图谱

大众VASS标准:FB_Typ_VAR(FB529)车型匹配功能块深度解读

9小时前
203
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

前几天我们对RFID读取功能块和校验功能块进行了解读

大众VASS标准:FB_Sick_RFU(FB520_RFID数据读取)功能块深度解读

大众VASS标准:FB_Pruefziffer(FB170)校验数据功能块深度解读

今天我们对FB_Typ_VAR(FB529)车辆代码匹配功能块进行详细解读

功能块简介

FB_Typ_VAR(FB529)核心作用是实现对车辆代码(RBS)接收与有效性校验、车型类型匹配评估,并提供可视化交互与故障监控能力。

功能块:

功能块大纲:

1初始化与参数计算

-?数据块缓存:通过`BLKMOV`将`DB_RBS`和`DB_STyp`复制到临时缓存(`tempDB_RBS`/`tempDB_STyp`)

-?参数计算:`iRBSAnz`(RBS位数)、`iRBSLen`(RBS长度,含校验位)、`iTypAnz`(工作站类型条目数)

2?RBS接收与处理

-?指针配置:`anyRBS`指向RBS数据(设置语法ID、数据类型、长度)

-?手动接收:从可视化界面读取RBS字符(`strVisuWertRBS`)或软键输入

-?自动接收:通过`BLKMOV`从RBS数据块自动读取

3?有效性校验

-?RBS校验:逐位匹配`tempDB_RBS`中的有效字符,设置`arrRBS_IO`(位置正常)

-?校验位计算:基于Code39算法,计算`chrPZ`并与输入比对(`xCODE39_IO`)

-?整体有效性:`xRBS_PZ_IO`(RBS+校验位正常)、`xRBS_PZ_NIO`(异常)

4?工作站类型评估

-?匹配逻辑:对比RBS与`tempDB_STyp`中的类型条目,支持占位符`X`/`~`(由`Cfg.X2`控制)

-?状态标志:`xSTyp_IO`(类型正常)、`xSTyp_NIO`(类型异常)

5?接收确认与输出

-?接收触发:自动模式或手动软键触发,设置`xUebern`(RBS已接收)

-?输出映射:`RBS_IO`/`STypIO`等状态输出,`RBS_S1`至`RBS_S8`编码输出

6?可视化与消息系统

-?可视化控制:颜色配置(`bFarbKombi`)、文本更新(多语言支持)

-?故障消息:`MSYS`记录故障源,通过`MeldSend`发送至消息缓冲区

-?故障汇总:`xStoe`(汇总故障)、`VkStoe_Out`(连锁故障)

变量声明:

1.?输入变量(VAR_INPUT)

完整代码解读:

### 西门子SCL功能块FB_Typ_VAR(FB529)详细解读#### 一、版权与版本日志```plaintext******************************************************************************************* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?**** ?Copyright ?2013? ? ? ? ? ? ?SIEMENS AG I IA/DT, D-90475?Nuernberg ? ? ? ? ? ? ? ? ? **** ?All Rights Reserved ? ? ? ? VOLKSWAGEN AG,?38436?Wolfsburg ? ? ? ? ? ? ? ? ? ? ? ? ?**** ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?AUDI AG, D-85045?Ingolstadt ? ? ? ? ? ? ? ? ? ? ? ? ? ? **** ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?********************************************************************************************** ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?**** Aenderungsjournal ?: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ********************************************************************************************** ?Datum ? ? ? Version ? ? Autor ? ? ? Beschreibung ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?**------------------------------------------------------------------------------------------? ??07.09.15? ??3.1.03? ? ? Schulz ? ? ?在有效工作站类型的声明中,'X'可作为占位符;若cfg.x2=true,'~'可作为占位符? ??22.01.15? ??3.1.02? ? ? Schulz ? ? ?移除了德语变音符号? ??06.12.13? ??3.1.02? ? ? Maletz ? ? ?调整了类型错误消息? ??03.12.13? ??3.1.01? ? ? Maletz ? ? ?校验位可关闭(Cfg.X1)? ??21.10.13? ??3.1.00? ? ? Maletz ? ? ?扩展校验位功能;扩展可变RBS长度? ??14.10.13? ??3.0.01? ? ? Maletz ? ? ?调整手动输入? ??20.08.13? ??3.0.00? ? ? Maletz ? ? ?重新创建*****************************************************************************************```**解读**: ?- 版权归属西门子、大众、奥迪公司,功能块用于工业控制场景(推测与汽车生产中的毛坯代码/工作站类型评估相关)。 ?- 版本迭代记录了功能扩展(如校验位、占位符)、bug修复(如变音符号移除)等,最新版本为3.1.03。 ?#### 二、功能块基本信息```sclFUNCTION_BLOCK FB_Typ_VAR ? ?//FB529TITLE ? =?'Version 3.1.03'VERSION :?'3.1'AUTHOR ?: VASS_V05NAME ? ?: TYPVARFAMILY ?: TYPVAR```**解读**: ?- 定义功能块`FB_Typ_VAR`,编号`FB529`,版本3.1.03,作者VASS_V05,名称TYPVAR,属于TYPVAR家族(功能块组)。 ?#### 三、变量声明##### 1. 输入变量(VAR_INPUT)```sclVAR_INPUT? ? Init ? ? ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//初始化(重新读取数据块) ? ? ? ? ? ? ? ?? ? RBS ? ? ? ? ? ? ? ? ? ? : POINTER; ? ? ?//指向UII_RBS起始地址的指针? ? ? ? pRBS AT RBS ? ? ? ? : STRUCT?? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//字节4+5:DB编号?? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//字节6至10:区域指针?? ? ? ? END_STRUCT;? ? DB_RBS ? ? ? ? ? ? ? ? ?: ANY; ? ? ? ? ?//毛坯代码数据块(DB_RBS)? ? ? ? pDB_RBS AT DB_RBS ? : STRUCT?? ? ? ? ? ? BYTE0 ? ? ? ? ? : BYTE; ? ? ? ??//字节0?? ? ? ? ? ? TYP ? ? ? ? ? ? : BYTE; ? ? ? ??//字节1:数据/参数类型?? ? ? ? ? ? ANZ ? ? ? ? ? ? : WORD; ? ? ? ??//字节2+3:变量长度?? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//字节4+5:DB编号?? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//字节6至10:区域指针?? ? ? ? END_STRUCT;?? ? DB_STyp ? ? ? ? ? ? ? ? : ANY; ? ? ? ? ?//工作站类型数据块? ? ? ? pDB_STyp AT DB_STyp : STRUCT?? ? ? ? ? ? BYTE0 ? ? ? ? ? : BYTE; ? ? ? ??//字节0?? ? ? ? ? ? TYP ? ? ? ? ? ? : BYTE; ? ? ? ??//字节1:数据/参数类型?? ? ? ? ? ? ANZ ? ? ? ? ? ? : WORD; ? ? ? ??//字节2+3:变量长度?? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//字节4+5:DB编号?? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//字节6至10:区域指针?? ? ? ? END_STRUCT;?? ? Sprache ? ? ? ? ? ? ? ? : INT; ? ? ? ? ?//语言(1:德语;2:其他语言;3:中文)? ? Auto ? ? ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//自动类型评估使能?? ? Hand ? ? ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//手动类型评估使能? ? FM_Reset ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//清除类型接收标志? ? _Cfg ? ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//配置字(X0:评估DB_RBS预设位置2-x;X1:无校验位;X2:占位符'~'替代'X')? ? ? ? Cfg AT _Cfg ? ? ? ? : STRUCT ? ? ? ?//WORD拆分为BOOL? ? ? ? ? ? X8 ? ? ? ? ? ? ?: BOOL;? ? ? ? ? ? X9 ? ? ? ? ? ? ?: BOOL;? ? ? ? ? ? X10 ? ? ? ? ? ? : BOOL;? ? ? ? ? ? X11 ? ? ? ? ? ? : BOOL;? ? ? ? ? ? X12 ? ? ? ? ? ? : BOOL;? ? ? ? ? ? X13 ? ? ? ? ? ? : BOOL;? ? ? ? ? ? X14 ? ? ? ? ? ? : BOOL;? ? ? ? ? ? X15 ? ? ? ? ? ? : BOOL;? ? ? ? ? ? X0 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//评估DB_RBS预设位置2-x? ? ? ? ? ? X1 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//无校验位? ? ? ? ? ? X2 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//工作站类型评估:用'~'作为占位符(替代'X')? ? ? ? ? ? X3 ? ? ? ? ? ? ?: BOOL;? ? ? ? ? ? X4 ? ? ? ? ? ? ?: BOOL;? ? ? ? ? ? X5 ? ? ? ? ? ? ?: BOOL;? ? ? ? ? ? X6 ? ? ? ? ? ? ?: BOOL;? ? ? ? ? ? X7 ? ? ? ? ? ? ?: BOOL;? ? ? ? END_STRUCT;? ? VkStoe_In ? ? ? ? ? ? ? : BOOL; ? ? ? ??//连锁故障输入?END_VAR```**解读**: ?- `Init`:触发数据块重新读取(初始化)。 ?- `RBS`:指针类型,通过`pRBS`结构体解析为`DBNR`(数据块编号)和`BZ`(区域指针,指向数据存储位置),用于定位毛坯代码(RBS)数据。 ?- `DB_RBS`/`DB_STyp`:`ANY`类型(任意数据类型指针),分别指向毛坯代码和工作站类型的数据块,通过`pDB_RBS`/`pDB_STyp`解析内部结构(含长度、DB编号等元数据)。 ?- `Sprache`:设置语言(支持中文)。 ?- `Auto`/`Hand`:自动/手动模式使能,控制类型评估方式。 ?- `FM_Reset`:清除“类型已接收”标志(`FM`)。 ?- `_Cfg`:配置字,通过`Cfg`结构体拆分为16个BOOL位,分别控制功能(如`X1`关闭校验位,`X2`切换占位符)。 ?- `VkStoe_In`:外部连锁故障输入,用于故障传递。 ?##### 2. 输出变量(VAR_OUTPUT)```sclVAR_OUTPUT? ? FM ? ? ? ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//毛坯代码已接收?? ? RBS_IO ? ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//毛坯代码正常?? ? RBS_NIO ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//毛坯代码异常? ? STypIO ? ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//工作站类型正常?? ? STypNIO ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//工作站类型异常? ? Data ? ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//工作站类型数据? ? RBS_S1 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位1(位编码)? ? RBS_S2 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位2(位编码)? ? RBS_S3 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位3(位编码)? ? RBS_S4 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位4(位编码)? ? RBS_S5 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位5(位编码)? ? RBS_S6 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位6(位编码)? ? RBS_S7 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位7(位编码)? ? RBS_S8 ? ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//毛坯代码位8(位编码)? ? Stoe ? ? ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//汇总故障?? ? VkStoe_Out ? ? ? ? ? ? ?: BOOL; ? ? ? ??//连锁故障输出?END_VAR```**解读**: ?- `FM`:毛坯代码成功接收标志。 ?- `RBS_IO`/`RBS_NIO`:毛坯代码是否有效(正常/异常)。 ?- `STypIO`/`STypNIO`:工作站类型是否有效(正常/异常)。 ?- `Data`:工作站类型对应的输出数据。 ?- `RBS_S1`至`RBS_S8`:毛坯代码各位置的位编码(用于外部传递具体位状态)。 ?- `Stoe`:汇总故障标志(所有故障的OR结果)。 ?- `VkStoe_Out`:连锁故障输出(输入故障与内部故障的OR结果)。 ?##### 3. 输入输出变量(VAR_IN_OUT)```sclVAR_IN_OUT? ? ST_Meld ? ? ? ? ? ? ? ? : Meldungspuffer; ??//消息缓冲区(消息结构体)END_VAR```**解读**: ?- `ST_Meld`:消息缓冲区,用于传递故障/状态消息(与消息系统交互)。 ?##### 4. 临时变量(VAR_Temp)```sclVAR_Temp? ? TempPointerMsys ? ? ? ? : ANY; ? ? ? ? ?//消息系统辅助指针? ? TempPointerFlanken ? ? ?: ANY; ? ? ? ? ?//边沿检测辅助指针? ? TempPointerMeldpuffer ? : ANY; ? ? ? ? ?//消息缓冲区辅助指针? ? erg_SFC20 ? ? ? ? ? ? ? : INT; ? ? ? ? ?//SFC20(块移动指令)返回值? ? pMeldFeld AT TempPointerMsys: STRUCT?? ? ? ? BYTE0 ? ? ? ? ? ? ? : BYTE; ? ? ? ??//字节0?? ? ? ? TYP ? ? ? ? ? ? ? ? : BYTE; ? ? ? ??//字节1:数据/参数类型?? ? ? ? ANZ ? ? ? ? ? ? ? ? : WORD; ? ? ? ??//字节2+3:变量长度?? ? ? ? DBNR ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//字节4+5:DB编号?? ? ? ? BZ ? ? ? ? ? ? ? ? ?: DWORD; ? ? ? ?//字节6至10:区域指针?? ? END_STRUCT;?? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? pMeldAbb AT TempPointerFlanken: STRUCT?? ? ? ? BYTE0 ? ? ? ? ? ? ? : BYTE; ? ? ? ??//字节0?? ? ? ? TYP ? ? ? ? ? ? ? ? : BYTE; ? ? ? ??//字节1:数据/参数类型?? ? ? ? ANZ ? ? ? ? ? ? ? ? : WORD; ? ? ? ??//字节2+3:变量长度?? ? ? ? DBNR ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//字节4+5:DB编号?? ? ? ? BZ ? ? ? ? ? ? ? ? ?: DWORD; ? ? ? ?//字节6至10:区域指针?? ? END_STRUCT;? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? pMeldDBNR AT TempPointerMeldpuffer: STRUCT?? ? ? ? BYTE0 ? ? ? ? ? ? ? : BYTE; ? ? ? ??//字节0?? ? ? ? TYP ? ? ? ? ? ? ? ? : BYTE; ? ? ? ??//字节1:数据/参数类型?? ? ? ? ANZ ? ? ? ? ? ? ? ? : WORD; ? ? ? ??//字节2+3:变量长度?? ? ? ? DBNR ? ? ? ? ? ? ? ?: WORD; ? ? ? ??//字节4+5:DB编号?? ? ? ? BZ ? ? ? ? ? ? ? ? ?: DWORD; ? ? ? ?//字节6至10:区域指针?? ? END_STRUCT;? ? bFarbKombi ? ? ? ? ? ? ?: BYTE; ? ? ? ??//可视化颜色组合? ? iAdr_RBS ? ? ? ? ? ? ? ?: INT; ? ? ? ? ?//RBS字节地址? ? anyRBS ? ? ? ? ? ? ? ? ?: ANY; ? ? ? ? ?//RBS辅助ANY指针? ? ? ? p_RBS AT anyRBS ? ? : STRUCT?? ? ? ? ? ? SyntaxId ? ? ? ?: BYTE; ? ? ? ??//字节0:语法ID(固定为16#10)? ? ? ? ? ? DataType ? ? ? ?: BYTE; ? ? ? ??//字节1:数据类型(如02=BYTE)? ? ? ? ? ? DataCount ? ? ? : WORD; ? ? ? ??//字节2+3:重复次数(长度)? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//字节4+5:DB编号?? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//字节6至10:区域指针?? ? ? ? END_STRUCT;?? ? anyDB_RBS1 ? ? ? ? ? ? ?: ANY; ? ? ? ? ?//DB_RBS辅助指针1? ? ? ? p_DB_RBS1 AT anyDB_RBS1 ? : STRUCT?? ? ? ? ? ? SyntaxId ? ? ? ?: BYTE; ? ? ? ??//语法ID? ? ? ? ? ? DataType ? ? ? ?: BYTE; ? ? ? ??//数据类型? ? ? ? ? ? DataCount ? ? ? : WORD; ? ? ? ??//长度? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//DB编号? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//区域指针? ? ? ? END_STRUCT;?? ? anyDB_RBS2 ? ? ? ? ? ? ?: ANY; ? ? ? ? ?//DB_RBS辅助指针2? ? ? ? p_DB_RBS2 AT anyDB_RBS2 ? : STRUCT?? ? ? ? ? ? SyntaxId ? ? ? ?: BYTE; ? ? ? ??//语法ID? ? ? ? ? ? DataType ? ? ? ?: BYTE; ? ? ? ??//数据类型? ? ? ? ? ? DataCount ? ? ? : WORD; ? ? ? ??//长度? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//DB编号? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//区域指针? ? ? ? END_STRUCT;?? ? anyQRBS_S ? ? ? ? ? ? ? : ANY; ? ? ? ? ?//RBS_S源指针? ? ? ? p_QRBS_S AT anyQRBS_S : STRUCT?? ? ? ? ? ? SyntaxId ? ? ? ?: BYTE; ? ? ? ??//语法ID? ? ? ? ? ? DataType ? ? ? ?: BYTE; ? ? ? ??//数据类型? ? ? ? ? ? DataCount ? ? ? : WORD; ? ? ? ??//长度? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//DB编号? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//区域指针? ? ? ? END_STRUCT;?? ? anyZRBS_S ? ? ? ? ? ? ? : ANY; ? ? ? ? ?//RBS_S目标指针? ? ? ? p_ZRBS_S AT anyZRBS_S : STRUCT?? ? ? ? ? ? SyntaxId ? ? ? ?: BYTE; ? ? ? ??//语法ID? ? ? ? ? ? DataType ? ? ? ?: BYTE; ? ? ? ??//数据类型? ? ? ? ? ? DataCount ? ? ? : WORD; ? ? ? ??//长度? ? ? ? ? ? DBNR ? ? ? ? ? ?: WORD; ? ? ? ??//DB编号? ? ? ? ? ? BZ ? ? ? ? ? ? ?: DWORD; ? ? ? ?//区域指针? ? ? ? END_STRUCT;?END_VAR```**解读**: ?- 临时变量用于中间计算,如`erg_SFC20`存储块移动指令的返回值(0表示成功);`anyRBS`系列指针用于动态定位数据块中的数据;`bFarbKombi`控制可视化界面的颜色(如正常为绿色,故障为红色)。 ?##### 5. 静态变量(VAR)```sclVAR? ? _dwVisuWerte1 ? ? ? ? ? : DWORD; ? ? ? ?//可视化状态双字1?? ? ? ? dwVisuWerte1 AT _dwVisuWerte1: STRUCT ??//DWORD拆分为BOOL/字节? ? ? ? ? ? B3 ? ? ? ? ? ? ?: BYTE; ? ? ? ??//可视化符号03边框(0..3)? ? ? ? ? ? B2 ? ? ? ? ? ? ?: BYTE; ? ? ? ??//可视化符号10边框(0..3)? ? ? ? ? ? X8 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//预留? ? ? ? ? ? X9 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//预留? ? ? ? ? ? X10 ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? ? ? X11 ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? ? ? X12 ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? ? ? X13 ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? ? ? X14 ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? ? ? X15 ? ? ? ? ? ? : BOOL; ? ? ? ??//手动输入RBS接收标志? ? ? ? ? ? X0 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//预留? ? ? ? ? ? X1 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//预留? ? ? ? ? ? X2 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//预留? ? ? ? ? ? X3 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//RBS位1故障闪烁? ? ? ? ? ? X4 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//RBS位2故障闪烁? ? ? ? ? ? X5 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//RBS位3故障闪烁? ? ? ? ? ? X6 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//RBS位4故障闪烁? ? ? ? ? ? X7 ? ? ? ? ? ? ?: BOOL; ? ? ? ??//RBS位5故障闪烁? ? ? ? END_STRUCT;? ? _dwVisuWerte2 ? ? ? ? ? : DWORD; ? ? ? ?//可视化状态双字2?? ? ? ? dwVisuWerte2 AT _dwVisuWerte2: STRUCT ??//DWORD拆分为字节? ? ? ? ? ? B3 ? ? ? ? ? ? ?: BYTE; ? ? ? ??//校验位按钮颜色? ? ? ? ? ? B2 ? ? ? ? ? ? ?: BYTE; ? ? ? ??//OK按钮颜色? ? ? ? ? ? B1 ? ? ? ? ? ? ?: BYTE; ? ? ? ??//RBS/工作站类型显示(0..3/4..7)? ? ? ? ? ? B0 ? ? ? ? ? ? ?: BYTE; ? ? ? ??//手动/自动显示(0..3/4..7)? ? ? ? END_STRUCT;? ? _strVisuWertRBS ? ? ? ? : STRING[10] :=?'**********';?//可视化RBS字符串? ? ? ? strVisuWertRBS AT _strVisuWertRBS: STRUCT ??//字符串结构? ? ? ? ? ? bMax ? ? ? ? ? ?: BYTE; ? ? ? ??//最大长度? ? ? ? ? ? bAct ? ? ? ? ? ?: BYTE; ? ? ? ??//实际长度? ? ? ? ? ? arrText ? ? ? ? : ARRAY[1..10] OF CHAR;?//RBS字符数组? ? ? ? END_STRUCT;? ? _strVisuWertPZ ? ? ? ? ?: STRING[2] :=?'*';?//可视化校验位字符串? ? ? ? strVisuWertPZ AT _strVisuWertPZ: STRUCT ? ??//校验位结构? ? ? ? ? ? bMax ? ? ? ? ? ?: BYTE; ? ? ? ??//最大长度? ? ? ? ? ? bAct ? ? ? ? ? ?: BYTE; ? ? ? ??//实际长度? ? ? ? ? ? arrText ? ? ? ? : ARRAY[1..2] OF CHAR;?//校验位字符? ? ? ? END_STRUCT;? ? bVisuTasten ? ? ? ? ? ? : BYTE; ? ? ? ??//可视化软键输入? ? strVisuText ? ? ? ? ? ? : STRUCT ? ? ? ?//可视化文本结构? ? ? ? S ? ? ? ? ? ? ? ? ? : ARRAY[1..8] OF STRUCT? ? ? ? ? ? Bez ? ? ? ? ? ? : STRING[20]; ?//标题? ? ? ? ? ? Z ? ? ? ? ? ? ? : ARRAY[1..16] OF STRUCT? ? ? ? ? ? ? ? Bez ? ? ? ? : STRING[30]; ?//按键文本? ? ? ? ? ? END_STRUCT;?? ? ? ? END_STRUCT;?? ? END_STRUCT;?? ? iVisuTastenS ? ? ? ? ? ?: ARRAY[1..8] OF INT; ??//可视化软键输入值(****************************************************************************************)(*****************************Anfang Variablendeklaration********************************)(*********************************fuers Meldesystem**************************************)(****************************************************************************************)? ? MSYS ? ? ? ? ? ? ? ? ? ?: STRUCT ? ? ? ?//消息系统标志? ? ? ? xF_1 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志1(RBS位1异常)? ? ? ? xF_2 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志2(RBS位2异常)? ? ? ? xF_3 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志3(RBS位3异常)? ? ? ? xF_4 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志4(RBS位4异常)? ? ? ? xF_5 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志5(RBS位5异常)? ? ? ? xF_6 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志6(RBS位6异常)? ? ? ? xF_7 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志7(RBS位7异常)? ? ? ? xF_8 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志8(RBS位8异常)? ? ? ? xF_9 ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//故障标志9(工作站类型无效)? ? ? ? xF_10 ? ? ? ? ? ? ? : BOOL; ? ? ? ??//故障标志10(校验位异常)? ? ? ? xF_11 ? ? ? ? ? ? ? : BOOL; ? ? ? ??//故障标志11(手动输入激活)? ? ? ? xF_12 ? ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? xF_13 ? ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? xF_14 ? ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? xF_15 ? ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? xF_16 ? ? ? ? ? ? ? : BOOL; ? ? ? ??//预留? ? ? ? Flanken ? ? ? ? ? ? : ARRAY[0..1] OF BYTE; ? ?//边沿检测字节? ? END_STRUCT;? ? AenderungsID ? ? ? ? ? ?: STRUCT ? ? ? ?//版本ID? ? ? ? SNr ? ? ? ? ? ? ? ? : WORD; ? ? ? ??//序列号? ? ? ? ANr ? ? ? ? ? ? ? ? : BYTE; ? ? ? ??//编号? ? ? ? Detail ? ? ? ? ? ? ?: BYTE; ? ? ? ??//细节? ? END_STRUCT;? ? xIntegritaet ? ? ? ? ? ?: BOOL; ? ? ? ??//完整性标志(消息系统)(****************************************************************************************)(*****************************Ende Variablendeklaration**********************************)(*********************************fuers Meldesystem**************************************)(****************************************************************************************)? ? xStoe ? ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//故障消息激活? ? xWarn ? ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//警告消息激活? ? xWart ? ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//维护消息激活? ? xInit ? ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//初始化完成标志? ? iStart ? ? ? ? ? ? ? ? ?: INT; ? ? ? ? ?//起始地址? ? iLetzter ? ? ? ? ? ? ? ?: INT; ? ? ? ? ?//结束地址? ? iLauf ? ? ? ? ? ? ? ? ? : INT; ? ? ? ? ?//循环变量1? ? i ? ? ? ? ? ? ? ? ? ? ? : INT; ? ? ? ? ?//循环变量2? ? iRBSAnz ? ? ? ? ? ? ? ? : INT :=?4; ? ??//毛坯代码位数(默认4位)? ? iTypAnz ? ? ? ? ? ? ? ? : INT :=?1; ? ??//工作站类型DB条目数(默认1)? ? iRBSLen ? ? ? ? ? ? ? ? : INT :=?5; ? ??//毛坯代码长度(含校验位,默认5)? ? iSicht_RBS ? ? ? ? ? ? ?: INT; ? ? ? ? ?//RBS位2-x的偏移量? ? iBer_RBS ? ? ? ? ? ? ? ?: INT; ? ? ? ? ?//RBS位2-x的区域长度? ? arrRBS ? ? ? ? ? ? ? ? ?: ARRAY[1..10] OF CHAR;?//毛坯代码字符数组? ? arrTemp ? ? ? ? ? ? ? ? : ARRAY[1..8] OF BOOL; ?//辅助布尔数组? ? arrRBS_IO ? ? ? ? ? ? ? : ARRAY[1..8] OF BOOL; ?//RBS各位置正常标志? ? arrRBS_NIO ? ? ? ? ? ? ?: ARRAY[1..8] OF BOOL; ?//RBS各位置异常标志? ? xRBS_IO ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//RBS整体正常? ? xRBS_NIO ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//RBS整体异常? ? xRBS_PZ_IO ? ? ? ? ? ? ?: BOOL; ? ? ? ??//RBS+校验位正常? ? xRBS_PZ_NIO ? ? ? ? ? ? : BOOL; ? ? ? ??//RBS+校验位异常? ? xUebern ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//RBS已接收标志? ? xS_TypFrg ? ? ? ? ? ? ? : BOOL; ? ? ? ??//类型输入接收按钮? ? xS_UebPZ ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//校验位接收按钮? ? xHand ? ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//手动接收标志? ? xAuto ? ? ? ? ? ? ? ? ? : BOOL; ? ? ? ??//自动接收标志? ? arrSTyp_IO ? ? ? ? ? ? ?: ARRAY[1..8] OF BOOL; ?//工作站类型各位置正常? ? arrSTyp_NIO ? ? ? ? ? ? : ARRAY[1..8] OF BOOL; ?//工作站类型各位置异常? ? xSTyp_IO ? ? ? ? ? ? ? ?: BOOL; ? ? ? ??//工作站类型整体正常? ? xSTyp_NIO ? ? ? ? ? ? ? : BOOL; ? ? ? ??//工作站类型整体异常? ? iZyklus ? ? ? ? ? ? ? ? : INT :=?1; ? ??//循环计数器(优化周期)? ? iZyklus16 ? ? ? ? ? ? ? : INT :=?1; ? ??//循环计数器(16分频)? ? wData ? ? ? ? ? ? ? ? ? : WORD; ? ? ? ??//工作站类型数据(内部)? ? ? ? _wData AT wData ? ? : STRUCT ? ? ? ?? ? ? ? ? ? IO ? ? ? ? ? ? ?: BOOL; ? ? ? ?//工作站类型有效标志? ? ? ? END_STRUCT;? ? arrCode_RBS ? ? ? ? ? ? : ARRAY[1..9] OF INT;?//RBS字符的Code39编码值? ? chrPZ ? ? ? ? ? ? ? ? ? : CHAR; ? ? ? ??//计算出的校验位? ? iCharCode39 ? ? ? ? ? ? : INT; ? ? ? ? ?//Code39编码总和? ? iMOD_39 ? ? ? ? ? ? ? ? : INT; ? ? ? ? ?//Code39编码总和模43结果? ? xCODE39_IO ? ? ? ? ? ? ?: BOOL; ? ? ? ??//Code39校验正常? ? xCODE39_NIO ? ? ? ? ? ? : BOOL; ? ? ? ??//Code39校验异常? ? R_TRIG_S_TypFrg_Q ? ? ? : BOOL; ? ? ? ??//xS_TypFrg的上升沿? ? xR_TRIG_S_TypFrg_Edge ? : BOOL; ? ? ? ??//xS_TypFrg的边沿记忆? ? R_TRIG_Uebern ? ? ? ? ? : BOOL; ? ? ? ??//xUebern的上升沿? ? xR_TRIG_Uebern ? ? ? ? ?: BOOL; ? ? ? ??//xUebern的边沿记忆? ? R_TRIG_Auto_Q ? ? ? ? ? : BOOL; ? ? ? ??//Auto的上升沿? ? xR_TRIG_Auto_Q_Edge ? ? : BOOL; ? ? ? ??//Auto的边沿记忆? ? tempDB_RBS ? ? ? ? ? ? ?: STRUCT ? ? ? ?//RBS数据块缓存? ? ? ? Z ? ? ? ? ? ? ? ? ? : ARRAY[1..8] OF STRUCT? ? ? ? ? ? Bez ? ? ? ? ? ? : ARRAY[1..3] OF STRING[20];?//各位置标题(3种语言)? ? ? ? ? ? Z ? ? ? ? ? ? ? : ARRAY[1..16] OF STRUCT ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? CH ? ? ? ? ?: CHAR; ? ? ? ?//字符? ? ? ? ? ? ? ? Frg ? ? ? ? : BOOL; ? ? ? ?//有效标志? ? ? ? ? ? ? ? Sicht_RBS ? : INT; ? ? ? ??//RBS可见性偏移? ? ? ? ? ? ? ? Bez ? ? ? ? : ARRAY[1..3] OF STRING[30];?//字符描述(3种语言)? ? ? ? ? ? END_STRUCT;? ? ? ? END_STRUCT;? ? END_STRUCT;? ? tempDB_STyp ? ? ? ? ? ? : STRUCT ? ? ? ?//工作站类型数据块缓存? ? ? ? Typ ? ? ? ? ? ? ? ? : ARRAY[1..100] OF STRUCT? ? ? ? ? ? bMax ? ? ? ? ? ?: BYTE; ? ? ? ?//最大长度? ? ? ? ? ? bAct ? ? ? ? ? ?: BYTE; ? ? ? ?//实际长度? ? ? ? ? ? arrText ? ? ? ? : ARRAY[1..8] OF CHAR;?//类型字符数组? ? ? ? ? ? Data ? ? ? ? ? ?: STRUCT? ? ? ? ? ? ? ? IO ? ? ? ? ?: BOOL; ? ? ? ?//类型有效标志? ? ? ? ? ? END_STRUCT;? ? ? ? END_STRUCT;? ? END_STRUCT;END_VAR```**解读**: ?- 静态变量用于存储持久化状态(功能块调用间保持值),如`_dwVisuWerte1`/`_dwVisuWerte2`控制可视化界面的状态(颜色、闪烁等);`arrRBS`存储当前读取的毛坯代码字符;`tempDB_RBS`/`tempDB_STyp`缓存数据块内容(避免频繁读取DB);`arrCode_RBS`存储RBS字符的Code39编码(用于校验位计算)。 ?#### 四、代码主体解读##### 1. 数据块初始化与参数计算```scl(* 数据块读取 *)IF Init OR NOT xInit OR?"Neustart"?THEN? ? erg_SFC20:=?BLKMOV(srcblk:= DB_RBS ?,?dstblk:= tempDB_RBS); ?//将DB_RBS复制到缓存tempDB_RBS? ? erg_SFC20:=?BLKMOV(srcblk:= DB_STyp ,?dstblk:= tempDB_STyp);?//将DB_STyp复制到缓存tempDB_STyp(* 计算毛坯代码位数 *)? ? iRBSAnz :=?WORD_TO_INT(pDB_RBS.Anz) /?1666; ?//pDB_RBS.Anz是DB_RBS的总长度,1666为单个位的长度(* 计算毛坯代码长度(带/不带校验位) *)? ? IF Cfg.X1 THEN ?//Cfg.X1=1:不使用校验位? ? ? ? iRBSLen := iRBSAnz;? ? ELSE ?//使用校验位:长度=位数+1? ? ? ? iRBSLen := iRBSAnz +?1;? ? END_IF;(* 计算工作站类型DB中的条目数 *)? ? iTypAnz :=?WORD_TO_INT(pDB_STyp.Anz) /?12; ?//pDB_STyp.Anz是DB_STyp的总长度,12为单个条目的长度END_IF;```**解读**: ?- 当`Init`触发、未初始化(`xInit=0`)或系统重启(`Neustart`)时,通过`BLKMOV`(块移动指令)将`DB_RBS`(毛坯代码数据块)和`DB_STyp`(工作站类型数据块)的数据缓存到`tempDB_RBS`和`tempDB_STyp`(减少对实际DB的访问)。 ?- 计算核心参数:`iRBSAnz`(毛坯代码的位数)、`iRBSLen`(带/不带校验位的总长度)、`iTypAnz`(工作站类型的条目数量)。 ?##### 2. 配置RBS数据的ANY指针```scl(* 设置ANY指针到RBS数据 *)p_RBS.SyntaxId ? ? := B#16#10; ? ? ? ? ? ? ? ? ? ? //ANY指针的语法ID固定为16#10p_RBS.DataType ? ? :=?02; ? ? ? ? ? ? ? ? ? ? ? ? ?//数据类型:02=BYTE(RBS为字符,按字节存储)p_RBS.DataCount ? ?:=?INT_TO_WORD(iRBSLen); ? ? ? ?//长度:RBS的总长度(含校验位)?p_RBS.DBNR ? ? ? ? := pRBS.DBNR; ? ? ? ? ? ? ? ? ??//DB编号:从RBS指针获取p_RBS.BZ ? ? ? ? ? := pRBS.BZ; ? ? ? ? ? ? ? ? ? ??//区域指针:从RBS指针获取```**解读**: ?- 配置`anyRBS`指针(`p_RBS`)指向实际的RBS数据,`SyntaxId=16#10`是西门子ANY指针的固定格式,`DataType=02`表示数据为字节类型,`DataCount`为RBS的长度。 ?##### 3. 可视化按键评估```scl(******* 按键评估 ****************************************************************)IF PC_AKTIV = DWORD#16#00000000 THEN ?//PC未激活时,软键输入清零? ? bVisuTasten := Byte#0;END_IF;xS_UebPZ ? ?:= (bVisuTasten = Byte#1); ?//bVisuTasten=1:校验位接收按键xS_TypFrg ? := (bVisuTasten = Byte#2); ?//bVisuTasten=2:类型输入接收按键```**解读**: ?- 读取可视化界面的软键输入(`bVisuTasten`),映射为具体功能:`xS_UebPZ`(校验位接收)和`xS_TypFrg`(类型输入接收)。 ?##### 4. 上升沿检测```scl(******* 上升沿检测 ***************************************************************)R_TRIG_S_TypFrg_Q ? ? ? := xS_TypFrg AND NOT xR_TRIG_S_TypFrg_Edge; ?//xS_TypFrg的上升沿(单次触发)xR_TRIG_S_TypFrg_Edge ? := xS_TypFrg; ?//记忆xS_TypFrg的当前状态R_TRIG_Auto_Q ? ? ? ? ? := Auto AND NOT xR_TRIG_Auto_Q_Edge; ?//Auto的上升沿(单次触发)xR_TRIG_Auto_Q_Edge ? ? := Auto; ?//记忆Auto的当前状态```**解读**: ?- 通过“当前值为1且前值为0”检测上升沿,确保`xS_TypFrg`(类型接收)和`Auto`(自动模式使能)的触发信号仅有效一次(避免持续触发)。 ?##### 5. 重置接收标志```scl(******* 重置接收 ***************************************************************)IF?FM_Reset OR?(NOT Hand AND R_TRIG_Auto_Q) THEN? ? xUebern ? ? ? ? := False; ?//清除RBS已接收标志END_IF;```**解读**: ?- 当`FM_Reset`(重置命令)触发,或切换到自动模式(`Hand=0`且`Auto`上升沿)时,清除`xUebern`(RBS已接收标志),允许重新接收RBS。 ?##### 6. RBS接收(手动/自动模式)```scl(******* RBS接收 *****************************************************************)//手动RBS接收IF NOT xUebern AND Hand THEN ?//未接收且手动模式使能? ? IF dwVisuWerte1.X15 THEN ? ? ? ?//手动字符串输入接收标志触发? ? ? ? arrRBS ? ? ?:= strVisuWertRBS.arrText; ?//从可视化字符串读取RBS字符? ? ? ? dwVisuWerte1.X15 := False; ?//清除标志? ? ELSE?? ? ? ? FOR iLauf :=?1?TO iRBSAnz BY?1?DO ?//循环读取各位置? ? ? ? ? ? IF iVisuTastenS[iLauf] >=?1?AND iVisuTastenS[iLauf] <=?16?THEN ?//软键输入有效? ? ? ? ? ? ? ? arrRBS[iLauf] := tempDB_RBS.Z[iLauf].Z[iVisuTastenS[iLauf]].CH;?//从缓存读取对应字符? ? ? ? ? ? ELSE? ? ? ? ? ? ? ? arrRBS[iLauf] :=?'*'; ?//无效输入用'*'表示? ? ? ? ? ? END_IF;? ? ? ? END_FOR;? ? ? ? IF NOT Cfg.X1 THEN?//使用校验位时? ? ? ? ? ? IF xS_UebPZ AND xRBS_IO THEN?//校验位接收按键触发且RBS有效? ? ? ? ? ? ? ? arrRBS[iRBSLen] ? := chrPZ; ?//用计算出的校验位填充? ? ? ? ? ? ELSIF arrRBS[iRBSLen] <> chrPZ THEN ?//输入校验位与计算值不符? ? ? ? ? ? ? ? arrRBS[iRBSLen] :=?'*'; ?//标记异常? ? ? ? ? ? END_IF;? ? ? ? END_IF;? ? END_IF;//自动RBS接收ELSIF NOT xUebern AND Auto THEN ?//未接收且自动模式使能? ? erg_SFC20 :=?BLKMOV(SRCBLK := anyRBS ,DSTBLK := arrRBS); ?//从RBS数据块自动读取字符END_IF; ? ?```**解读**: ?- **手动模式**:通过可视化界面输入RBS,支持两种方式:直接输入字符串(`dwVisuWerte1.X15`触发)或通过软键选择字符(`iVisuTastenS`),无效输入用`*`标记;若启用校验位,需匹配计算出的`chrPZ`。 ?- **自动模式**:通过`BLKMOV`从`anyRBS`指向的RBS数据块自动读取字符到`arrRBS`。 ?##### 7. RBS预设位置评估(位置1)```scl(******* 评估RBS预设位置1?********************************************************)anyDB_RBS1 := DB_RBS; ?//指向原始DB_RBSanyDB_RBS2 := tempDB_RBS.Z[2]; ?//指向缓存中RBS的位置2IF Cfg.X0 THEN ?//Cfg.X0=1:需评估DB_RBS的预设位置2-x? ? FOR i :=?1?TO?16?BY?1?DO ?//循环匹配位置1的字符? ? ? ? IF tempDB_RBS.Z[1].Z[i].CH = arrRBS[1] THEN ?//位置1字符匹配? ? ? ? ? ? iSicht_RBS := tempDB_RBS.Z[1].Z[i].Sicht_RBS; ?//获取可见性偏移? ? ? ? ? ? iBer_RBS ? :=?1666?* (iRBSAnz -?1); ?//计算区域长度(位置2-x的总长度)? ? ? ? ? ?? ? ? ? ? ? p_DB_RBS1.DataCount :=?INT_TO_WORD(iBer_RBS); ?//设置数据长度? ? ? ? ? ??//调整区域指针(指向位置2-x的起始地址)? ? ? ? ? ? p_DB_RBS1.BZ :=?16#84000000 OR SHL(IN:=INT_TO_DWORD(1666 + (iBer_RBS * iSicht_RBS)),N:=3);?? ? ? ? ? ? p_DB_RBS2.DataCount :=?INT_TO_WORD(iBer_RBS); ?//缓存中位置2-x的长度? ? ? ? ? ? p_DB_RBS2.BZ := p_DB_RBS2.BZ OR?16#1000000; ?//调整区域指针(从DB到DI)? ? ? ? ? ? erg_SFC20:=?BLKMOV(srcblk:= anyDB_RBS1 ?,?dstblk:= anyDB_RBS2); ?//更新缓存中位置2-x的数据? ? ? ? END_IF;? ? END_FOR;END_IF;```**解读**: ?- 当`Cfg.X0=1`时,需根据RBS位置1的字符匹配预设规则,动态更新位置2-x的数据(从`DB_RBS`复制到缓存`tempDB_RBS.Z[2]`),实现灵活的RBS结构适配。 ?##### 8. 重置与初始化```scl(****** 重置 ***************************************************************************)IF NOT xUebern OR FM_Reset THEN ?//未接收或重置时? ? arrRBS_IO ? ? ? := arrTemp; ?//清空RBS各位置正常标志? ? xRBS_IO ? ? ? ? := False; ?//RBS整体正常标志清零? ? xRBS_NIO ? ? ? ?:= False; ?//RBS整体异常标志清零? ? xRBS_PZ_IO ? ? ?:= False; ?//RBS+校验位正常标志清零? ? xRBS_PZ_NIO ? ? := False; ?//RBS+校验位异常标志清零? ? iVisuTastenS[1] :=?0; ?//软键输入值清零(位置1)? ? iVisuTastenS[2] :=?0; ?//位置2? ? iVisuTastenS[3] :=?0; ?//位置3? ? iVisuTastenS[4] :=?0; ?//位置4? ? iVisuTastenS[5] :=?0; ?//位置5? ? iVisuTastenS[6] :=?0; ?//位置6? ? iVisuTastenS[7] :=?0; ?//位置7? ? iVisuTastenS[8] :=?0; ?//位置8? ? CASE iRBSLen OF ?//根据RBS长度初始化可视化字符串? ? ? ??4?: _strVisuWertRBS :=?'****';? ? ? ??5?: _strVisuWertRBS :=?'*****';? ? ? ??6?: _strVisuWertRBS :=?'******';? ? ? ??7?: _strVisuWertRBS :=?'*******';? ? ? ??8?: _strVisuWertRBS :=?'********';? ? ? ??9?: _strVisuWertRBS :=?'*********';? ? END_CASE;? ? _strVisuWertPZ ?:=?'*'; ?//校验位可视化字符串初始化? ? arrSTyp_IO ? ? ?:= arrTemp; ?//清空工作站类型各位置正常标志? ? xSTyp_IO ? ? ? ?:= False; ?//工作站类型整体正常标志清零? ? xSTyp_NIO ? ? ? := False; ?//工作站类型整体异常标志清零? ? wData ? ? ? ? ? := Word#0; ?//工作站类型数据清零? ? xCODE39_IO ? ? ?:= False; ?//Code39校验正常标志清零? ? xCODE39_NIO ? ? := False; ?//Code39校验异常标志清零END_IF;```**解读**: ?- 当未接收RBS或`FM_Reset`触发时,重置所有与RBS、工作站类型相关的标志和变量,初始化可视化字符串(用`*`占位),确保下次接收前状态干净。 ?##### 9. RBS有效性评估```scl(***** 评估毛坯代码 ******************************************************)IF?(HAND OR Auto) AND NOT xUebern AND NOT FM_Reset THEN ?//手动/自动使能、未接收、未重置? ? FOR i :=?1?TO iRBSAnz BY?1?DO ?//循环评估各位置? ? ? ? FOR iLauf :=?1?TO?16?BY?1?DO ?//匹配缓存中的有效字符? ? ? ? ? ? IF tempDB_RBS.Z[i].Z[iLauf].CH = arrRBS[i] THEN ?//字符匹配? ? ? ? ? ? ? ? arrRBS_IO[i] := tempDB_RBS.Z[i].Z[iLauf].Frg; ?//获取该字符的有效标志? ? ? ? ? ? ? ? IF arrRBS_IO[i] THEN ?//字符有效? ? ? ? ? ? ? ? ? ? iVisuTastenS[i] := iLauf; ?//记录软键输入值? ? ? ? ? ? ? ? ? ? strVisuWertRBS.arrText[i] := tempDB_RBS.Z[i].Z[iVisuTastenS[i]].CH; ?//更新可视化字符? ? ? ? ? ? ? ? END_IF;? ? ? ? ? ? ? ? EXIT; ?//匹配后退出内层循环? ? ? ? ? ? ELSIF tempDB_RBS.Z[i].Z[iLauf].CH =?' '?THEN ?//遇到空格(结束符)? ? ? ? ? ? ? ? EXIT;? ? ? ? ? ? END_IF; ? ? ? ??? ? ? ? END_FOR;? ? ? ? arrRBS_NIO[i] := NOT arrRBS_IO[i]; ?//异常标志=非正常标志? ? END_FOR;? ? xRBS_IO ?:= True; ?//默认RBS整体正常? ? FOR i :=?1?TO iRBSAnz BY?1?DO ?//检查所有位置? ? ? ? xRBS_IO ?:= xRBS_IO AND arrRBS_IO[i]; ?//整体正常=所有位置正常? ? ? ? xRBS_NIO := NOT xRBS_IO; ?//整体异常=非整体正常? ? END_FOR;END_IF;```**解读**: ?- 评估RBS各位置的字符是否有效:循环匹配`tempDB_RBS`中定义的有效字符,设置`arrRBS_IO`(位置正常)和`arrRBS_NIO`(位置异常)。 ?- `xRBS_IO`为所有位置正常的“与”结果(全正常才为1),`xRBS_NIO`为其反值。 ?##### 10. 校验位评估(Code39算法)```scl(***** 评估校验位 ***********************************************************)IF NOT Cfg.X1 AND xRBS_IO THEN ?//启用校验位且RBS本身正常? ? strVisuWertRBS.arrText[iRBSLen] := arrRBS[iRBSLen]; ?//更新可视化校验位? ? FOR iLauf :=?1?TO iRBSLen BY?1?DO ?//将RBS字符转换为Code39编码? ? ? ? IF ? ?strVisuWertRBS.arrText[iLauf] =?'0'?THEN arrCode_RBS[iLauf] :=?0;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'1'?THEN arrCode_RBS[iLauf] :=?1;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'2'?THEN arrCode_RBS[iLauf] :=?2; ?? ? ? ? ? ? ? ?ELSIF strVisuWertRBS.arrText[iLauf] =?'3'?THEN arrCode_RBS[iLauf] :=?3;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'4'?THEN arrCode_RBS[iLauf] :=?4;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'5'?THEN arrCode_RBS[iLauf] :=?5;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'6'?THEN arrCode_RBS[iLauf] :=?6;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'7'?THEN arrCode_RBS[iLauf] :=?7;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'8'?THEN arrCode_RBS[iLauf] :=?8;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'9'?THEN arrCode_RBS[iLauf] :=?9;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'A'?THEN arrCode_RBS[iLauf] :=?10;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'B'?THEN arrCode_RBS[iLauf] :=?11;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'C'?THEN arrCode_RBS[iLauf] :=?12;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'D'?THEN arrCode_RBS[iLauf] :=?13;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'E'?THEN arrCode_RBS[iLauf] :=?14;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'F'?THEN arrCode_RBS[iLauf] :=?15;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'G'?THEN arrCode_RBS[iLauf] :=?16;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'H'?THEN arrCode_RBS[iLauf] :=?17;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'I'?THEN arrCode_RBS[iLauf] :=?18;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'J'?THEN arrCode_RBS[iLauf] :=?19;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'K'?THEN arrCode_RBS[iLauf] :=?20;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'L'?THEN arrCode_RBS[iLauf] :=?21;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'M'?THEN arrCode_RBS[iLauf] :=?22;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'N'?THEN arrCode_RBS[iLauf] :=?23;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'O'?THEN arrCode_RBS[iLauf] :=?24;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'P'?THEN arrCode_RBS[iLauf] :=?25;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'Q'?THEN arrCode_RBS[iLauf] :=?26;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'R'?THEN arrCode_RBS[iLauf] :=?27;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'S'?THEN arrCode_RBS[iLauf] :=?28;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'T'?THEN arrCode_RBS[iLauf] :=?29;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'U'?THEN arrCode_RBS[iLauf] :=?30;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'V'?THEN arrCode_RBS[iLauf] :=?31;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'W'?THEN arrCode_RBS[iLauf] :=?32;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'X'?THEN arrCode_RBS[iLauf] :=?33;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'Y'?THEN arrCode_RBS[iLauf] :=?34;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'Z'?THEN arrCode_RBS[iLauf] :=?35;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'-'?THEN arrCode_RBS[iLauf] :=?36;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'.'?THEN arrCode_RBS[iLauf] :=?37;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?' '?THEN arrCode_RBS[iLauf] :=?38;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] ='$24'THEN arrCode_RBS[iLauf] :=?39;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'/'?THEN arrCode_RBS[iLauf] :=?40;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'+'?THEN arrCode_RBS[iLauf] :=?41;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'%'?THEN arrCode_RBS[iLauf] :=?42;? ? ? ? END_IF;?? ? END_FOR;? ? iCharCode39 :=?0; ?//初始化编码总和? ? FOR i :=?1?TO iRBSAnz BY?1?DO ?//计算RBS位(不含校验位)的编码总和? ? ? ? iCharCode39 := iCharCode39 + arrCode_RBS[i];? ? END_FOR;? ? iMOD_39 := iCharCode39 MOD?43?; ?//总和模43(Code39校验规则)? ??//检查输入校验位是否与计算值匹配? ? IF arrCode_RBS[iRBSLen] = iMOD_39 AND strVisuWertRBS.arrText[iRBSLen] <>?'*'?THEN?? ? ? ? xCODE39_IO ?:= True; ?//校验正常? ? ? ? xCODE39_NIO := False;? ? ELSE? ? ? ? xCODE39_IO ?:= False; ?//校验异常? ? ? ? xCODE39_NIO := True;? ? END_IF;? ??//根据模43结果确定校验位字符? ? CASE iMOD_39 OF? ? ? ??0? : chrPZ :=?'0';? ? ? ??1? : chrPZ :=?'1';?? ? ? ? ? ? ?2? : chrPZ :=?'2';? ? ? ??3? : chrPZ :=?'3';? ? ? ??4? : chrPZ :=?'4';? ? ? ??5? : chrPZ :=?'5';? ? ? ??6? : chrPZ :=?'6';? ? ? ??7? : chrPZ :=?'7';? ? ? ??8? : chrPZ :=?'8';? ? ? ??9? : chrPZ :=?'9';? ? ? ??10?: chrPZ :=?'A';? ? ? ??11?: chrPZ :=?'B';? ? ? ??12?: chrPZ :=?'C';? ? ? ??13?: chrPZ :=?'D';? ? ? ??14?: chrPZ :=?'E';? ? ? ??15?: chrPZ :=?'F';? ? ? ??16?: chrPZ :=?'G';? ? ? ??17?: chrPZ :=?'H';? ? ? ??18?: chrPZ :=?'I';? ? ? ??19?: chrPZ :=?'J';? ? ? ??20?: chrPZ :=?'K';? ? ? ??21?: chrPZ :=?'L';? ? ? ??22?: chrPZ :=?'M';? ? ? ??23?: chrPZ :=?'N';? ? ? ??24?: chrPZ :=?'O';? ? ? ??25?: chrPZ :=?'P';? ? ? ??26?: chrPZ :=?'Q';? ? ? ??27?: chrPZ :=?'R';? ? ? ??28?: chrPZ :=?'S';? ? ? ??29?: chrPZ :=?'T';? ? ? ??30?: chrPZ :=?'U';? ? ? ??31?: chrPZ :=?'V';? ? ? ??32?: chrPZ :=?'W';? ? ? ??33?: chrPZ :=?'X';? ? ? ??34?: chrPZ :=?'Y';? ? ? ??35?: chrPZ :=?'Z';? ? ? ??36?: chrPZ :=?'-';? ? ? ??37?: chrPZ :=?'.';? ? ? ??38?: chrPZ :=?' ';? ? ? ??39?: chrPZ :=?'$24';? ? ? ??40?: chrPZ :=?'/';? ? ? ??41?: chrPZ :=?'+';? ? ? ??42?: chrPZ :=?'%';? ? END_CASE;ELSE? ? chrPZ :=?'*'; ?//不启用校验位或RBS异常时,校验位无效END_IF;strVisuWertPZ.arrText[1] := chrPZ; ?//更新可视化校验位(*RBS整体有效性(含校验位)*)xRBS_PZ_IO ?:=?xRBS_IO AND?(xCODE39_IO OR Cfg.X1); ?//整体正常=RBS正常且(校验正常或不启用校验)xRBS_PZ_NIO :=?xRBS_NIO OR?(xCODE39_NIO AND NOT Cfg.X1); ?//整体异常=RBS异常或(校验异常且启用校验)```**解读**: ?- 当启用校验位(`Cfg.X1=0`)且RBS本身正常(`xRBS_IO=1`)时,通过Code39算法计算校验位: ???1. 将RBS字符映射为Code39编码(0-42); ???2. 计算RBS位(不含校验位)的编码总和,对43取模(`iMOD_39`); ???3. 模值对应的字符即为正确校验位(`chrPZ`),与输入校验位比对,设置`xCODE39_IO`(校验正常)。 ?- `xRBS_PZ_IO`为RBS整体有效性(含校验位),`xRBS_PZ_NIO`为其反值。 ?##### 11. 工作站类型评估```scl(****** 评估工作站类型 **********************************************************)IF?(HAND OR Auto) AND NOT xUebern AND NOT FM_Reset AND xRBS_PZ_IO THEN ?//RBS有效时评估工作站类型? ? FOR iLauf :=?1?TO iTypAnz BY?1?DO ?//循环匹配工作站类型条目? ? ? ? FOR i :=?1?TO iRBSAnz BY?1?DO ?//匹配各位置字符? ? ? ? ? ? IF tempDB_STyp.Typ[iLauf].arrText[i] = arrRBS[i] ?//字符完全匹配? ? ? ? ? ? ? ? OR tempDB_STyp.Typ[iLauf].arrText[i] =?'X'?AND NOT cfg.X2 ?//占位符X(Cfg.X2=0)? ? ? ? ? ? ? ? OR tempDB_STyp.Typ[iLauf].arrText[i] =?'~'?AND cfg.X2 ?//占位符~(Cfg.X2=1)? ? ? ? ? ? THEN? ? ? ? ? ? ? ? arrSTyp_IO[i] ?:= True; ?//该位置匹配? ? ? ? ? ? ELSE? ? ? ? ? ? ? ? EXIT; ?//不匹配则退出内层循环? ? ? ? ? ? END_IF; ? ? ? ??? ? ? ? END_FOR;? ? ? ? IF arrSTyp_IO[iRBSAnz] THEN ?//所有位置都匹配? ? ? ? ? ? _wData ?:= tempDB_STyp.Typ[iLauf].Data; ?//获取该类型的数据? ? ? ? ? ? EXIT; ?//退出外层循环? ? ? ? END_IF; ? ? ? ??? ? END_FOR;? ? xSTyp_IO ?:= arrSTyp_IO[iRBSAnz]; ?//工作站类型正常=所有位置匹配? ? xSTyp_NIO := NOT xSTyp_IO; ?//工作站类型异常=非正常END_IF;```**解读**: ?- 当RBS有效(`xRBS_PZ_IO=1`)时,评估RBS是否匹配`tempDB_STyp`中定义的工作站类型: ?? - 支持精确匹配或占位符匹配(`X`或`~`,由`Cfg.X2`控制); ?? - 所有位置匹配时,`xSTyp_IO=1`(工作站类型正常),并获取对应数据`_wData`。 ?##### 12. 接收确认```scl(* 接收确认 *)IF?((Auto AND NOT Hand)?OR?(Hand AND R_TRIG_S_TypFrg_Q AND NOT xUebern)) AND xRBS_PZ_IO AND NOT FM_Reset THEN? ? xUebern ? ? := True; ?//设置RBS已接收标志(自动模式或手动触发且RBS有效)ELSIF?(Hand AND R_TRIG_S_TypFrg_Q AND xUebern) OR xRBS_PZ_NIO OR FM_Reset THEN? ? xUebern ? ? := False; ?//清除接收标志(手动触发已接收、RBS异常或重置)END_IF;//更新手动/自动接收标志R_TRIG_Uebern ? ?:= xUebern AND NOT xR_TRIG_Uebern; ?//xUebern的上升沿xR_TRIG_Uebern ? := xUebern; ?//记忆xUebern状态IF R_TRIG_Uebern THEN ?//接收成功时? ? xHand ?:= Hand; ?//记录手动模式? ? xAuto ?:= NOT Hand; ?//记录自动模式ELSIF NOT xUebern THEN ?//未接收时? ? xHand ?:= False;? ? xAuto ?:= False;END_IF;```**解读**: ?- 当满足以下条件时,设置`xUebern`(RBS已接收标志): ?? - 自动模式(`Auto=1`且`Hand=0`)且RBS有效; ?? - 手动模式(`Hand=1`)且触发`R_TRIG_S_TypFrg_Q`(类型接收上升沿)且RBS有效。 ?- 记录当前接收模式(`xHand`/`xAuto`)。 ?##### 13. 输出变量赋值```scl(***** 输出 *************************************************************************)RBS_IO ? ? := xRBS_PZ_IO; ?//RBS正常=RBS+校验位正常RBS_NIO ? ?:= xRBS_PZ_NIO; ?//RBS异常=RBS+校验位异常STypIO ? ? := xSTyp_IO AND xUebern; ?//工作站类型正常=类型正常且已接收STypNIO ? ?:= xSTyp_NIO AND xUebern; ?//工作站类型异常=类型异常且已接收FM ? ? ? ? := xUebern; ?//RBS已接收标志//初始化RBS各位置输出(位编码)RBS_S1 ? := Word#0;RBS_S2 ? := Word#0;// ... 省略RBS_S3至RBS_S7 ...RBS_S8 ? := Word#0;Data ? ? := Word#0;IF xUebern ?THEN ?//已接收时更新输出? ? IF iVisuTastenS[1] >?0?THEN RBS_S1 :=?ROL?(IN:=WORD#2#0000_0000_1000_0000,?N:=iVisuTastenS[1]); END_IF; ?//位1编码? ? IF iVisuTastenS[2] >?0?THEN RBS_S2 :=?ROL?(IN:=WORD#2#0000_0000_1000_0000,?N:=iVisuTastenS[2]); END_IF; ?//位2编码? ??// ... 省略RBS_S3至RBS_S8的编码 ...? ? Data ? ? := wData; ?//输出工作站类型数据END_IF;```**解读**: ?- 输出变量与内部状态映射:`RBS_IO`/`RBS_NIO`反映RBS整体有效性,`STypIO`/`STypNIO`反映工作站类型有效性(仅在已接收时有效),`FM`为接收标志。 ?- `RBS_S1`至`RBS_S8`通过循环左移(`ROL`)将软键输入值编码为位信号,便于外部识别具体位置。 ?##### 14. 数据块更新(RBS_S数据)```scl(* 设置ANY指针到RBS_S数据源 *)anyQRBS_S := Data; ?//源为工作站类型数据p_QRBS_S.DataType ?:= Byte#4; ?//数据类型:4=WORDp_QRBS_S.DataCount :=?INT_TO_WORD(iRBSAnz +?1); ?//长度:RBS位数+1p_QRBS_S.BZ ? ? ? ?:= p_QRBS_S.BZ OR?16#1000000; ?//调整区域指针(从DB到DI)(* 设置ANY指针到RBS_S数据目标 *)anyZRBS_S := DB_STyp; ?//目标为工作站类型数据块p_ZRBS_S.DataType ?:= Byte#4; ?//数据类型:4=WORDp_ZRBS_S.DataCount :=?INT_TO_WORD(iRBSAnz +?1); ?//长度:RBS位数+1p_ZRBS_S.BZ ? ? ? ?:=?SHL(IN:=pDB_STyp.Anz,?N:=3) OR?16#84000000; ?//计算目标区域指针erg_SFC20 :=?BLKMOV(SRCBLK := anyQRBS_S ,dstblk := anyZRBS_S); ?//将RBS_S数据写入目标DB```**解读**: ?- 配置指针将工作站类型数据(`Data`)写入`DB_STyp`(工作站类型数据块),实现数据持久化存储。 ?##### 15. 循环周期优化```scl(* 循环时间优化 *)iZyklus16 := iZyklus16 +?1; ?//16分频计数器IF iZyklus16 >?16?THEN? ? iZyklus16 :=?1;? ? iZyklus := iZyklus +?1; ?//主循环计数器? ? IF iZyklus > iRBSAnz THEN? ? ? ? iZyklus :=?1; ?//计数器回环(最大为RBS位数)? ? END_IF;END_IF;```**解读**: ?- 通过分频计数器(`iZyklus16`)和主计数器(`iZyklus`)控制可视化更新频率,避免高频刷新占用过多资源。 ?##### 16. 可视化文本更新```scl(* 列标题 *)strVisuText.S[iZyklus].Bez := tempDB_RBS.Z[iZyklus].Bez[Sprache]; ?//根据语言更新列标题(* 按键标题 *)strVisuText.S[iZyklus].Z[iZyklus16].Bez := tempDB_RBS.Z[iZyklus].Z[iZyklus16].Bez[Sprache]; ?//根据语言更新按键标题```**解读**: ?- 根据当前语言(`Sprache`)和循环计数器,动态更新可视化界面的列标题和按键文本(支持多语言)。 ?##### 17. 可视化状态与颜色控制```scl(******* 可视化数据 **************************************************)(**************************颜色编码表***********************************************)(*BK=黑, BU=蓝, GN=绿, GR=灰, LT=浅, WH=白, YE=黄, RD=红 ? ? ? ? ? ? ? ? ? ? ? ? ? ?*)(*st=静态, bl=闪烁 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *)(*HEX/INT ?背景色 ? ? ? ?文本色 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *)(*H00/I00: 灰st ? ? ? ? 黑st ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *)(*H01/I01: 不可见 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *)(*H02/I02: 绿st ? ? ? ? 黑st ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *)(*H03/I03: 蓝st ? ? ? ? 白st ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *)(*H04/I04: 红st ? ? ? ? 白st ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *)(*... 省略其他颜色编码 ... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*)(****************************************************************************************)//可视化状态位配置dwVisuWerte1.X0 ?:= Hand AND NOT xUebern AND NOT FM_Reset; ?//手动输入使能dwVisuWerte1.X1 ?:= Auto; ?//自动模式使能dwVisuWerte1.X2 ?:= Hand; ?//手动模式使能dwVisuWerte1.X3 ?:= xRBS_NIO AND NOT arrRBS_IO[1]?OR?(xSTyp_NIO AND NOT arrSTyp_IO[1]) AND NOT xUebern; ?//RBS位1故障闪烁// ... 省略RBS位2至位8的故障闪烁配置 ...dwVisuWerte1.X11 := iRBSAnz >=?5; ?//位5可见dwVisuWerte1.X12 := iRBSAnz >=?6; ?//位6可见dwVisuWerte1.X13 := iRBSAnz >=?7; ?//位7可见dwVisuWerte1.X14 := iRBSAnz >=?8; ?//位8可见dwVisuWerte1.X15 := dwVisuWerte1.X15; ?//手动RBS接收标志//RBS边框颜色(正常=绿,异常=红)bFarbKombi := byte#16#00; ?//默认灰底黑字IF xRBS_PZ_IO THEN ?//RBS正常? ? bFarbKombi := byte#16#02; ?//绿底黑字ELSIF xRBS_PZ_NIO THEN ?//RBS异常? ? bFarbKombi := byte#16#04; ?//红底白字END_IF;dwVisuWerte1.B2 := bFarbKombi; ?//更新可视化//校验位边框颜色(故障=红)bFarbKombi := byte#16#00;IF False THEN ?//预留故障条件? ? bFarbKombi := byte#16#04; ?//红底白字END_IF;dwVisuWerte1.B2 := dwVisuWerte1.B2?OR SHL(IN:=bFarbKombi,N:=4); ?//高4位控制校验位边框// ... 省略其他可视化元素(符号边框、按钮颜色)的颜色配置 ...```**解读**: ?- 配置可视化界面的状态位(如手动/自动模式、故障闪烁)和颜色(基于颜色编码表),直观反映系统状态(正常为绿,异常为红)。 ?##### 18. 消息系统与故障处理```scl(****************************************************************************************)(*******************消息系统信号处理 *******************************)(***********************在SCL块末尾调用**********************************)TempPointerMsys ? ? ? := Msys; ?//消息系统指针TempPointerFlanken ? ?:= Msys.Flanken; ?//边沿检测指针TempPointerMeldpuffer := ST_Meld; ?//消息缓冲区指针pMeldFeld.BZ := pMeldFeld.BZ OR?16#1000000; ?//调整区域指针(DB→DI)pMeldAbb.BZ ?:= pMeldAbb.BZ ?OR?16#1000000;pMeldFeld.TYP :=?1; ?//数据类型=BOOLpMeldFeld.ANZ :=?16; ?//16个消息标志pMeldAbb.TYP ?:=?2; ?//数据类型=BYTEpMeldAbb.ANZ ?:=?2; ?//2个边沿检测字节//消息标志映射(故障源)MSYS.xF_1 ? := ?xRBS_NIO AND arrRBS_NIO[1]; ?//RBS位1异常MSYS.xF_2 ? := ?xRBS_NIO AND arrRBS_NIO[2]; ?//RBS位2异常// ... 省略RBS位3至位8的故障映射 ...MSYS.xF_9 ? := ?STypNIO; ?//工作站类型无效MSYS.xF_10 ?:= ?xCODE39_NIO; ?//校验位异常MSYS.xF_11 ?:= ?HAND AND NOT xUebern; ?//手动输入激活//发送消息MeldSend(AufrufNr ? ? ? :=?1? ? ? ? ?,Anz_Meld ??? ?:=?11?? ? ? ? ?,pMeldFeld ? ? := pMeldFeld.BZ? ? ? ? ?,pMeldAbb ??? ?:= pMeldAbb.BZ? ? ? ? ?,MeldDB ? ??? ?:=?WORD_TO_INT(pMeldDBNR.DBNR)? ? ? ? ?,AenderungsID ?:= AenderungsID? ? ? ? ?,Integritaet ? := xIntegritaet? ? ? ? ?,Neustart ??? ?:= Neustart? ? ? ? ?);?// 发送消息到消息系统xInit := True; ?//初始化完成//故障/警告/维护消息汇总xStoe := ?Msys.xF_1 ? ?OR Msys.xF_2 ? ?OR Msys.xF_3 ? ?OR Msys.xF_4 ? ?OR Msys.xF_5 ? ?OR Msys.xF_6 ? ?OR Msys.xF_7 ? ?OR Msys.xF_8 ? ?OR Msys.xF_10; ?//故障汇总DB_ARG.VisuSS.Station_Stoer:= DB_ARG.VisuSS.Station_Stoer OR xStoe; ?//更新全局故障xWarn := Msys.xF_9 OR ?Msys.xF_11; ?//警告汇总DB_ARG.VisuSS.Station_Warn := DB_ARG.VisuSS.Station_Warn OR xWarn; ?//更新全局警告xWart := False; ?//维护消息(预留)DB_ARG.VisuSS.Station_Wart := DB_ARG.VisuSS.Station_Wart OR xWart;```**解读**: ?- 将内部故障(如RBS位异常、校验位错误)映射到消息系统标志(`MSYS.xF_1`至`xF_11`),通过`MeldSend`发送到消息缓冲区(`ST_Meld`)。 ?- 汇总故障(`xStoe`)、警告(`xWarn`)并更新全局状态(`DB_ARG`),实现故障的集中监控。 ?##### 19. 故障输出```scl(***** 汇总故障 *******************************************************************)Stoe := xStoe; ?//输出汇总故障(***** 连锁故障 **************************************************************)VkStoe_Out := VkStoe_In OR xStoe; ?//连锁故障=输入连锁故障OR内部故障```**解读**: ?- `Stoe`输出内部汇总故障;`VkStoe_Out`输出连锁故障(包含外部输入故障和内部故障),用于故障级联传递。 ?#### 五、总结FB_Typ_VAR(FB529)是一个用于评估毛坯代码(RBS)和工作站类型的功能块,核心功能包括: ?1. 支持手动/自动模式接收RBS,通过数据块缓存实现高效访问。 ?2. 对RBS进行有效性校验(含Code39校验位),评估各位置字符是否合法。 ?3. 匹配工作站类型(支持占位符`X`/`~`),判断是否与RBS匹配。 ?4. 丰富的可视化交互(多语言、颜色状态、软键输入)和故障消息系统,便于运维监控。 ?该功能块广泛应用于工业自动化场景(如汽车生产),确保毛坯代码与工作站类型的一致性,提高生产过程的可靠性。

部分详细解读:

1.?数据块初始化与参数计算

##### 1. 数据块初始化与参数计算```scl(* 数据块读取 *)IF Init OR NOT xInit OR?"Neustart"?THEN? ? erg_SFC20:=?BLKMOV(srcblk:= DB_RBS ?,?dstblk:= tempDB_RBS); ?//将DB_RBS复制到缓存tempDB_RBS? ? erg_SFC20:=?BLKMOV(srcblk:= DB_STyp ,?dstblk:= tempDB_STyp);?//将DB_STyp复制到缓存tempDB_STyp(* 计算毛坯代码位数 *)? ? iRBSAnz :=?WORD_TO_INT(pDB_RBS.Anz) /?1666; ?//pDB_RBS.Anz是DB_RBS的总长度,1666为单个位的长度(* 计算毛坯代码长度(带/不带校验位) *)? ? IF Cfg.X1 THEN ?//Cfg.X1=1:不使用校验位? ? ? ? iRBSLen := iRBSAnz;? ? ELSE ?//使用校验位:长度=位数+1? ? ? ? iRBSLen := iRBSAnz +?1;? ? END_IF;(* 计算工作站类型DB中的条目数 *)? ? iTypAnz :=?WORD_TO_INT(pDB_STyp.Anz) /?12; ?//pDB_STyp.Anz是DB_STyp的总长度,12为单个条目的长度END_IF;```

解读:

-?当`Init`触发、未初始化(`xInit=0`)或系统重启(`Neustart`)时,通过`BLKMOV`(块移动指令)将`DB_RBS`(毛坯代码数据块)和`DB_STyp`(工作站类型数据块)的数据缓存到`tempDB_RBS`和`tempDB_STyp`(减少对实际DB的访问)。

-?计算核心参数:`iRBSAnz`(毛坯代码的位数)、`iRBSLen`(带/不带校验位的总长度)、`iTypAnz`(工作站类型的条目数量)。

1.1:

erg_SFC20:=BLKMOV(srcblk:=?DB_STyp , dstblk:=?tempDB_STyp);?//将DB_STyp复制到缓存tempDB_STyp

两个结构不同,目的是将原来的字符串拆分开

bMax是复制的字符串最大值,

bAct?字符串当前长度,

因为字符串前面两个字节是隐藏的,所以在拆分的时候要写出来

1.2:

(*?计算车型代码位数?*)

iRBSAnz?:=?WORD_TO_INT(pDB_RBS.Anz)?/?1666;?//pDB_RBS.Anz是DB_RBS的总长度,1666为单个位的长度

4代表四位车型码,四组

1.3:

ELSE??//使用校验位:长度=位数+1

iRBSLen?:=?iRBSAnz?+?1;

此时+1??加一位代表着第五位的校验位

1.4:

iTypAnz?:=?WORD_TO_INT(pDB_STyp.Anz)?/12;?//pDB_STyp.Anz是DB_STyp的总长度,12为单个条目的长度

48组数据

FB530的STyp结构总长度为576(16进制240)??除以12(每组车型12个字节占一组)

2.?配置RBS数据的ANY指针

(* 设置ANY指针到RBS数据 *)p_RBS.SyntaxId ? ? := B#16#10; ? ? ? ? ? ? ? ? ? ??//ANY指针的语法ID固定为16#10p_RBS.DataType ? ? :=?02; ? ? ? ? ? ? ? ? ? ? ? ? ?//数据类型:02=BYTE(RBS为字符,按字节存储)p_RBS.DataCount ? ?:= INT_TO_WORD(iRBSLen); ? ? ? ?//长度:RBS的总长度(含校验位)?p_RBS.DBNR ? ? ? ? := pRBS.DBNR; ? ? ? ? ? ? ? ? ??//DB编号:从RBS指针获取p_RBS.BZ ? ? ? ? ? := pRBS.BZ; ? ? ? ? ? ? ? ? ? ??//区域指针:从RBS指针获取

解读:

-?配置`anyRBS`指针(`p_RBS`)指向实际的RBS数据,`SyntaxId=16#10`是西门子ANY指针的固定格式,`DataType=02`表示数据为字节类型,`DataCount`为RBS的长度。

DataCount:重复系数,只复制5个数据

输入数据RBS、DB2389.DBB89

2c8?—0010 1100 1000??—字地址89.0

(包含了字节地址与后三个位地址)

6.?RBS接收(手动/自动模式)

(******* RBS接收 *****************************************************************)//手动RBS接收IF NOT xUebern AND Hand THEN ?//未接收且手动模式使能? ? IF dwVisuWerte1.X15 THEN ? ? ? ?//手动字符串输入接收标志触发? ? ? ? arrRBS ? ? ?:= strVisuWertRBS.arrText; ?//从可视化字符串读取RBS字符? ? ? ? dwVisuWerte1.X15 := False; ?//清除标志? ? ELSE?? ? ? ? FOR iLauf :=?1?TO iRBSAnz BY?1?DO ?//循环读取各位置? ? ? ? ? ? IF iVisuTastenS[iLauf] >=?1?AND iVisuTastenS[iLauf] <=?16?THEN ?//软键输入有效? ? ? ? ? ? ? ? arrRBS[iLauf] := tempDB_RBS.Z[iLauf].Z[iVisuTastenS[iLauf]].CH;?//从缓存读取对应字符? ? ? ? ? ? ELSE? ? ? ? ? ? ? ? arrRBS[iLauf] :=?'*'; ?//无效输入用'*'表示? ? ? ? ? ? END_IF;? ? ? ? END_FOR;? ? ? ? IF NOT Cfg.X1 THEN?//使用校验位时? ? ? ? ? ? IF xS_UebPZ AND xRBS_IO THEN?//校验位接收按键触发且RBS有效? ? ? ? ? ? ? ? arrRBS[iRBSLen] ? := chrPZ; ?//用计算出的校验位填充? ? ? ? ? ? ELSIF arrRBS[iRBSLen] <> chrPZ THEN ?//输入校验位与计算值不符? ? ? ? ? ? ? ? arrRBS[iRBSLen] :=?'*'; ?//标记异常? ? ? ? ? ? END_IF;? ? ? ? END_IF;? ? END_IF;//自动RBS接收ELSIF NOT xUebern AND Auto THEN ?//未接收且自动模式使能? ? erg_SFC20 := BLKMOV(SRCBLK := anyRBS ,DSTBLK := arrRBS); ?//从RBS数据块自动读取字符END_IF; ? ?

解读:

-?手动模式:通过可视化界面输入RBS,支持两种方式:直接输入字符串(`dwVisuWerte1.X15`触发)或通过软键选择字符(`iVisuTastenS`),无效输入用`*`标记;若启用校验位,需匹配计算出的`chrPZ`。

-?自动模式:通过`BLKMOV`从`anyRBS`指向的RBS数据块自动读取字符到`arrRBS`。

6.1:

IFiVisuTastenS[iLauf]?>=1?AND?iVisuTastenS[iLauf]?<=?16?THEN?//软键输入有效

iVisuTastenS数组为手动输入的数据

6.2:

arrRBS[iLauf]?:=?tempDB_RBS.Z[iLauf].Z[iVisuTastenS[iLauf]].CH;//从缓存读取对应字符

iVisuTastenS[iLauf]

 

arrRBS[iLauf]

arrRBS[iRBSLen]? ?:=?chrPZ;??//用计算出的校验位填充

6.3:

erg_SFC20?:=BLKMOV(SRCBLK?:=?anyRBS ,DSTBLK?:=?arrRBS);??//从RBS数据块自动读取字符

由输入RBS?传入

9.?RBS有效性评估

(***** 评估毛坯代码 ******************************************************)IF (HAND OR Auto) AND NOT xUebern AND NOT FM_Reset THEN ?//手动/自动使能、未接收、未重置? ? FOR i :=?1?TO iRBSAnz BY?1?DO ?//循环评估各位置? ? ? ? FOR iLauf :=?1?TO?16?BY?1?DO ?//匹配缓存中的有效字符? ? ? ? ? ? IF tempDB_RBS.Z[i].Z[iLauf].CH = arrRBS[i] THEN ?//字符匹配? ? ? ? ? ? ? ? arrRBS_IO[i] := tempDB_RBS.Z[i].Z[iLauf].Frg; ?//获取该字符的有效标志? ? ? ? ? ? ? ? IF arrRBS_IO[i] THEN ?//字符有效? ? ? ? ? ? ? ? ? ? iVisuTastenS[i] := iLauf; ?//记录软键输入值? ? ? ? ? ? ? ? ? ? strVisuWertRBS.arrText[i] := tempDB_RBS.Z[i].Z[iVisuTastenS[i]].CH; ?//更新可视化字符? ? ? ? ? ? ? ? END_IF;? ? ? ? ? ? ? ? EXIT; ?//匹配后退出内层循环? ? ? ? ? ? ELSIF tempDB_RBS.Z[i].Z[iLauf].CH =?' '?THEN ?//遇到空格(结束符)? ? ? ? ? ? ? ? EXIT;? ? ? ? ? ? END_IF; ? ? ? ??? ? ? ? END_FOR;? ? ? ? arrRBS_NIO[i] := NOT arrRBS_IO[i]; ?//异常标志=非正常标志? ? END_FOR;? ? xRBS_IO ?:= True; ?//默认RBS整体正常? ? FOR i :=?1?TO iRBSAnz BY?1?DO ?//检查所有位置? ? ? ? xRBS_IO ?:= xRBS_IO AND arrRBS_IO[i]; ?//整体正常=所有位置正常? ? ? ? xRBS_NIO := NOT xRBS_IO; ?//整体异常=非整体正常? ? END_FOR;END_IF;```

解读:

-?评估RBS各位置的字符是否有效:循环匹配`tempDB_RBS`中定义的有效字符,设置`arrRBS_IO`(位置正常)和`arrRBS_NIO`(位置异常)。

-`xRBS_IO`为所有位置正常的“与”结果(全正常才为1),`xRBS_NIO`为其反值。

9.1

arrRBS_IO[i]

9.2

strVisuWertRBS.arrText[i]?:=tempDB_RBS.Z[i].Z[iVisuTastenS[i]].CH;??//更新可视化字符

注意这里只存入前四个数据,校验位由下面的程序传入

10.?校验位评估(Code39算法)

(***** 评估校验位 ***********************************************************)IF NOT Cfg.X1 AND xRBS_IO THEN ?//启用校验位且RBS本身正常? ? strVisuWertRBS.arrText[iRBSLen] := arrRBS[iRBSLen]; ?//更新可视化校验位? ? FOR iLauf :=?1?TO iRBSLen BY?1?DO ?//将RBS字符转换为Code39编码? ? ? ? IF ? ?strVisuWertRBS.arrText[iLauf] =?'0'?THEN arrCode_RBS[iLauf] :=?0;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'1'?THEN arrCode_RBS[iLauf] :=?1;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'2'?THEN arrCode_RBS[iLauf] :=?2; ?? ? ? ? ? ? ? ?ELSIF strVisuWertRBS.arrText[iLauf] =?'3'?THEN arrCode_RBS[iLauf] :=?3;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'4'?THEN arrCode_RBS[iLauf] :=?4;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'5'?THEN arrCode_RBS[iLauf] :=?5;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'6'?THEN arrCode_RBS[iLauf] :=?6;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'7'?THEN arrCode_RBS[iLauf] :=?7;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'8'?THEN arrCode_RBS[iLauf] :=?8;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'9'?THEN arrCode_RBS[iLauf] :=?9;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'A'?THEN arrCode_RBS[iLauf] :=?10;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'B'?THEN arrCode_RBS[iLauf] :=?11;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'C'?THEN arrCode_RBS[iLauf] :=?12;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'D'?THEN arrCode_RBS[iLauf] :=?13;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'E'?THEN arrCode_RBS[iLauf] :=?14;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'F'?THEN arrCode_RBS[iLauf] :=?15;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'G'?THEN arrCode_RBS[iLauf] :=?16;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'H'?THEN arrCode_RBS[iLauf] :=?17;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'I'?THEN arrCode_RBS[iLauf] :=?18;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'J'?THEN arrCode_RBS[iLauf] :=?19;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'K'?THEN arrCode_RBS[iLauf] :=?20;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'L'?THEN arrCode_RBS[iLauf] :=?21;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'M'?THEN arrCode_RBS[iLauf] :=?22;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'N'?THEN arrCode_RBS[iLauf] :=?23;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'O'?THEN arrCode_RBS[iLauf] :=?24;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'P'?THEN arrCode_RBS[iLauf] :=?25;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'Q'?THEN arrCode_RBS[iLauf] :=?26;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'R'?THEN arrCode_RBS[iLauf] :=?27;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'S'?THEN arrCode_RBS[iLauf] :=?28;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'T'?THEN arrCode_RBS[iLauf] :=?29;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'U'?THEN arrCode_RBS[iLauf] :=?30;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'V'?THEN arrCode_RBS[iLauf] :=?31;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'W'?THEN arrCode_RBS[iLauf] :=?32;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'X'?THEN arrCode_RBS[iLauf] :=?33;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'Y'?THEN arrCode_RBS[iLauf] :=?34;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'Z'?THEN arrCode_RBS[iLauf] :=?35;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'-'?THEN arrCode_RBS[iLauf] :=?36;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'.'?THEN arrCode_RBS[iLauf] :=?37;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?' '?THEN arrCode_RBS[iLauf] :=?38;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] ='$24'THEN arrCode_RBS[iLauf] :=?39;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'/'?THEN arrCode_RBS[iLauf] :=?40;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'+'?THEN arrCode_RBS[iLauf] :=?41;? ? ? ? ELSIF strVisuWertRBS.arrText[iLauf] =?'%'?THEN arrCode_RBS[iLauf] :=?42;? ? ? ? END_IF;?? ? END_FOR;? ? iCharCode39 :=?0; ?//初始化编码总和? ? FOR i :=?1?TO iRBSAnz BY?1?DO ?//计算RBS位(不含校验位)的编码总和? ? ? ? iCharCode39 := iCharCode39 + arrCode_RBS[i];? ? END_FOR;? ? iMOD_39 := iCharCode39 MOD?43?; ?//总和模43(Code39校验规则)? ??//检查输入校验位是否与计算值匹配? ? IF arrCode_RBS[iRBSLen] = iMOD_39 AND strVisuWertRBS.arrText[iRBSLen] <>?'*'?THEN?? ? ? ? xCODE39_IO ?:= True; ?//校验正常? ? ? ? xCODE39_NIO := False;? ? ELSE? ? ? ? xCODE39_IO ?:= False; ?//校验异常? ? ? ? xCODE39_NIO := True;? ? END_IF;? ??//根据模43结果确定校验位字符? ? CASE iMOD_39 OF? ? ? ??0? : chrPZ :=?'0';? ? ? ??1? : chrPZ :=?'1';?? ? ? ? ? ? ?2? : chrPZ :=?'2';? ? ? ??3? : chrPZ :=?'3';? ? ? ??4? : chrPZ :=?'4';? ? ? ??5? : chrPZ :=?'5';? ? ? ??6? : chrPZ :=?'6';? ? ? ??7? : chrPZ :=?'7';? ? ? ??8? : chrPZ :=?'8';? ? ? ??9? : chrPZ :=?'9';? ? ? ??10?: chrPZ :=?'A';? ? ? ??11?: chrPZ :=?'B';? ? ? ??12?: chrPZ :=?'C';? ? ? ??13?: chrPZ :=?'D';? ? ? ??14?: chrPZ :=?'E';? ? ? ??15?: chrPZ :=?'F';? ? ? ??16?: chrPZ :=?'G';? ? ? ??17?: chrPZ :=?'H';? ? ? ??18?: chrPZ :=?'I';? ? ? ??19?: chrPZ :=?'J';? ? ? ??20?: chrPZ :=?'K';? ? ? ??21?: chrPZ :=?'L';? ? ? ??22?: chrPZ :=?'M';? ? ? ??23?: chrPZ :=?'N';? ? ? ??24?: chrPZ :=?'O';? ? ? ??25?: chrPZ :=?'P';? ? ? ??26?: chrPZ :=?'Q';? ? ? ??27?: chrPZ :=?'R';? ? ? ??28?: chrPZ :=?'S';? ? ? ??29?: chrPZ :=?'T';? ? ? ??30?: chrPZ :=?'U';? ? ? ??31?: chrPZ :=?'V';? ? ? ??32?: chrPZ :=?'W';? ? ? ??33?: chrPZ :=?'X';? ? ? ??34?: chrPZ :=?'Y';? ? ? ??35?: chrPZ :=?'Z';? ? ? ??36?: chrPZ :=?'-';? ? ? ??37?: chrPZ :=?'.';? ? ? ??38?: chrPZ :=?' ';? ? ? ??39?: chrPZ :=?'$24';? ? ? ??40?: chrPZ :=?'/';? ? ? ??41?: chrPZ :=?'+';? ? ? ??42?: chrPZ :=?'%';? ? END_CASE;ELSE? ? chrPZ :=?'*'; ?//不启用校验位或RBS异常时,校验位无效END_IF;strVisuWertPZ.arrText[1] := chrPZ; ?//更新可视化校验位(*RBS整体有效性(含校验位)*)xRBS_PZ_IO ?:= xRBS_IO AND (xCODE39_IO OR Cfg.X1); ?//整体正常=RBS正常且(校验正常或不启用校验)xRBS_PZ_NIO := xRBS_NIO OR (xCODE39_NIO AND NOT Cfg.X1); ?//整体异常=RBS异常或(校验异常且启用校验)

解读:

-?当启用校验位(`Cfg.X1=0`)且RBS本身正常(`xRBS_IO=1`)时,通过Code39算法计算校验位:

1.?将RBS字符映射为Code39编码(0-42);

2.?计算RBS位(不含校验位)的编码总和,对43取模(`iMOD_39`);

3.?模值对应的字符即为正确校验位(`chrPZ`),与输入校验位比对,设置`xCODE39_IO`(校验正常)。

-`xRBS_PZ_IO`为RBS整体有效性(含校验位),`xRBS_PZ_NIO`为其反值。

10.1

strVisuWertPZ.arrText[1]?:=?chrPZ;??//更新可视化校验位

14.?数据块更新(RBS_S数据)

(* 设置ANY指针到RBS_S数据源 *)anyQRBS_S := Data; ?//源为工作站类型数据p_QRBS_S.DataType ?:= Byte#4; ?//数据类型:4=WORDp_QRBS_S.DataCount := INT_TO_WORD(iRBSAnz +?1); ?//长度:RBS位数+1p_QRBS_S.BZ ? ? ? ?:= p_QRBS_S.BZ OR?16#1000000; ?//调整区域指针(从DB到DI)(* 设置ANY指针到RBS_S数据目标 *)anyZRBS_S := DB_STyp; ?//目标为工作站类型数据块p_ZRBS_S.DataType ?:= Byte#4; ?//数据类型:4=WORDp_ZRBS_S.DataCount := INT_TO_WORD(iRBSAnz +?1); ?//长度:RBS位数+1p_ZRBS_S.BZ ? ? ? ?:= SHL(IN:=pDB_STyp.Anz, N:=3) OR?16#84000000; ?//计算目标区域指针erg_SFC20 := BLKMOV(SRCBLK := anyQRBS_S ,dstblk := anyZRBS_S); ?//将RBS_S数据写入目标DB

解读:

-?配置指针将工作站类型数据(`Data`)写入`DB_STyp`(工作站类型数据块),实现数据持久化存储。

将功能块输出Data以下的五个字的数据复制到DB530.Data结构开始的五个字

监控数据:

Data数据等于16#0100,iRBSAnz等于4,p_QRBS_S.BZ数据等于16#85000130,DB_STyp为输入管脚传入的any指针数据,

详细解读:

这段代码的核心功能是通过SCL?的?ANY?指针配置,使用块移动指令(BLKMOV/SFC20)将源数据区域的内容复制到目标数据区域,本质是实现结构化数据的批量传输。结合你提供的具体参数(Data=16#0100、iRBSAnz=4、p_QRBS_S.BZ=16#85000130),我们可以分步骤解析如下:

一、背景知识:ANY?指针与?BLKMOV

在西门子?PLC?编程中:

ANY?指针是一种灵活的数据类型,用于描述?“一段连续数据的位置、类型和长度”,其结构包含:数据类型(DataType)、数据长度(DataCount)、存储区域指针(BZ,即?Bereichszeiger)等。

BLKMOV(SFC20) 是块移动指令,功能是将SRCBLK(源地址)指向的连续数据,复制到DSTBLK(目标地址),复制的长度由?ANY?指针中的DataCount决定。

逐段解析代码逻辑

1.?配置源数据的?ANY?指针(anyQRBS_S)

scl

(* Anypointer auf Quelle RBS_S Daten setzten *)

anyQRBS_S?:=?Data; ?// 源数据的基础地址指向Data变量

p_QRBS_S.DataType??:=Byte#4; ?// 数据类型为WORD(16位)

p_QRBS_S.DataCount:=INT_TO_WORD(iRBSAnz?+1); ?// 复制的长度:iRBSAnz=4 → 4+1=5个数据

p_QRBS_S.BZ? ? ? ??:=?p_QRBS_S.BZOR16#1000000; ?// 修正存储区域指针

anyQRBS_S?:=?Data:

Data是 FB 的输出变量(WORD?类型,值为?16#0100),这句的作用是将源?ANY?指针的 “基础地址” 绑定到Data所在的内存位置(即Data的地址作为源数据的起始地址)。

p_QRBS_S.DataType:=Byte#4:

西门子中,DataType是数据类型编码,Byte#4对应WORD?类型(16?位无符号整数)。这表示要复制的数据是 “WORD?类型”。

p_QRBS_S.DataCount:=5:

iRBSAnz=4,因此iRBSAnz?+1=5,表示要复制5 个?WORD(总长度?=5×2?字节?=10?字节)。

p_QRBS_S.BZ:=16#84000130OR16#1000000:

得出数据16#85000130:修正为背景 DB 区域

? 区域指针(BZ)的作用:32?位值,最高字节表示存储区域,低?24?位表示地址偏移(以位为单位)。

? 原始p_QRBS_S.BZ=16#84000130:最高字节84表示 “全局 DB”,低?24?位000130表示地址偏移为0x130位。

? 执行OR?16#1000000后,结果为16#85000130:最高字节85表示 “FB 的背景 DB”(84?|?1=85),低?24?位保持000130(地址偏移不变)。

? 最终含义:源数据位于FB 的背景 DB 中,起始地址偏移为0x130位(换算为字节:0x130?÷?8=?0x19字节,即背景 DB 的第?25?个字节)。

在西门子?PLC?的块移动逻辑中,Data在这里代表的是?“源数据的起始地址”,而不是?“唯一的数据内容”。具体来说,“复制?5?个WORD”?是从Data的地址开始,连续读取?5?个?WORD?类型的内存单元,Data本身是这?5?个?WORD?中的第一个。

第?1?个?WORD:Data本身(地址DB2390.DBW38,值?= 16#0100)

第?2?个WORD:Data地址?+ 2?字节(地址DB2390.DBW40,值?=?未知,取决于后续变量)

第?3?个WORD:Data地址?+ 4?字节(地址DB2390.DBW42)

第?4?个WORD:Data地址?+ 6?字节(地址DB2390.DBW44)

第?5?个WORD:Data地址?+ 8?字节(地址DB2390.DBW46)

2.?配置目标数据的?ANY?指针(anyZRBS_S)

scl

(* Anypointer auf Ziel RBS_S Daten setzten *)

anyZRBS_S?:=?DB_STyp; ?// 目标地址绑定到输入的DB_STyp(ANY指针)

p_ZRBS_S.DataType??:=Byte#4; ?// 数据类型与源一致:WORD

p_ZRBS_S.DataCount:=INT_TO_WORD(iRBSAnz?+1); ?// 复制长度与源一致:5个WORD

p_ZRBS_S.BZ? ? ? ??:=SHL(IN:=pDB_STyp.Anz, N:=3)?OR16#84000000; ?// 计算目标区域指针

anyZRBS_S?:=?DB_STyp:

DB_STyp是 FB 的输入变量(ANY?类型),表示目标数据所在的数据库(如某个全局 DB),这句将目标?ANY?指针绑定到DB_STyp指向的数据库。

p_ZRBS_S.DataType:=Byte#4:

与源数据类型保持一致(WORD),确保数据格式匹配。

p_ZRBS_S.DataCount:=5:

与源数据长度一致(5?个?WORD),确保复制的数据量相同。

p_ZRBS_S.BZ的计算:

16#84000000是西门子存储区域编码,表示 “全局数据块(Global DB)”;

SHL(IN:=pDB_STyp.Anz, N:=3):pDB_STyp.Anz是DB_STyp中定义的?“数据长度”(WORD?类型),左移?3?位等价于 “乘以?8”(将字节地址转换为位地址偏移,西门子中地址以位为最小单位);

最终BZ的含义:目标数据位于全局 DB 中,起始地址偏移为pDB_STyp.Anz?×?8。

目标地址:

第?1?个?WORD:地址DB530.DBW576)

第?2?个WORD:地址DB530.DBW578)

第?3?个WORD:地址DB530.DBW580)

第?4?个WORD:地址DB530.DBW582)

第?5?个WORD:地址DB530.DBW584)

3.?执行数据复制(BLKMOV)

scl

erg_SFC20?:=?BLKMOV(SRCBLK?:=?anyQRBS_S ,dstblk?:=?anyZRBS_S);

功能:调用块移动指令,将anyQRBS_S指向的源数据(5?个?WORD)复制到anyZRBS_S指向的目标地址。

具体传输内容:

源数据以Data(16#0100)为起始,连续?5?个?WORD(假设后续?4?个?WORD?的值为Data+1、Data+2、Data+3、Data+4),最终复制到DB_STyp指定的全局 DB 中。

erg_SFC20:返回值,0表示复制成功,非?0?表示失败(如地址无效、长度不匹配等)。

我找到一个博途的vass06程序,通过博途监控程序可以详细看出此时传输的是地址指针

大众汽车

大众汽车

大众汽车集团是中国汽车工业最早、最成功的国际合作伙伴之一,伴随中国汽车工业成长近四十年。大众汽车集团(中国)始终致力于成为中国社会最值得信赖的合作伙伴,在为消费者提供可靠、高质量产品与服务的同时,更以支持中国社会的可持续发展作为重要己任。

大众汽车集团是中国汽车工业最早、最成功的国际合作伙伴之一,伴随中国汽车工业成长近四十年。大众汽车集团(中国)始终致力于成为中国社会最值得信赖的合作伙伴,在为消费者提供可靠、高质量产品与服务的同时,更以支持中国社会的可持续发展作为重要己任。收起

查看更多

相关推荐