131:S7-300/400 PLC支持哪些寻址方式?
1)直接寻址
1.直接地址:例如I0.0,Q1.7,PIW256,PQW512,MD20,T15,C16,DB1.DBB10,L10.0等
2.符号寻址:例如qq,ww.aa等
2)间接寻址
1.存储器间接寻址:16位指针,例如OPN DB[MW2] 32位指针,例如A I[MD0]
2.寄存器间接寻址:32位指针,例如A I[AR1,P#0.0],A [AR1,P#0.0]
3)S7-300/400寻址方式图解

132:如何使用指针?
指针用来指向一个地址。使用这种寻址方式的优点在于可以在程序运行过程中实现变址。 指针用于存储器间接寻址
程序中用于存储器间接寻址的语句包含一个指令、一个地址标识符、以及一个偏移量(偏移量必须在方括号内给出)。
下面给出一个双字格式的指针的例子:
L P#8.7 把指针值装载到累加器1
T I[MD2] 把指针值传送到MD2
A I[MD2] 查询I8.7的信号状态
= Q[MD2] 给输出位Q8.7赋值
存储区域内部寻址及交叉寻址 :程序中采用这些寻址方式的语句包含一个指令以及下列内容:地址标识符、地址寄存器标识符、偏移量。地址
寄存器(AR1、AR2)及偏移量必须写在方括号内。
存储区域内部寻址例程 :指针不包含指示存储区域的信息:
L P#8.7 把指针值装载到累加器1
LAR1 把指针从累加器1装载到AR1
A I[AR1,P#0.0] 查询I8.7的信号状态
= Q[AR1,P#1.1] 给输出位Q10.0赋值
偏移量0.0不起作用。输出Q10.0 等于8.7 (AR1) 加偏移量1.1。结果是10.0 ,而不是9.8。
存储区域交叉寻址例程 :在存储区域交叉寻址中,指针中包含指示存储区域的信息(例子中为 I 和 Q)。
L P#I8.7 把指针值及存储区域标识装载到累加器1
LAR1 把存储区域I 和地址8.7装载到AR1
L P#Q8.7 把指针值和地址标识符装载到累加器1
LAR2 把存储区域Q和地址8.7装载到AR2
A [AR1,P#0.0] 查询输入位I8.7的信号状态
= [AR2,P#1.1] 给输出位Q10.0赋值
偏移量0.0不起作用。输出Q10.0 等于8.7 (AR2) 加偏移量1.1。结果是10.0 ,而不是9.8,
133.如何用一个变量作索引实现在一个域中读一个元素或写一个元素?
一个域(数据类型为ARRAY)是几个相同数据元素的连接。在源代码中一个单空间域的声明执行如下:
My_Array: ARRAY[4..11] OF INT;
它标识了一个数据类型为“INTEGER”的8(=11-4+1)元素单空间域。
为了访问域中的一个元素,输入域名并在方括号中输入希望访问的元素的号码,比如:My_Array[6]。
在S7-SCL (结构化控制语言 - 符合IEC 1131-3 的结构化文本)可以使用变量做索引:
i:INT:=46
My_Array[i]:=0
在FBD/LAD/STL中,索引必须是个常量,因此限制了可使用的域的范围。
134:怎样访问复合数据类型数组单元的变量?
复合数据类型数组单元中的变量只有通过单独的函数才能访问。作为传送参数这个函数拥有期望的数组数量并以数组[0]作为起始地址。对此函数的要求是数组置于一个数据块中并且数组[0]不被当前数据使用。这就决定了从参数传送来的地址并将指定的数组拷贝到作为处理区的数组[0]。接下来可对数组进行符号处理。然后它被拷贝回原始的数组号。
首先用这些参数定义并计算数组[0]的地址和要处理的数组数量。将这些值保存在函数的临时变量内。
L P##Field_Start // 输入地址域[0]
LAR1
L D [AR1,P#0.0] // 把这些地址保存在类型为ANY的临时变量中
T LD 0 // temp 'firststruc' = LD 0-9
T LD 10 // temp 'sourcestruc' = LD 10-19
L D [AR1,P#4.0]
T LD 4
T LD 14
L W [AR1,P#8.0]
T LW 8
T LW 18
L LD 16 // 定义期望数组的地址
LAR1
L #Indices
L LW 12
*I
SLD 3
+AR1
TAR1 LD 16
然后用SFC20 (BLKMOV)将要处理的数组拷贝到数组[0]。就可以根据应用需求,对索引数组通过符号访问。 然后用SFC20 (BLKMOV)将数组[0]拷贝回原始区域。
135:能否在STEP 7中使用间接寻址编写循环程序?
可以,间接寻址允许寻址地址在程序运行期间才可以确定的操作数。这意味着,程序的一部分可以重复执行。在每个运行周期内,循环编程为所使用的操作数分配不同的地址。
136:ANY指针类型的参数如何被传送出块边界?
下面的例子解释了系统功能块SFC50“RD_LGADR”(读模块逻辑地址)内参数的确定。例如,为功能块FB1编程可分为下面几个步骤:
• 声明一个IN变量“test”和一个TEMP变量“test2”,类型都为ANY(图1)。
• 将SFC50的参数“PEADDR”传送到变量“test2”(图1)。
• 通过为ANY指针“test”赋值,将数据传送到临时变量“test2”中。

语句L P##test首先将地址装载到Accu1,然后通过LAR1语句装载到地址寄存器AR1中(可能是LAR1 P##test的简化格式)。通过寄存器间接寻址将ANY指针(10 字节长)中的地址信息读出:
代码 注释
0 L W[AR1,P#0.0] 读出当前Accu1中参数数据类型的代码。
2 L W[AR1,P#2.0] 读出Accu1中的重复因数。重复因数表明通过参数类型ANY传递的数据类型的大小。
4 L W[AR1,P#4.0] 读数据块的号或者从ANY指针中读出“0”(这个对应于ANY指针的第 4 到第 5 字节)。
6 L D[AR1, P#6.0] 将区域指针读入 Accu1。
每次读地址寄存器AR1之后,数据被保存或者缓存(如T LW 0)在临时变量“test2”中(ANY指针)。按照Network 1中的语句顺序,传送到功能块FB1 的ANY指针被复制到临时变量“test2”中。
137:怎样通过交叉区域寄存器间接寻址访问功能块的本地数据或者功能?
这里必须预先定义本地数据。您可以使用下列语句访问FB或FC的本地数据:
对于存储器间接指针寻址,本地变量必须声明为临时变量(temp):
L P##Lokalvariable
LAR1
L W[AR1,P#X.x]
此处不能使用变量类型“Input”、“Output”和“In_Out”,将被语法检查视为非法。
138:怎样编程间接访问一个ARRAY类型变量的元素?
一个位、字节或者字符域的尺寸是按照字节限制排列的——在所有其它情况下是按照字对齐的。表T6-1中给出了一个域的存储示例。操作系统计算域中单个元素末端位置的位地址。域被分配到从下一个字地址(或字节地址)。下一个数据类型从下一个整字开始(或者整字节).
声明部分:
在声明部分,必须定义一个与将被间接寻址的ARRAY有着同一结构的ARRAY。不一定非要将ARRAY声明为IN-OUT变量;也可以声明为TEMP、IN或OUT变量。
网络:
域宽度(OFFSET)在网络中定义。ARRAY中的单个元素的最小常规数据宽度是一个字节;即使在两个变量之间定义一个BOOL。有必要确定相关的域的宽度和确定下一个期望域的起始地址。可使用下面的算法:
地址(指数):b = 元素长度*(指数 - 1)
创建具有不同数据类型的结构时,必须注意,在特定的环境下可能会自动插入填充字节。
保存ARRAY数据类型 :
示例:ARRAY [1..2,1..3] OF 整数 将生成下列域:
多维域是按照顺序保存的。在本例中整数 [1,1]后面是整数 [1,2],整数 [1,3]后面是整数 [2,1]。
139:STEP 7 以哪种格式存储POINTER参数类型?
STEP 7以 6 个字节保存POINTER参数。表4-1显示了用于保存POINTER参数类型的内存区域以及每个字节中保存的数据。i POINTER参数类型保存了下列信息:

DB号(如果DB中没有保存任何数据时为0)。
CPU中的内存区域(表格中列出了不同内存区域的十六进制代码)。
数据的地址(按照Byte.Bit格式)。
如果将形式参数声明为POINTER参数类型,则只需要指定内存区域和地址。STEP 7自动将输入项目的格式转换为指针格式。
140:如何间接访问I/O地址区域?
下面演示了一个间接访问PA区域的例子。您具有对输出模块只写访问和对输入模块只读访问的权利
FUNCTION_BLOCK FB 2
TITLE =
VERSION : 0.1
VAR_INPUT
TargetAddress : DWORD := DW#16#FF; //Target address by PA address range
OutputValue : DWORD ; //Output value
P_Typ : BOOL ; //1=PE range, 0=PA range
END_VAR
VAR_OUTPUT
InputValue : DWORD ; //Input value
END_VAR
VAR_TEMP
TargetTmp : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =
U #P_Typ;
SPB PEA;
L #TargetAddress;
T #TargetTmp; //Load target address in the tempor鋜e store
SLD 3; //Calculate the formate of pointer Byte.Bit
T #TargetTmp; //Initialisation of temp variable with target address in L-Stack
L #OutputValue; //Load output value
T PAD [#TargetTmp]; //Transfere output value to target address
SPA End;
PEA: L #TargetAddress;
T #TargetTmp; //Load target address in the tempor鋜e store
SLD 3; //Calculate the formate of pointer Byte.Bit
T #TargetTmp; //Initialisation of temp variable with target address in L-Stack
L PED [#TargetTmp]; //Load output value
T #OutputValue; //Transfere output value to target address
End: CLR ;
END_FUNCTION_BLOCK