1.3存储器32位地址指针
32位地址指针用于I、Q、M、L、数据块等存储器中位、字节、字及双字的寻址,32位的地址指针使用一个双字表示,第0位~第2位作为寻址操作的位地址,第3位~第18位作为寻址操作的字节地址,第19位~第31位没有定义,32位地址指针的格式如下:
访问时需要使用地址存储器标识符及32位地址指针,地址寻址表示格式为:
地址存储器标识符 [32位地址指针],例如指针存储于LD20中,装载M存储器一个字节表示为:
前面介绍的存储器16位指针,特定用于T、C、程序块的寻址,使用一个INT格式的值表示,每次值加1,指向的对象地址加1,例如,T1、T2,其中的“1”、“2”就是指针的直接变化(好像没有说明白!)。32地址指针使用一个DINT格式的值表示,指向的是I、Q、M、L、数据块等存储器中位,每次值加1,指向的地址区位的号加1,区别就是在这里。一个字节是8个位,如果指向的是字节每次就要加8的倍数,例如地址MB[LD20],LD20值为0,则表示MB0,LD20值为8,则表示MB1,如果指向的是字每次就要加16的倍数,以此类推。
如果将32位指针按照16位指针的方式使用就会出问题,例如MB[LD20],LD值为10,指向地址为MB1.2,程序编译没有问题(语法正确),下载下去造成CPU停机,原因就是地址长度错误。在第三部分介绍定时器循环调用的示例程序中,TRIG1和TRIG2就是使用32指针迭代的,例如 A M [LD20],每次LD值加1,由于显示的问题别屏蔽了,所以程序量还有有一点的。前面也提到了优化的问题,16位和32指针由于使用方法不同,不能简单地合并。
32位指针也可以使用另外一种形式表示,就是使用P#X.Y,P表示指针,#表示特定符号,X表示字节地址,Y表示位地址,P#X.Y可以与DINT格式的值相互转换,DINT值=X*8+Y,
例如P#2.0转换DINT格式为16,P#3.1转换DINT格式为25。在指针寻址时可以使用指针的格式也可以使用DINT格式进行运算。使用32位地址指针寻址参考下面的示例程序:
OPN DB 1 //打开DB1。
OPN DI 3 //打开DB3,最多可以同时打开两个DB块。
L 4 //装载4到累加器1中。
SLD 3 //累加器1中数值左移3位,在程序中经常见到,
左移3位就是将原值乘以8
T MD 20 //将逻辑操作结果传送到MD20中,MD20包含地址指针为P#4.0。
L P#20.0 //将地址指针P#20.0装载到MD24中。
T MD 24
L 320 //320就是P#40.0装载到MD28中。
T MD 28
L DBW [MD 20] //装载DB1.DBW4。
L DBW [MD 24] //装载DB1.DBW20。
+I //相加
L DIW [MD 28] //装载DB3.DBW40。
-I //相减。
T DIW 2 //将运算结果传送到DB3.DBW2中。
使用32位地址指针寻址数据块地址时,数据块必须先打开,然后才能寻址,数据块寻址方法参考下面的示例程序,如果直接使用指令对完整数据格式地址(例如地址DB1.DBB[MD100])进行间接寻址被视为非法。
使用LOOP 指令与32位地址指针可以进行循环操作(这是固定的操作模式,在程序中一看到LOOP指令就要想到地址的迭代),假设一个编程应用:一个INT变量(MW2)与一个数组(假设存储于DB1中,包含100个元素为INT的数组)存储的值相比较,如果数值相同,指出第一个相同数值存储在DB块中的位置(数组中的位置)。使用通常的编程方法,需要逐个进行比较,程序量比较大,如果实际需要与1000个数值比较,将占用大量的存储空间,使用LOOP指令与地址指针相结合可以轻松解决上述问题,参考下面的示例程序:
L 0 //初始化MW100和MD4。
T MW 100
T MD 4
OPN DB 1 //打开DB1。
L 100 //循环操作的次数,100次。
next: T MW 100 //将循环100次装载到MW100中,固定格式。
L MW 2 // 进行比较的数值存储于MW2。
L DBW [MD 4] //与DB块中存储的值进行比较,开始地址为DBW0。
==I //如果数值相等跳到m1。
JC m1
L MD 4 //将地址指针加2(每个相邻的INT地址相差2)。
L P#2.0
+D
T MD 4
L MW 100 //次数减1,跳回next,如果MW100等于0,跳出
LOOP next //循环操作LOOP指令,LOOP指令固定格式。
m1: FP M 10.0 //如果数值相等,记录MD4指针的位置,转换
为数组的位置((地址值/P#2.0)+1)值并存储
于MD8中。
JCN m2 //为0跳转到m2。
L MD 4
L P#2.0
/D
+ 1
T MD 8
m2: NOP 0
地址的循环操作只是减少了程序量,CPU扫描时间不会减少。
1.4存储器32位地址指针-S7-1500的处理方式
与16位指针的处理方式是一样的,还是使用数组进行循环迭代。上面的应用如果在S7-1500中编写则非常方便,示例程序参考图11。
使用变量“START_COMP”作为开始信号,如果比较值“COMP_Value”与数组的元素“A.B["INDEX"]”不相等(INDEX缺省为0),则变量“INDEX”加1,如果大于等于100,则将“INDEX”清0,然后复位开始信号“START_COMP”;如果比较值“COMP_Value”与数组中的第一个元素“A.B["INDEX"]”相等,则将变量“INDEX”中的值传送到结果“RESULT”中,然后将“INDEX”清0并复位开始信号“START_COMP”。
程序比较简单,使用LAD即可编程程序,对编程人员的要求不高,如果使用SCL编写程序可能更加简单。
---------------------------------------------------------------------------------------------------------
上一篇:【3】16位地址指针使用示例——从S7-300/400到s7-1500系列故事之三
下一篇:【5】寄存器间接寻址——从S7-300_400到S7-1500看变址寻址的改变系列故事之五
汇总帖:技术Π活动故事、视频与案例分享汇总