SFC20 功能例子 注解

谁能够把这注解一下,给大家分享一下,谢谢了

LAR1  P##SOURCE 
      L     B#16#10 
      T     LB [AR1,P#0.0] 
      L     B#16#2 
      T     LB [AR1,P#1.0] 
      L     #LENG 
      T     LW [AR1,P#2.0] 
      L     #SOU_DB 
      T     LW [AR1,P#4.0]  
      L     P#DBX 0.0 
      T     LD [AR1,P#6.0]
      LAR1  P##DEST 
      L     B#16#10 
      T     LB [AR1,P#0.0] 
      L     B#16#2 
      T     LB [AR1,P#1.0] 
      L     #LENG 
      T     LW [AR1,P#2.0] 
      L     #DES_DB 
      T     LW [AR1,P#4.0] 
      L     P#DBX 0.0 
      T     LD [AR1,P#6.0] 
      CALL "BLKMOV" 
           SRCBLK                   := #SOURCE
           RET_VAL                  := MW 0
           DSTBLK                   := #DEST

注解:

L     B#16#10 
      T     LB [AR1,P#0.0] 
装载语法标示(ID)并且传送给ANY指针
L     B#16#2 
      T     LB [AR1,P#1.0] 
装载数据类型字节并传送给ANY指针
L     #LENG 
      T     LW [AR1,P#2.0] 
装载字节传送给ANY指针(字节长度由LENG变量指定)
 L     #SOU_DB 
      T     LW [AR1,P#4.0]  
      L     P#DBX 0.0 
      T     LD [AR1,P#6.0]
指定数据块号为SOU_DB,起始地址为DBX0.0
下面为目标地址ANY指针,含义与源地址ANY指针相同。
因为SFC20的INPUT,OUT端的数据类型都是ANY指针,所以必须按照ANY指针格式处理。
在此给你作了解释,亿万电器论坛和中华工控网上你发的帖子就不再做重复解释了。

 LAR1  P##TEMP5

      L     B#16#10

      T     LB [AR1,P#0.0]

      L     B#16#2

      T     LB [AR1,P#1.0]

      L     #IN4

      T     LW [AR1,P#2.0]

      L     #IN0

      T     LW [AR1,P#4.0]

      L     W#16#84

      T     LB [AR1,P#6.0]

      L     W#16#0

      T     LB [AR1,P#7.0]

      L     #IN1

      SLW   3

      T     LW [AR1,P#8.0]

      LAR1  P##TEMP6

      L     B#16#10

      T     LB [AR1,P#0.0]

      L     B#16#2

      T     LB [AR1,P#1.0]

      L     #IN4

      T     LW [AR1,P#2.0]

      L     #IN2

      T     LW [AR1,P#4.0]

      L     W#16#84

      T     LB [AR1,P#6.0]

      L     W#16#0

      T     LB [AR1,P#7.0]

      L     #IN3

      SLW   3

      T     LW [AR1,P#8.0]

      CALL  "BLKMOV"

       SRCBLK :=#TEMP5

       RET_VAL:=#TEMP7

       DSTBLK :=#TEMP6

注释:

temp5和temp6是ANY指针变量,整个程序的主要部分就是构建一个完整的ANY指针,以temp5为例:

      LAR1  P##TEMP5          //将TEMP5的指针存放在地址寄存器1里

      L     B#16#10           

      T     LB [AR1,P#0.0]   //写入ANY指针的第一个字节B#16#10   

      L     B#16#2

      T     LB [AR1,P#1.0]   //写入ANY指针的第二个字节B#16#2,表示数据的读取以字节位单位 

      L     #IN4

      T     LW [AR1,P#2.0]   //写入ANY指针的第二个字  数据的长度 

      L     #IN0

      T     LW [AR1,P#4.0]    //写入ANY指针的第三个字节 DB块号

      //

      L     W#16#84

      T     LB [AR1,P#6.0]   

      L     W#16#0

      T     LB [AR1,P#7.0]

       //以上这个部分改成如下比较好

      

      L     W#16#84

      T     LW [AR1,P#6.0]       //表示数据的类型是DB块数据

      L     #IN1

      SLW   3                   //左移动三位的目的是,IN1输入的是起始字节的号,而地址指针里处理字节地址外,还有位地址,而左移动三位后相当于乘以8,这样就得到了字节的地址

      T     LW [AR1,P#8.0]      //对ANY指针的最后一个双字进行赋值,表示的是数据的地址,

整个程序的意思就是根据输入的变量IN0---IN4,将一个DB块的数据拷贝到另外一个DB块里,

IN0和IN1对应的是来源的数据,IN2和IN3对应的是目标的数据,IN4是数据的长度,两者是一样的。

ANY 指针定义的存储区如果不在过程映像区,则不能使用 SFC20 进行复制,首先,必须将位于过程映像之外的输入数据按照连续顺序复制到全局数据块中,然后再使用 SFC20 将数据从全局数据块 (数据源) 复制到目标数据区 (输出、标记、数据块),不能使用ANY 指针直接访问外设地址区如“P#PE300.0 BYTE 16”。

下图示例了如何将数据从外设地址区PEW300 复制到 DB5 数据块。

 

注意:

在上述示例中使用 SFC20 (BLKMOV) 要占用CPU大量循环时间,因此这也涉及到CPU装载存储区的使用问题。在这种情况下使用装载和传送指令比较好例如

L  PEW 300
T  DB5.DBW0

间接寻址的示例程序如下:

文件"PAE.zip"包含使用间接寻找访问PQ数据区的示例程序,对输出模块是只写操作,对输入模块为只读操作,文件"PAE.zip"包含两个STL源文件。

你好!
    使用说明!
   
SRCBLK INPUT ANY I、Q、M、D、L 指定要复制的存储区(源区域)。不允许指定STRING类型的数组。
RET_VAL OUTPUT INT I、Q、M、D、L 在功能执行时如有故障发生,此参数值中包含故障代码。
DSTBLK OUTPUT ANY I、Q、M、D、L 指定要将数据复制到的存储区(目标区域)。不允许指定STRING类型的数组。
注意源区域与目标区域一定不可以交叉。如果指定的目标区域大于源区域,此功能只将源区域中包含的数据复制到目标区域。如果指定的目标区域(DSTBLK参数)小于源区域(SRCBLK参数),则功能仅复制所能写入到目标区域的尽可能多的数据。如果实际存在的目标区域或源区域小于源区域或目标区域的存储区的参数集大小(SRCBLK、DSTBLK参数),则数据将不传送。如果ANY指针(源或目标)是布尔类型,则指定的长度必须是8的倍数;否则SFC将不能执行。源或目标参数(或二者都)的数据类型也可以为STRING。如果源为字符串,将只复制该字符串的当前字符。如果源和目标为字符串,则复制字符数目的当前长度将被写入。 如果要复制包括最大长度和实际长度的字符串,可如下操作:创建自己在SRCBLK和DSTBLK参数中使用的ANY指针请使用BYTE数据类型完成此操作。
特性:如果用SFC 20 BLKMOV将未链接的数据块复制并装载到RAM (例如,通过编程设备),SFC将被延时多达几毫秒。这会导致一个长的OB循环时间,可能会使循环监控报警。所以应避免在CPU通过SFC 20 复制块时装载这类块。

看指令相应帮助文件就清楚了!

L     W#16#3230                   // Load ASCII first and second value of the year ‘20‘ (for 2000 year)
      T     LW    26                    // Save in temporary ASCII array

      L     P#0.0                       // Load start address
      LAR1                              // Save this address in address register 1 
      L     0                           // Load start address
      SLD   3                           // Create pointer
      +AR1                              // Add this value to address register 1

      L     P#0.0                       // Load start address
      LAR2                              // Save this address in address register 2 
      L     28                          // Load start address
      SLD   3                           // Create pointer
      +AR2                              // Add this value to address register 2

// Conversion from BCD format to ASCII format

      L     8                           // Load number of loops
Next: NOP   1                           // Do nothing
      T     #Index_ASCII                // Save actual loop number as Index ASCII
      L     LB 【AR1,P#0.0】              // Load value from address in address register 1
      SRW   4                           // Shift bits four places to the right
      L     B#16#30                     // Load value 0 in ASCII
      OW                                // Do OR operation with bits
      SLW   8                           // Shift bits eight places to the right
      T     LW 【AR2,P#0.0】              // Save this value to address in address register 2
      L     LB 【AR1,P#0.0】              // Load value from address in address register 1
      L     DW#16#F                     // Load F value
      AW                                // Do AND operation with bits
      L     B#16#30                     // Load value 0 in ASCII
      OW                                // Do OR operation with bits
      L     LW 【AR2,P#0.0】              // Load value from address in address register 2
      OW                                // Do OR operation with bits
      T     LW 【AR2,P#0.0】              // Save this value to address in address register 2
      +AR1  P#1.0                       // Add one byte to address register 1
      +AR2  P#2.0                       // Add two bytes to address register 2
      L     #Index_ASCII                // Before next loop load actual loop counter
      LOOP  Next                        // Decrease actual loop counter and jump to "Next" label

      LAR1  P##Date_time_ASCII          // Load pointer of destination data block and set all parameters
      L     B#16#10                     // Load value 10 (for S7 always the same)
      T     LB 【AR1,P#0.0】              // Set this value in right place in "Destination" pointer
      L     B#16#2                      // Load value 2 (data type - BYTE)
      T     LB 【AR1,P#1.0】              // Set this value in right place in "Destination" pointer
      L     22                          // Load number bytes to copy (repetition factor)
      T     LW 【AR1,P#2.0】              // Set this value in right place in "Destination" pointer
      L     #DB_date_and_time           // Load DB number
      T     LW 【AR1,P#4.0】              // Set this value in right place in "Destination" pointer
      L     P#DBX 16.0                  // Load start memory area to copy data
      T     LD 【AR1,P#6.0】              // Set this value in right place in "Destination" pointer

      CALL  "BLKMOV"                    // Using actual date and time in ASCII format
       SRCBLK :=#Date_time_ASCII_array  // And "Destination" pointer
       RET_VAL:=#Temp                   // Copy data from source area
       DSTBLK :=#Date_time_ASCII        // To destination area

西门子STL间接寻址常问问题集

1.1如何获得指针或者间接寻址有关的信息?
指针的类型包括16位指针、32位指针、Pointer(6Byte)和Any(10Byte)。16位指针用于定时器、计数器、程序块的寻址;32位指针用于I/Q/M/L/数据块等存储器中位、字节、字以及双字的寻址,其中第0~2位表示位地址(0~7)、第3~18位为字节地址,其余位未定义;Pointer和Any一般应用在复杂数据类型(比如Date_and_Time /Array/String等)在FB、FC之间的传递。而Any可以看做是对Pointer的延伸,因为由10Byte组成的Any中Byte4~Byte9就是一个Pointer。
了解指针的格式十分重要,为正确使用指针,应阅读如下内容:
1、 "SIMATIC Programming with STEP 7 V5.5" 05/2010 第27.3.4章 参数类型
2、文档:1008用于S7-300 和S7-400 的语句表(STL)编程
3、文档:F0215,S7-300和S7-400寻址

1.2为什么语句 LAR1 P##PointerInput 在一个函数(FC)中是无效的,然而,同样的语句在一个功能块(FB)中是有效的?
在FC被调用时,复杂数据类型例如指针是被复制到调用者的临时变量区中,在FC内部对此V区地址直接取址放入到地址寄存器AR1或AR2是不被编译器规则接受的(导致MC7寄存器信息过长),也就是说在FC内部通过P#进行地址寄存器取址仅能支持Temp临时变量。因此如果需要在FC中操作指针等复杂输入输出变量地址需要使用累加器进行中转。
考虑到程序的一致性、遵守编译器规则和STL手册中LAR1指令说明,建议用户使用如下指令操作:
L P##PointerInput
LAR1

1.3 STEP 7 中哪些操作会覆盖DB/DI寄存器或者地址寄存器AR1/AR2的内容?
下面说明了可能引起DB/DI寄存器或者地址寄存器AR1/AR2内容改变的一些操作:

  • DB寄存器和AR1受到影响的操作
    1. 使用完整的DB路径(如L DB20.Val)或者调用FC/FB时使用DB块完整地址作为其参数,则DB寄存器内容被覆盖。
    例如在OB1中调用FC1后,DB寄存器变成20。
    OPN DB1
    Call FC1
    Input(bit):DB20.DBX0.2
    因此在编程的时候,OPN 指令打开数据块,通过DBX x.y的方式访问其中内容, 但是如果在打开数据块后DB寄存器的内容被修改了,则DBX x.y的方式访问变量则 会访问到错误的地址。可以通过使用符号寻址的方式或者使用完整路径编程避免,当 然重新使用 OPN指令也是可以的。
    2. 调用FC时使用string, array, structure ,UDT作为其形参或者调用FB时使用string, array, structure 或者UDT作为其in out形参,在FC/FB程序中访问这些地址则AR1寄存器内容被覆盖,因此当使用AR1进行间接寻址时需要注意AR1内容的正确性。
  • AR2地址寄存器和DI寄存器在FB中作为参数和静态变量的基址寻址使用。AR2和DI如果被修改,会影响FB的参数访问,如果希望在FB中使用DI寄存器或者地址寄存器AR2,必须预先保存它们中的内容,并在使用后恢复它们,例如:
    TAR2 #AR2_SAVE; //AR2寄存器状态保存到#AR2_SAVE
    L                     DINO;
    T                     #DB2_SAVE; //DI寄存器状态保存到#DB2_SAVE

User Program

LAR2             #AR2_SAVE; //AR2寄存器恢复到使用前状态
OPN             DI [#DB2_SAVE]; //DI寄存器恢复到使用前状态

1.4 如何得到多重背景FB中的变量在背景DB里的绝对偏移量呢?
可以用下面的方法处理:
TAR2 (得到多重背景FB在背景DB里的偏移地址)
AD DW#16#00FFFFFF (屏蔽掉存储区ID,可参考32位指针格式)
L P##Variable (得到变量在多重背景FB里的地址)
+D (多重背景FB的偏移地址与变量在多重背景FB里地址相加,即得到实际绝对偏移量)
LAR1
上述语句就是就得到了变量在背景DB中的绝对偏移量,从而供后续程序处理。

1.5如何在程序中使用ANY 型指针?

简要说明如下:
L             P##Input                 //指向存储地址指针Input首地址
//这个参数是一个Any类型,P##Input指向参数Input的值所在地址,这就是指针的指针
LAR1                                                                 //装载到地址寄存器AR1中。
L                 W [AR1,P#4.0]             //打开DB块
// 由Any类型结构知道Any类型的Byte4、Byte5存放的数据块号
T                 #BLOCK_NO
OPN             DB [#BLOCK_NO]                 //如果是DB块,打开指定的DB块。
L                 W [AR1,P#2.0] //判断ANY指针中数据长度
// Any类型的Byte2、Byte3是重复系数,如P#DB1.DBX0.0 Byte 8后面的Byte 8
_001:T             #DATA_LEN                     //通常此处做loop循环!!
L                 D [AR1,P#6.0]                         //找出需要计算数据区的开始地址
// Any类型Byte6~Byte9是32位区域地址
理解Pointer、Any的类型的数据结构,对于正确使用指针有很大帮助。
为正确使用指针,应仔细阅读如下内容:
"SIMATIC Programming with STEP 7 V5.5" 05/2010 第27.3.4章 参数类型

如下的程序实现了SFC20的部分功能,可以作为Any使用的参考。
FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1
VAR_INPUT
SRCBLK : ANY ;
END_VAR
VAR_OUTPUT
RETVAL : INT ;
DSTBLK : ANY ;
END_VAR
VAR_TEMP
LOOP : INT ;
BLOCK_NO_DB : WORD ;
BLOCK_NO_DI : WORD ;
SRC_ADD : DWORD ;
DST_ADD : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =
L P##SRCBLK; //读取输入any的首地址
LAR1 ; //装载到ar1
L P##DSTBLK; //读取输出any的首地址
LAR2 ; //装载到ar2
L W [AR1,P#4.0]; //打开DB块
T #BLOCK_NO_DB;
L W [AR2,P#4.0]; //打开DI块
T #BLOCK_NO_DI;
OPN DB [#BLOCK_NO_DB]; //打开DB块
OPN DI [#BLOCK_NO_DI]; //打开DI块
L D [AR1,P#6.0];
T #SRC_ADD; //读取地址
L D [AR2,P#6.0];
T #DST_ADD; //读取地址

L W [AR1,P#2.0]; //读取循环次数
_001: T #LOOP;
L DBB [#SRC_ADD];
T DIB [#DST_ADD]; //赋值
//地址偏移1个字节
L P#1.0;
L #SRC_ADD;
+D ;
T #SRC_ADD;
L P#1.0;
L #DST_ADD;
+D ;
T #DST_ADD;
L #LOOP; //循环
LOOP _001;
END_FUNCTION

1.6 当FC 或FB的输入参数类型为:BLOCK_DB, TIMER或者 COUNTER,如何确定其编号?
例1 :FB 块
FB1 变量声明中定义了“ Timer” 类型的变量“ Time_1” ,在 FB2 中调用 FB1,将定时器“T5”传递给变量“ Time_1”。如图 01 所示程序代码中数值 5 表示“T5”。



图 01 FB中确定定时器编号

在使用多重实例时,需要在图 01 所示程序中增加以下代码:
TAR2 //多重实例偏移地址
LAR1 P##Time_1
+AR1 //多重实例偏移地址与当前地址相加
L W[AR1,P#0.0]
T MW0
例 2 FC
FC1 变量声明中定义了“ Timer” 类型的变量“ Time_1” ,在 FC2 中调用 FC1,将定时器“T8”传递给变量“ Time_1”。如图 02 所示程序代码中数值 8 表示“T8”。


图 02 FC中确定定时器编号

“BLOCK_DB”类型参数在调用 FC 时不可以直接传送给 FC 。如果在调用功能时试图使用此参数类型,将产生如下的错误消息: “非法的参数传输<参数名>” 。“BLOCK_DB”类型参数仅在 FB 被调用(从一个 FB 或 FC 中)时可被传送。 “BLOCK_DB”类型参数不可以在 FC 被调用(从一个 FB 或 FC 中)时可被传送。
相关详细信息可参考 STEP7 在线帮助中“合法的传输参数类型”。
然而,如果希望将 BLOCK_DB 参数类型传送给 FC, DB 块的编号可以通过基本数据类型(例如 WORD)传送。 在下面的例子中,FB100 拥有一个“BLOCK_DB” 的输入参数类型。为了在调用 FC101 时将参数传送给它,“BLOCK_DB”中的 DB 块编号被传送给 WORD 临时变量(DB_No)。当 FC 被调用,数据块序号以一个 WORD 参数类型替代 BLOCK_DB 参数类型。


图 03 FB中确定Block_DB编号

如果 FB 的接口参数能被定义成 WORD 参数类型来传送 DB 块编号,当 FC 被调用时,此参数可以被直接传送给 FC。


图 04 FC中确定DB编号

1.7 参数传递有何限制?
当分配实际参数给形式参数时,可以指定绝对地址、符号名称或常数。STEP 7 限制不同参数的分配。例如,输出和输入/输出参数不能被分配常数值(因为输出或输入/输出参数的目的是改变其值)。这些限定尤其适用于具有复杂数据类型的参数,这些参数既不能分配绝对地址也不能分配常数。下表关明涉及分配给形式参数的实际参数数据类型的限制(--)和允许的分配(由 符号显示)。


图 05 允许的参数传递

详细信息请参考手册中附录27.3.4.8节内容:45531107

1.8 如何传递any参数到其他程序块的参数中?
下面的例子将说明如何为系统功能 SFC50 “RD_LGADR” (读取模块逻辑地址)参数化 ANY 指针。例如对于功能块 FB1,按下述步骤编程:
1. 声明一个输入变量“test”和一个临时变量“test2”为 ANY 类型(图05)。
2. 例如,把 SFC50 的参数“PEADDR”传递给变量“test2”(图06)。
3. 通过判断 ANY 指针“test”,能够传递临时变量“test2”的数据。


图 06 any的临时变量传递

语句 L P##test 先把地址加载到 Accu1,然后通过语句 LAR1 把地址加载到地址寄存器 AR1 (可简写为:LAR1 P##test)。每次读取地址寄存器 AR1 并存储数据(例如 T LW0)到临时变量“test2”(ANY 指针)中。Network 1 中的语句复制数据传送到功能块 FB1 的 ANY 数据到临时变量“test2”。


图 07 临时变量的建立

1.9 如何通过UC或CC指令调用FB?
当使用UC,CC指令调用不带参数的FB可以通过手动修改DI值的方式进行背景数据块的动态分配,此操作相当于模仿系统调用FB的过程。
例如: OPN DI[FB1_DI_Number]
LAR2 P#DBX0.0
UC FB1

ANY 数据类型  除了交叉区域指针和 DB 编号之外,ANY 数据类型指针还包含一个数据类型标识符和一个复制因子,这样,不仅能够标识单个地址,而且还可以标识完整的数据区。
ANY 类型的指针有两种用途:
 ?用于数据类型变量:这种类型的 ANY 指针包含有一个语法 ID 16#10  (对于 STL)、一个数据类型标识符、一个复制因子、一个 DB 号以及一个交叉区域 指针。
 ?用于参数类型变量:在这种情况下,ANY 指针仅包含一个语法 ID 16#10 (对  于 STL)、一个参数类型标识符以及一个 16 位的无符号数 (位于字节 n+8 和字节 n+9 中,用以表示块号),字节 n+4、 …、n+7 的内容为“0”。

声明 ANY 类型指针 ANY 数据类型的变量一般可在 FC 和 FB 中声明为 IN、OUT 及 INOUT 参数。 
 该声明也可以在 FB和FC 中用作临时变量。借助该临时变量,可以创建一个运行期间可改变的 ANY 类型的指针,并将其传递到被调块中 (请参见 ANY 类型的间接参数赋值)。
区域标识符          000 I/O          
                                    001  输 入 (PII) 
 (RRR):    010     输出 (PIQ)                 011 位 (Bit) 存储器
 100 DB 寄存器数据块中的数据   
         101                 DI 寄存器数据块中的数据
 110 自有的局部数据      111 主调方的 LD

了解ANY 类型数据的特点。
1.  ANY 类型占用长度  10个字节
2.  每个字节的所代表的含义
3.  每个字节功能代码的表达的意义

知道原理,程序就可以操纵10个字节的区域,想怎么用就怎么用。
这个只有知其道,才能用其妙!那就跟独孤九剑一样,无招胜有招。

呵呵 首先你要了解any指针的数据结构
他一共有10个字节 所以要读取any指针本身的数据 也要用间接寻址的方式。
比如iAny是功能块的一个输入 类型是any      


      L     P##iAny
      LAR1  
      L     B [AR1,P#1.0]   //any指针的字节1 表达数据类型  
      T     #DataType
      
      L     W [AR1,P#2.0]  //any指针的字节2-3 表达在该数据类型下的数据长度
      T     #DataLength
               
      L     W [AR1,P#4.0]  //any指针的字节4-5 表达该数据所在的DB块号 非DB为0
     T    #DB_NUM
        
     L     D [AR1,P#6.0]  //any指针的字节6-9 表达该数据指向的数据的首地址
    LAR2

应用举例:比如要做一个把any指针指向的数据全部清零的功能块

比如iAny的输入参数为 p#db1.dbx0.0 byte 10
    

      L     P##iAny
      LAR1  
      L     B [AR1,P#1.0]   //any指针的字节1 表达数据类型  
      T     #DataType
      
      L     W [AR1,P#2.0]  //any指针的字节2-3 表达在该数据类型下的数据长度
      L   8
       *I
      T     #DataLength
               
      L     W [AR1,P#4.0]  //any指针的字节4-5 表达该数据所在的DB块号 非DB为0
     T    #DB_NUM
        
     L     D [AR1,P#6.0]  //any指针的字节6-9 表达该数据指向的数据的首地址
    LAR2

OPN DB[#DB_NUM]

           L     D [AR1,P#6.0]
           LAR2  
           L     #DataLength
NEXT: T     #mLoop
           R      [AR2,P#0.0]
           +AR2  P#0.1
           LOOP  NEXT


执行完后DB1.DBX0.0 到DB1.DBX9.7 全部清零了

可以,用系统功能块SFC20 BLKMOV,用法参照:http://www.ad.siemens.com.cn/service/search/
 

回答者: lish_bing83 - 初级工程师  第9级 
 2010-01-23 13:20:58 

 

LAR1  P##SOURCE 
       L     B#16#10 
       T     LB [AR1,P#0.0] 
       L     B#16#2 
       T     LB [AR1,P#1.0] 
       L     #LENG 
       T     LW [AR1,P#2.0] 
       L     #SOU_DB 
       T     LW [AR1,P#4.0]  
       L     P#DBX 0.0 
       T     LD [AR1,P#6.0]
       LAR1  P##DEST 
       L     B#16#10 
       T     LB [AR1,P#0.0] 
       L     B#16#2 
       T     LB [AR1,P#1.0] 
       L     #LENG 
       T     LW [AR1,P#2.0] 
       L     #DES_DB 
       T     LW [AR1,P#4.0] 
       L     P#DBX 0.0 
       T     LD [AR1,P#6.0] 
       CALL "BLKMOV" 
            SRCBLK                   := #SOURCE
            RET_VAL                  := MW 0
            DSTBLK                   := #DEST

 L     B#16#10 
       T     LB [AR1,P#0.0] 
 装载语法标示(ID)并且传送给ANY指针
 L     B#16#2 
       T     LB [AR1,P#1.0] 
 装载数据类型字节并传送给ANY指针
 L     #LENG 
       T     LW [AR1,P#2.0] 
 装载字节传送给ANY指针(字节长度由LENG变量指定)
  L     #SOU_DB 
       T     LW [AR1,P#4.0]  
       L     P#DBX 0.0 
       T     LD [AR1,P#6.0]
 指定数据块号为SOU_DB,起始地址为DBX0.0
 下面为目标地址ANY指针,含义与源地址ANY指针相同。
 因为SFC20的INPUT,OUT端的数据类型都是ANY指针,所以必须按照ANY指针格式处理。

 参考:
 http://www.gongkong.com/webpage/forum/200609/C-ACB4-B6B3DF880F2B-1.shtml

回答者: hdz - 中级工程师  第10级 
 2010-01-23 14:29:27 

 

如何使用间接寻址访问I/O地址区,当使用SFC20时应注意什么? 
 http://www2.ad.siemens.com.cn/download/html/603.aspx

 
 当使用SFC20 “BLKMOV”,SFC81“UBLKMOV”或SFC21“FILL”块时应注意些什么? 
 http://www2.ad.siemens.com.cn/download/html/849.aspx

回答者: huanghuang - 高级工程师  第11级 
 2010-01-23 15:01:28 

 

You use SFC 20 "BLKMOV" (block move) to copy the contents of a memory area (= source area) to another memory area (= destination area).

 Permissible source areas are the following:

 · Parts of data blocks

 · Memory bits

 · Process-image partition (part process image) for inputs

 · Process-image partition (part process image) for outputs

 The source parameter can be a part of the data block in the load memory which is not relevant to program execution (DB compiled with the keyword UNLINKED).
 这是SFC的帮助,任何数据类型都可以!
 不信你可以访真啊!

23_如何使用 AT 函数在 S7-SCL 中构造一个 ANY 指针?
 
说明在 S7-SCL 中可以使用 AT 命令来定义其它声明变量的视图。下面的两个例子描述了如何为 ANY 指针声明组件,创建 ANY 指针以及确定用于从 DB6 复制数据到 DB7 的 SFC20 (BLKMOV) 的参数。
下表描述了如何在函数中定义一个 ANY 指针。
No.
步骤
STEP 7 将参数类型 ANY 的数据保存在 10 个字节中。为此必须定义一个结构变量,它包含如“data type”,“repeat factor”,“DB number”的参数类型,还有构造 ANY 指针的字节和位地址。图 01 显示了在 FC 中两个结构变量“Test1”和“Test2”的样例声明。
图01
使用 S7-SCL 指令
AT
通过结构变量“Test1”或“Test2”创建一个模板,并且给为此而定义的变量声明“ANY”类型,例如“pAny_source”。 这样使用指令
"pAny_source
AT
Test1: ANY;"
已经定义了一个 ANY 指针
现在必须如图 01 所示通过结构说明预置 ANY 指针。以下指令对应于 ANY 指针“P#DB6.DBX0.0 Byte 10” 的结构:
"Test1.Any_id:= 16#10;"  //语法 ID 为十六进制
"Test1.Source_DataType:= 16#02;"  //为数据类型字节
"Test1.Source_Length:= 16#0A;"  //长度为 10 字节
"Test1.Source_DB_Number:= 16#06;"  //为 DB6
"Test1.Source_Byte_Pointer:= dw#16#84000000;"  //数据块的字节和位地址
用定义了的 ANY 变量“pAny_source”和“pAny_destin”确定SFC20(BLKMOV)的 ANY 参数(图 01),例如,
"erg:= SFC20(srcblk:= pAny_source, dstblk:= pAny_destin)";
INT 类型的变量“erg”对应于函数的返回值(RET_VAL),
已经定义了一个 ANY 指针
INT 类型的变量“erg”对应于函数的返回值(RET_VAL),
下表描述了如何在 UDT 中定义一个 ANY 指针。
No.
步骤
首先创建一个 UDT 来定义 ANY 参数,例如为参数创建一个符号名为“AnyPoint” 的 UDT1:
SyntaxID: BYTE;  //指定语法 ID
DataType: BYTE;  //数据类型编码
DataCount: INT;  //重复因数
DB_Number: WORD;  //数据块数
BytePointer: DWORD;  //字节和位地址的指针
在函数中声明了变量,如“AnyPoint”类型 (UDT1) 的“buffer_source”(源 DB)和“buffer_destin”(目的 DB)。使用 S7-SCL 指令
AT
通过结构变量“buffer_source”和“buffer_destin”创建模板,并声明为此而定义的变量为“ANY”类型,例如“Source_Any”和“Destin_Any”。使用指令
"Source_Any
AT
buffer_source: ANY;"
"Destin_Any
AT
buffer_destin: ANY;"
已经定义 ANY 指针如图 02 所示。
图 02
现在必须用图 02 中的结构化指令预置 ANY 指针。以下指令对应于目的数据块的 ANY 指针“P#DB7.DBX0.0 Byte 10”。
"buffer_destin.SyntaxID:= 16#10;"  //语法 ID 为十六进制
"buffer_destin.DataType:= 16#02;"  //数据类型字节
"buffer_destin.DataCount:= 16#0A;"  //本长度为 10  字节
"buffer_destin.DB_Number:= 16#07;"  //为 DB7
"buffer_destin.BytePointer:= dw#16#84000000;"  //数据块的字节和位地址
用定义了的 ANY 变量“Source_Any” 和“Destin_Any” 确定 SFC20 (BLKMOV) 的 ANY 参数 (图 02),例如,
"erg:= SFC20(srcblk:= Source_Any, dstblk:= Destin_Any)";
INT 类型的变量“erg” 对应于函数的返回值 (RET_VAL)。
已经定义 ANY 指针如图 02 所示。
INT 类型的变量“erg” 对应于函数的返回值 (RET_VAL)。
关于 ANY 指针的更多信息可见 STEP 7 的在线帮助的以下标题中
注意事项如果在 S7-SCL 中用 STL 程序调用一个函数,而且该函数有一个 ANY 类型的 OUT 参数,就要用 ANY 指针将其参数化,例如,像“P#DB10.DBX0.0 BYTE 10”不可能在 S7-SCL 中,因为 ANY 指针在 STL 和 S7-SCL 中的处理是不一样的。当在 S7-SCL 中从 ANY 到 ANY 赋值时,为了转发接收到 INPUT 参数的 ANY 指针,就会有 10 个字节从一个指针复制到其它指针(6  字节)。为了确定 STL 程序的 ANY OUT 参数推荐使用“STRUCT” 类型(如上例所述)。如果一个不是 ANY 的类型变量赋值给 ANY 变量,那么 S7-SCL 编译器就会创建地址(10 字节)并且将其写入 ANY 指针。
复制“SCL_Any.zip”文件到一个单独的文件夹,并且双击打开。STEP 7 V5.5 项目以及其全部相关子目录就会自动解包。可以使用 SIMATIC 管理器打开和处理压缩项目。STEP 7 项目包含两个站。站_1 包含在一个函数中定义 ANY 指针的程序 而站_2 包含在一个 UDT 中定义 ANY 指针的程序。
https://support.industry.siemens.com/cs/document/21946854/如何使用-at-函数在-s7-scl-中构造一个-any-指针??dti=0&lc=zh-CN
原文地址:https://www.cnblogs.com/kdp0213/p/8538931.html