楼主最近还看过
存储器间接寻址具有两个指针格式:单字和双字。
单字指针是一个16bit的结构,从0-15bit,指示一个从0-65535的数值,这个数值就是被寻址的存储区域的编号。
双字指针是一个32bit的结构,从0-2bit,共三位,按照8进制指示被寻址的位编号,也就是0-7;而从3-18bit,共16位,指示一个从0-65535的数值,这个数值就是被寻址的字节编号。
指针可以存放在M、DI、DB和L区域中,也就是说,可以用这些区域的内容来做指针。
单字指针和双字指针在使用上有很大区别。下面举例说明:
L DW#16#35 //将32位16进制数35存入ACC1
T MD2 //这个值再存入MD2,这是个32位的位存储区域
L +10 //将16位整数10存入ACC1,32位16进制数35自动移动到ACC2
T MW100 //这个值再存入MW100,这是个16位的位存储区域
OPN DBW【MW100】 //打开DBW10。这里的【MW100】就是个单字指针,存放指针的区域是M区,MW100中的值10,就是指针间接指定的地址,它是个16位的值!
L L#+10 //以32位形式,把10放入ACC1,此时,ACC2中的内容为:16位整数10
T MD104 //这个值再存入MD104,这是个32位的位存储区域
A I【MD104】 //对I1.2进行与逻辑操作!
= DIX【MD2】 //赋值背景数据位DIX6.5!
A DB【MW100】.DBX【MD2】 //读入DB10.DBX6.5数据位状态
= Q【MD2】 //赋值给Q6.5
A DB【MW100】.DBX【MD2】 //读入DB10.DBX6.5数据位状态
= Q【MW100】 //错误!!没有Q10这个元件
从上面系列举例我们至少看出来一点:
单字指针只应用在地址标识符是非位的情况下。的确,单字指针前面描述过,它确定的数值是0-65535,而对于byte.bit这种具体位结构来说,只能用双字指针。这是它们的第一个区别,单字指针的另外一个限制就是,它只能对T、C、DB、FC和FB进行寻址,通俗地说,单字指针只可以用来指代这些存储区域的编号。
相对于单字指针,双字指针就没有这样的限制,它不仅可以对位地址进行寻址,还可以对BYTE、WORD、DWORD寻址,并且没有区域的限制。不过,有得必有失,在对非位的区域进行寻址时,必须确保其0-2bit为全0!
【地址寄存器间接寻址】
在先前所说的存储器间接寻址中,间接指针用M、DB、DI和L直接指定,就是说,指针指向的存储区内容就是指令要执行的确切地址数值单元。但在寄存器间接寻址中,指令要执行的确切地址数值单元,并非寄存器指向的存储区内容,也就是说,寄存器本身也是间接的指向真正的地址数值单元。从寄存器到得出真正的地址数值单元,西门子提供了两种途径:
1、 区域内寄存器间接寻址
2、 区域间寄存器间接寻址
地址寄存器间接寻址的一般格式是:
〖地址标识符〗〖寄存器,P#byte.bit〗,比如:DIX【AR1,P#1.5】 或M【AR1,P#0.0】 。
〖寄存器,P#byte.bit〗统称为:寄存器寻址指针,而〖地址标识符〗在上帖中谈过,它包含〖存储区符〗+〖存储区尺寸符〗。但在这里,情况有所变化。比较一下刚才的例子:
DIX 【AR1,P#1.5】
X 【AR1,P#1.5】
DIX可以认为是我们通常定义的地址标识符,DI是背景数据块存储区域,X是这个存储区域的尺寸符,指的是背景数据块中的位。但下面一个示例中的M呢?X只是指定了存储区域的尺寸符,那么存储区域符在哪里呢?毫无疑问,在AR1中!
DIX 【AR1,P#1.5】 这个例子,要寻址的地址区域事先已经确定,AR1可以改变的只是这个区域内的确切地址数值单元,所以我们称之为:区域内寄存器间接寻址方式,相应的,这里的【AR1,P#1.5】 就叫做区域内寻址指针。
地址寄存器是专门用于寻址的一个特殊指针区域,西门子的地址寄存器共有两个:AR1和AR2,每个32位。
当使用在区域内寄存器间接寻址中时,我们知道这时的AR中的内容只是指明数值单元,因此,区域内寄存器间接寻址时,寄存器中的内容等同于上帖中提及的存储器间接寻址中的双字指针,也就是:
其0-2bit,指定bit位,3-18bit指定byte字节。其第31bit固定为0。
这样规定,就意味着AR的取值只能是:0.0 ——65535.7
例如:当AR=D4(hex)=0000 0000 0000 0000 0000 0000 1101 0100(B),实际上就是等于26.4。
而在区域间寄存器间接寻址中,由于要寻址的区域也要在AR中指定,显然这时的AR中内容肯定于寄存器区域内间接寻址时,对AR内容的要求,或者说规定不同。
比较一下两种格式的不同,我们发现,这里的第31bit被固定为1,同时,第24、25、26位有了可以取值的范围。聪明的你,肯定可以联想到,这是用于指定存储区域的。对,bit24-26的取值确定了要寻址的区域。
在寄存器寻址指针 【AR1/2,P#byte.bit】 这种结构中,P#byte.bit如何参与运算,得出最终的地址呢?
运算的法则是:AR1和P#中的数值,按照BYTE位和BIT位分类相加。BIT位相加按八进制规则运算,而BYTE位相加,则按照十进制规则运算。
例如:寄存器寻址指针是:【AR1,P#2.6】,我们分AR1=26.4和DBX26.4两种情况来分析。
当AR1等于26.4,
AR1:26.2
l P#: 2.6
= 29.7这是区域内寄存器间接寻址的最终确切地址数值单元
当AR1等于DBX26.4,
AR1:DBX26.2
l P#: 2.6
= DBX29.7这是区域间寄存器间接寻址的最终确切地址数值单元
【AR的地址数据赋值】
【存储器间接寻址应用实例】
我们先看一段示例程序:
L 100
T MW 100 // 将16位整数100传入MW100
L DW#16#8 // 加载双字16进制数8,当把它用作双字指针时,按照BYTE.BIT结构,
结果演变过程就是:8H=1000B=1.0
T MD 2 // MD2=8H
OPN DB 【MW 100】 // OPN DB100
L DBW 【MD 2】 // L DB100.DBW1
T MW【MD2】 // T MW1
A DBX 【MD 2】 // A DBX1.0
= M 【MD 2】 // =M1.0
① 立即数,即常数,也称为数据。在OMRON主推PLC的指令系统中,立即数可用#****或&****表示,#****可为BCD码,也可为十六进制码,具体由指令确定;&****则是十进制码。
② 直接地址,操作数若为上述的立即数,则指令对这个立即数进行操作;若为地址,则是对这个地址中内容进行操作。
③ 间接地址,此时,以这个地址的内容为地址,指令对这个地址的内容进行操作。主推PLC支持D区的间接寻址。地址号前加“*”为D区的BCD间接寻址,如D00010中的内容是15,若操作数为*D00010,则要指令要操作的是D00015中的内容;地址号前加“@”则是D区的十六进制间接寻址,如D00010中的内容为15,当操作数是@D00010时,指令要操作的是D00021中的内容。除了支持D区间接寻址外,这些系列PLC还可以使用索引寄存器(IR)和数据寄存器(DR)进行间接寻址。
a.直接寻址索引寄存器 使用MOVR(560)将一个字或位的内部I/O内存地址传送到一个索引寄存器中(IR0~IR15)。
如 MOVR 0010 IR0 把CIO 00010 的内部I/O 内存地址储存在IR0 中
MOVR 000102 IR2 把CIO 00102 内部I/O 内存地址储存在IR2 中
b.用索引寄存器间接寻址
◆基本操作(无偏移) 把含在IR□中的I/O 内存地址中的字或位作为操作数用。在索引寄存器前放一逗号以表示间接寻址(根据指令或操作数可决定所指定的位/ 字)。
如 LD ,IR0 取包含在IR0 中的I/O 内存地址上位的状态。
MOV #0001, IR1 把#0001 传送到包含在IR1 中的I/O 内存地址上的字中。
◆常数操作 把偏移值(-2,048~+2,047) 加到包含在IR□中的I/O 内存地址上,并且把结果地址当作操作数用。(指令执行时偏移转换为二进制)
如 LD +5 ,IR0 把5 加到包含在IR0 中的I/O 内存地址中,并且取该地址的位状态。
MOV #0001 +31 ,IR1 把31 加到包含在IR1 中的I/O 内存地址上,并且把#0001 传送到该地址的字中。
◆DR偏移 把数据寄存器中的带符号二进制内容加到包含在IR□中的I/O 内存地址上并且把结果地址当操作数用。
如 LD DR0 ,IR0 把DR0 内容加到包含在IR0 中的I/O 内存地址上,并且取该地址位的状态。
MOV #0001 DR0 ,IR1 把DR0 内容加到包含在IR1 中的I/O 内存地址上,并且把#0001 传送到该地址的字中。
◆自动递增 在IR□读I/O 内存地址后,索引寄存器的内容增加1 或2。
递增1:,IR□+
递增2:,IR□++
如 LD ,IR0 + + 取包含在IR0 中的I/O 内存地址上位的状态,并且使寄存器递增2。
MOV #0001 ,IR1 + 把#0001 传送到包含在IR1 中的I/O 内存地址上的字中,并且使寄存器递增1。
◆自动递减 IR□内容减1 或2,然后把寄存器中的I/O 内存地址当操作数用。
递减1:,– IR□
递减2:,– –IR□
如 LD ,– – IR0 使IR0 的内容减2,然后取I/O 内存地址上位的状态。
MOV #0001 ,– IR1 使IR1 的内容减1,然后把#0001传送到该I/O 内存地址的字中。
寻址,即为梯形图功能模块及其它编程方式访问测点的方法。有下列几种寻址方式可用:
1、 立即寻址
直接以常数作为访问对象。如下图的赋值功能模块,执行功能为把100赋值到%MW0001中,其输入端100即为立即寻址方式。
图4.7 立即寻址示意图
※ 立即寻址方式在数据输入时,十六进制的数据后加字母H,十六进制如果第一个数据为字母,要在前面加0,例如想输入B021H必须写为0B021H,否则系统编译时报错。
2、 直接寻址
直接寻址是以测点类型加测点序号作为访问对象。如图4.7的赋值操作,%MW0001作为一个指定测点,即为直接寻址方式。
作为一种特例,使用测点的名称也属于直接寻址,因为测点名称对应的是一个指定测点。例如:定义测点%I0001的名称为GD_ON,在程序中可以直接使用GD_ON,所指代的就是%I0001。
间接寻址,是指访问对象的测点序号不是一个常数,而是另一个测点,即以该测点的当前值作为测点序号。与直接寻址的测点序号不同,间接寻址的测点是从0开始的,即对于一个间接寻址的测点%I【%MW0001】,%MW0001的当前值为1,其访问的测点为%I0002,而不是%I0001。如图4.8所示梯形,%Q【%MW0001】即为间接寻址方式。其测点类型为Q,测点序号不是一个常数,而是另一个测点%MW0001。梯形执行的操作为:%MW0001被赋值为0,线圈对开出测点%Q0001输出1。
CONST
number :=12;//数组存放的数据数量
END_CONST
VAR_INPUT
Tem_actual_input : REAL;//实际温度输入
Tem_actual_udt : UDT3;//存放12个温度的结构体变量
END_VAR
VAR_IN_OUT
Tem_array_1 :ARRAY【1..number】 OF REAL;//从大到小排序的数组
END_VAR
VAR_TEMP
Index_1 : INT;
Index_2 : INT;
Tem_temp :REAL;
END_VAR
VAR_OUTPUT
Tem_actual_output :REAL;//实际值温度输出
END_VAR
BEGIN
//取11组温度放入中间数组
Tem_array_1【1】 :=Tem_actual_udt.Tem_01;
Tem_array_1【2】 :=Tem_actual_udt.Tem_02;
Tem_array_1【3】 :=Tem_actual_udt.Tem_03;
Tem_array_1【4】 :=Tem_actual_udt.Tem_04;
Tem_array_1【5】 :=Tem_actual_udt.Tem_05;
Tem_array_1【6】 :=Tem_actual_udt.Tem_06;
Tem_array_1【7】 :=Tem_actual_udt.Tem_07;
Tem_array_1【8】 :=Tem_actual_udt.Tem_08;
Tem_array_1【9】 :=Tem_actual_udt.Tem_09;
Tem_array_1【10】 :=Tem_actual_udt.Tem_10;
Tem_array_1【11】 :=Tem_actual_udt.Tem_11;
Tem_array_1【12】 :=Tem_actual_udt.Tem_12;
//开始冒泡程序
FOR Index_1 :=1 TO number-1 BY +1 DO
FOR Index_2 :=Index_1+1 TO number BY +1 DO
IF Tem_array_1【Index_1】 < Tem_array_1【Index_2】 THEN
Tem_temp :=Tem_array_1【Index_2】;
Tem_array_1【Index_2】 :=Tem_array_1【Index_1】;
Tem_array_1【Index_1】 :=Tem_temp;
END_IF;
END_FOR;
END_FOR;
//取中间大小的值作为温度的输出
Tem_actual_output :=Tem_array_1【6】;
南大傲拓NA系列PLC寻址方式介绍:
寻址,即为梯形图功能模块及其它编程方式访问测点的方法。有下列几种寻址方式可用:
1、 立即寻址
直接以常数作为访问对象。如下图的赋值功能模块,执行功能为把100赋值到%MW0001中,其输入端100即为立即寻址方式。
※ 立即寻址方式在数据输入时,十六进制的数据后加字母H,十六进制如果第一个数据为字母,要在前面加0,例如想输入B021H必须写为0B021H,否则系统编译时报错。
2、 直接寻址
直接寻址是以测点类型加测点序号作为访问对象。如图4.7的赋值操作,%MW0001作为一个指定测点,即为直接寻址方式。
作为一种特例,使用测点的名称也属于直接寻址,因为测点名称对应的是一个指定测点。例如:定义测点%I0001的名称为GD_ON,在程序中可以直接使用GD_ON,所指代的就是%I0001。
间接寻址,是指访问对象的测点序号不是一个常数,而是另一个测点,即以该测点的当前值作为测点序号。与直接寻址的测点序号不同,间接寻址的测点是从0开始的,即对于一个间接寻址的测点%I【%MW0001】,%MW0001的当前值为1,其访问的测点为%I0002,而不是%I0001。如图4.8所示梯形,%Q【%MW0001】即为间接寻址方式。其测点类型为Q,测点序号不是一个常数,而是另一个测点%MW0001。梯形执行的操作为:%MW0001被赋值为0,线圈对开出测点%Q0001输出1。