您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 西门子间接寻址常问问题集
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、SIMATICProgrammingwithSTEP7V5.505/2010第27.3.4章参数类型2、文档:1008用于S7-300和S7-400的语句表(STL)编程3、文档:F0215,S7-300和S7-400寻址1.2为什么语句LAR1P##PointerInput在一个函数(FC)中是无效的,然而,同样的语句在一个功能块(FB)中是有效的?在FC被调用时,复杂数据类型例如指针是被复制到调用者的临时变量区中,在FC内部对此V区地址直接取址放入到地址寄存器AR1或AR2是不被编译器规则接受的(导致MC7寄存器信息过长),也就是说在FC内部通过P#进行地址寄存器取址仅能支持Temp临时变量。因此如果需要在FC中操作指针等复杂输入输出变量地址需要使用累加器进行中转。考虑到程序的一致性、遵守编译器规则和STL手册中LAR1指令说明,建议用户使用如下指令操作:LP##PointerInputLAR11.3STEP7中哪些操作会覆盖DB/DI寄存器或者地址寄存器AR1/AR2的内容?下面说明了可能引起DB/DI寄存器或者地址寄存器AR1/AR2内容改变的一些操作:DB寄存器和AR1受到影响的操作1.使用完整的DB路径(如LDB20.Val)或者调用FC/FB时使用DB块完整地址作为其参数,则DB寄存器内容被覆盖。例如在OB1中调用FC1后,DB寄存器变成20。OPNDB1CallFC1Input(bit):DB20.DBX0.2因此在编程的时候,OPN指令打开数据块,通过DBXx.y的方式访问其中内容,但是如果在打开数据块后DB寄存器的内容被修改了,则DBXx.y的方式访问变量则会访问到错误的地址。可以通过使用符号寻址的方式或者使用完整路径编程避免,当然重新使用OPN指令也是可以的。2.调用FC时使用string,array,structure,UDT作为其形参或者调用FB时使用string,array,structure或者UDT作为其inout形参,在FC/FB程序中访问这些地址则AR1寄存器内容被覆盖,因此当使用AR1进行间接寻址时需要注意AR1内容的正确性。AR2地址寄存器和DI寄存器在FB中作为参数和静态变量的基址寻址使用。AR2和DI如果被修改,会影响FB的参数访问,如果希望在FB中使用DI寄存器或者地址寄存器AR2,必须预先保存它们中的内容,并在使用后恢复它们,例如:TAR2#AR2_SAVE;//AR2寄存器状态保存到#AR2_SAVELDINO;T#DB2_SAVE;//DI寄存器状态保存到#DB2_SAVEUserProgramLAR2#AR2_SAVE;//AR2寄存器恢复到使用前状态OPNDI[#DB2_SAVE];//DI寄存器恢复到使用前状态1.4如何得到多重背景FB中的变量在背景DB里的绝对偏移量呢?可以用下面的方法处理:TAR2(得到多重背景FB在背景DB里的偏移地址)ADDW#16#00FFFFFF(屏蔽掉存储区ID,可参考32位指针格式)LP##Variable(得到变量在多重背景FB里的地址)+D(多重背景FB的偏移地址与变量在多重背景FB里地址相加,即得到实际绝对偏移量)LAR1上述语句就是就得到了变量在背景DB中的绝对偏移量,从而供后续程序处理。1.5如何在程序中使用ANY型指针?简要说明如下:LP##Input//指向存储地址指针Input首地址//这个参数是一个Any类型,P##Input指向参数Input的值所在地址,这就是指针的指针LAR1//装载到地址寄存器AR1中。LW[AR1,P#4.0]//打开DB块//由Any类型结构知道Any类型的Byte4、Byte5存放的数据块号T#BLOCK_NOOPNDB[#BLOCK_NO]//如果是DB块,打开指定的DB块。LW[AR1,P#2.0]//判断ANY指针中数据长度//Any类型的Byte2、Byte3是重复系数,如P#DB1.DBX0.0Byte8后面的Byte8_001:T#DATA_LEN//通常此处做loop循环!!LD[AR1,P#6.0]//找出需要计算数据区的开始地址//Any类型Byte6~Byte9是32位区域地址理解Pointer、Any的类型的数据结构,对于正确使用指针有很大帮助。为正确使用指针,应仔细阅读如下内容:SIMATICProgrammingwithSTEP7V5.505/2010第27.3.4章参数类型如下的程序实现了SFC20的部分功能,可以作为Any使用的参考。FUNCTIONFC1:VOIDTITLE=VERSION:0.1VAR_INPUTSRCBLK:ANY;END_VARVAR_OUTPUTRETVAL:INT;DSTBLK:ANY;END_VARVAR_TEMPLOOP:INT;BLOCK_NO_DB:WORD;BLOCK_NO_DI:WORD;SRC_ADD:DWORD;DST_ADD:DWORD;END_VARBEGINNETWORKTITLE=LP##SRCBLK;//读取输入any的首地址LAR1;//装载到ar1LP##DSTBLK;//读取输出any的首地址LAR2;//装载到ar2LW[AR1,P#4.0];//打开DB块T#BLOCK_NO_DB;LW[AR2,P#4.0];//打开DI块T#BLOCK_NO_DI;OPNDB[#BLOCK_NO_DB];//打开DB块OPNDI[#BLOCK_NO_DI];//打开DI块LD[AR1,P#6.0];T#SRC_ADD;//读取地址LD[AR2,P#6.0];T#DST_ADD;//读取地址LW[AR1,P#2.0];//读取循环次数_001:T#LOOP;LDBB[#SRC_ADD];TDIB[#DST_ADD];//赋值//地址偏移1个字节LP#1.0;L#SRC_ADD;+D;T#SRC_ADD;LP#1.0;L#DST_ADD;+D;T#DST_ADD;L#LOOP;//循环LOOP_001;END_FUNCTION1.6当FC或FB的输入参数类型为:BLOCK_DB,TIMER或者COUNTER,如何确定其编号?例1:FB块FB1变量声明中定义了“Timer”类型的变量“Time_1”,在FB2中调用FB1,将定时器“T5”传递给变量“Time_1”。如图01所示程序代码中数值5表示“T5”。图01FB中确定定时器编号在使用多重实例时,需要在图01所示程序中增加以下代码:TAR2//多重实例偏移地址LAR1P##Time_1+AR1//多重实例偏移地址与当前地址相加LW[AR1,P#0.0]TMW0例2FCFC1变量声明中定义了“Timer”类型的变量“Time_1”,在FC2中调用FC1,将定时器“T8”传递给变量“Time_1”。如图02所示程序代码中数值8表示“T8”。图02FC中确定定时器编号“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参数类型。图03FB中确定Block_DB编号如果FB的接口参数能被定义成WORD参数类型来传送DB块编号,当FC被调用时,此参数可以被直接传送给FC。图04FC中确定DB编号1.7参数传递有何限制?当分配实际参数给形式参数时,可以指定绝对地址、符号名称或常数。STEP7限制不同参数的分配。例如,输出和输入/输出参数不能被分配常数值(因为输出或输入/输出参数的目的是改变其值)。这些限定尤其适用于具有复杂数据类型的参数,这些参数既不能分配绝对地址也不能分配常数。下表关明涉及分配给形式参数的实际参数数据类型的限制(--)和允许的分配(由符号显示)。图05允许的参数传递详细信息请参考手册中附录27.3.4.8节内容:455311071.8如何传递any参数到其他程序块的参数中?下面的例子将说明如何为系统功能SFC50“RD_LGADR”(读取模块逻辑地址)参数化ANY指针。例如对于功能块FB1,按下述步骤编程:1.声明一个输入变量“test”和一个临时变量“test2”为ANY类型(图05)。2.例如,把SFC50的参数“PEADDR”传递给变量“test2”(图06)。3.通过判断ANY指针“test”,能够传递临时变量“test2”的数据。图06any的临时变量传递语句LP##test先把地址加载到Accu1,然后通过语句LAR1把地址加载到地址寄存器AR1(可简写为:LAR1P##test)。每次读取地址寄存器AR1并存储数据(例如TLW0)到临时变量“test2”(ANY指针)中。Network1中的语句复制数据传送到功能块FB1的ANY数据到临时变量“test2”。图07临时变量的建立1.9如何通过UC或CC指令调用FB?当使用UC,CC指令调用不带参数的FB可以通过手动修改DI值的方式进行背景数据块的动态分配,此操作相当于模仿系统调用FB的过程。例如:OPNDI[FB1_DI_Number]LAR2P#DBX0.0UCFB1
本文标题:西门子间接寻址常问问题集
链接地址:https://www.777doc.com/doc-2038446 .html