S7-300和S7-400寻址

2018年6月26日22:51:48 发表评论 354 阅读

摘   要 本文对S7-300, S7-400 PLC编程过程中,所涉及的寻址方式方法,做了简单介绍及简单示例。

关键词  STEP7, 编程,寻址,间接寻址,S7-300, S7-400

Key Words  STEP7, Programming, Addressing, Indirection addressing, S7-300,S7-400

目       录

S7-300和S7-400寻址

1.S7-300/400系统存储区域

2. S7-300/400 PLC寻址方式

      2.1直接寻址

2.1.1绝对地址:

2.1.2符号寻址:

      2.2间接寻址

2.2.1存储器间接寻址

2.2.2寄存器间接寻址

2.2.3 FB/FC的指针参数传递

1 S7-300/400系统存储区域

S7 CPU的系统存储区域分为下表中列出的地址区域。在程序中可以根据相应的地址直接读取数据。

地址区域 可以访问的地址单位 S7符号

(IEC)

描述
过程映像输入表 输入(位) I 循环扫描周期开始时,CPU从输入模板读输入值并记录到该区域
输入(字节) IB
输入(字) IW
输入(双字) ID
过程映像输出表 输出(位) Q 在循环扫描周期中,程序计算输出值并记录到该区域。循环扫描周期结束时,CPU将计算结果写入相应的输出模板
输出(字节) QB
输出(字) QW
输出(双字) QD
位存储器 存储器(位) M 该区域用于存储程序的中间计算结果
存储器(字节) MB
存储器(字) MW
存储器(双字) MD
定时器 定时器 (T) T 该区域提供定时器的存储
计数器 计数器 (C) C 该区域提供计数器的存储
数据块 数据块,用"OPN DB"打开 DB 数据块中包含了程序的信息。可以定义为所有逻辑块共享 (shared DBs) 或指定给一个特定的 FB或 SFB 做背景数据块(instance DB)。
数据位 DBX
数据字节 DBB
数据字 DBW
数据双字 DBD
数据块,用"OPN DI"打开 DI
数据位 DIX
数据字节 DIB
数据字 DIW
数据双字 DID
局部数据 局部数据位 L 该区域包含块执行时该块的临时数据。L堆栈还提供用于传递块参数及记录梯形逻辑网络中间结果的存储器
局部数据字节 LB
局部数据字 LW
局部数据双字 LD
外设地址 (I/O) 外设输入字节 PIB 主站及分布式从站(DP)外设输入输出区域允许直接存取
输入
外设输入字 PIW
外设输入双字 PID
外设地址 (I/O) 外设输出字节 PQB
输出
外设输出字 PQW
外设输出双字 PQD

 

2.S7-300/400 PLC寻址方式

2.1直接寻址

在STEP7程序中可以使用输入输出信号(I/O),位存储区(M),计数器(C),计时器(T),数据块(DB)以及功能块(FB)等地址。你可以直接访问这些绝对地址,但是如果给绝对地址以符号(助记符)程序将更易读懂(例如Motor_A_On, 或者根据你的公司或者工程中的代码使用别的标识符),而一个你的用户程序中的地址也就可以用一个符号来访问。

2.1.1绝对地址:

绝对地址由一个地址标识符和存储器位置组成。

例如I 0.0,Q 1.7,PIW 256,PQW 512,MD 20,T 15,C 16,DB1.DBB 10,L1 0.0等。

2.1.2符号寻址:

如果给绝对地址分配符号可使程序易读而简化故障查找。

STEP7能自动翻译符号名为要求的绝对地址。如果你准备用符号名访问 数组,结构,数据块,局部变量,逻辑块及用户自定义数据类型,那么你必须在此之前先分配符号名给绝对地址。

例如, 你可以分配符号名’Motor_On’给地址Q 4.0,然后在程序语句中使用符名’Motor_On’作为地址。

如需在程序中显示DB里所定义的符号,可以给该DB块定义一个符号。不能在符号表给DB块中某地址单独定义符号。

2.2间接寻址

间接寻址分为存储器间接寻址和寄存器间接寻址,间接寻址的指针分为16位指针和32位指针,而32位指针又分为内部区域寻址与交叉区域寻址。

2.2.1存储器间接寻址

►16位指针:16位地址指针用于定时器、计数器、程序块(DB、FC、FB)的寻址,16位指针被看作一个无符号整数(0~65535),它表示定时器(T)、计数器(C)、数据块(DB、DI)或程序块(FB、FC)的号,16位指针的格式如下:

image004.jpg

图1

 

寻址格式表示为:   区域标识符 [ 16位地址指针 ]

例如使一个计数器向上计数表示为:

CU         C [ MW ]

上述指令中,’C’为区域标识符,而’MW20’为一个16位指针。

 

16位指针存储器间接寻址举例:

 

//用于定时器

L    1

T    MW0                    //将1传送到MW0

A    I0.0               //如果I0.0 = True

L    S5T#10S

SD T[MW0]         //T1开始计时

//            上述指令可等同于:

A    I0.0

L    S5T#10S

SD T1

 

//用于打开DB块

L    20

T    LW20

OPN       DB[LW20]            //打开DB20

 

//程序调用

L     2

T    LW20

UC  FC[LW20]            //调用FC2

 

L     41

T    DBW30

UC        FB[DBW30]          //调用FB41

 

►32位指针:32位地址指针用于I、Q、M、L、数据块等存储器中位、字节、字及双字的寻址,32位的地址指针可以使用一个双字表示,第0位~第2位作为寻址操作的位地址,第3位~第18位作为寻址操作的字节地址,第19位~第31位没有定义,32位指针的格式如下:

image006.jpg

图 2

 

存储器32指针仅用于内部区域寻址。

寻址格式表示为:   地址存储器标识符  [ 32位地址指针 ]

 

例如写入一个M的双字表示为:

T     MD [ LD0 ]

‘MD’为区域标识符及访问宽度,而LD0为一个32位指针。

 

32位内部区域指针可用常数表示, 表示为P# 字节.位 。如常数

P#   10.3

为指向第10个字节第3位的指针常数。

若把一个32位整型转换为字节指针常数,从上述指针格式可以看出,应要把该数左移3位(或是乘8)即可。

如:       L     L#100           //Accu0装入32位整形100

SLD       3                   //左移3位

T     LD0               //LD0得到P#100.0指针常数

 

32位存储器间接寻址举例:

 

//DB块间接寻址举例

OPN       DB  1            //打开DB1。

OPN       DI    3            //打开DB3,最多可以同时打开两个DB块。

L     4                   //装载4到累加器1中。

SLD       3                   //累加器1中数值左移3位。

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中。

JZ       m1

 

//M存储器连续区域操作

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(每个相邻的字地址相差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指针的数据,将转换为数组

JCN     m2                          //的位置((地址值/P#2.0)+1)值存储于MD8中。

L        MD      4

L        P#2.0

/D

+     L#1

T        MD            8

m2:      NOP   0

 

2.2.2寄存器间接寻址

通过CPU的地址寄存器AR1和AR2寻址方式称为寄存器间接寻址,分为内部区域间接寻址和交叉区域寻址。使用寄存器间接寻址方式的程序语句包含以下部分:

 

指令,地址标识符,地址寄存器标识符,偏移量

 

AR1,AR2均为32位寄存器,寄存器间接寻址只使用32位指针。

与ARx相关的指令有:

 

LAR1, LAR2, TAR1, TAR2, +AR1, +AR2, LAR1 AR2, CAR等。

以上指令使用请参考手册:开始 -> (所有)程序 -> SIMATIC -> Documentation -> English -> STEP 7 – Statement List for S7-300 and S7-400。

 

►内部区域寄存器间接寻址

指针格式与存储器间接寻址的32位指针相同,第0位~第2位作为寻址操作的位地址,第3位~第18位作为寻址操作的字节地址,第19位~第31位没有定义,32位指针的格式如下:

image007.jpg

图 3

间接寻址表示为:存储器标识符 [ ARx, 地址偏移量 ]

如:

L     MW [AR1, P#2.0]

‘MW’为被访问的存储器及访问宽度,’AR1’为地址寄存器1,P#2.0为地址偏移量。

 

内部区域寄存寻址举例:

 

//DB块寄存器内部寻址

OPN   DB     1            //打开DB1。

LAR1    P#10.0         //将指针P#10.0 装载到地址寄存器1中。

L        DBW      [AR1, P#12.0]     //将DBW22装载到累加器1中。

LAR1    MD      20                   //将存储于MD20中的指针装载到地址寄存器1中。

L        DBW     [AR1, P#0.0] //将DBW装载到累加器1中,地址存储于MD20中。

+I

LAR2    P#40.0                        //将指针P#40.0 装载到地址寄存器2中。

T        DBW     [AR2, P#0.0] //运算结果传送到DBW40中。

 

//DI、DO区寄存器内部寻址

L     P#8.7                   //装载指向第8字节第7位的指针值到累加器1

LAR1                                     //累加器1中的指针装载到AR1

A     I     [AR1, P#0.0] //查询I8.7的信号状态

=    Q    [AR1, P#1.1] //给输出位Q10.0赋值

 

►交叉区域寄存器间接寻址

包含有存储器区域信息的指针,称为交叉区域指针。

同样,交叉区域指针为32位,寄存器间接寻址要使用地址寄存器AR1或AR2。

32位交叉区域指针,左起0~18位格式与32位内部区域指针相同,19~23位,27~30位未定义,31位为交叉区域指针标识位。

24~26位是存储区域地址标识,8中组合表示8种存储器区域:

000     表示没有地址区,例如P#12.0;

001     表示输入地址区I,例如P#I12.0;

010     表示输出地址区Q,例如P#Q12.0;

011     表示标志位地址区M,例如P#M12.0;

100     表示数据块(DB)中的数据,例如P#DB1.DBX12.0

101     表示数据块(DI)中的数据,例如P#DI1.DIX12.0

110     表示区域地址区L,例如P#L12.0;

111     表示调用程序块的区域地址区V,例如P#V12.0;

交叉区域指针格式如下:

image008.png

图 4

 

交叉区域指针常数表达为:P#   存储器  字节 . 位

 

例如:    P#Q10.5              //指向Q区第10字节第5位的指针常

P#DB1.DBX32.0  //指向DB1区域的第32字节第0位的指针常数

 

交叉区域寻址表示为:       访问宽度 [ ARx, 偏移量 ]

例如:    L     W [ AR2, P#1.0 ]

‘W’为访问宽度,AR2为地址寄存器2,P#1.0为偏移量。

 

交叉区域间接寻址举例:

//M存储区

L     P#M20.0

LAR1

L     1234

T     W [ AR1, P#2.0]

 

//I存储区

L     P#I0.0

LAR2

L     W[ AR2, P#0.0 ]

T     MW0

 

2.2.3 FB/FC的指针参数传递

在使用FB/FC形参传递指针参数时,16位、32位指针是可用的,但POINTER与ANY指针类型也是常见的类型,因为更方便。

►16指针用于参数传递

例如:

//编写一个FC,作用是启动条件满足后延时3秒输出闭合信号

//定义FC的形参如下:

image010.png

图 5

//程序如下:

L     #Pointer16

T     LW     0            //将16位指针装入LW0

A     #Start                   //Start参数 = True时

L     S5T#3S        //计时3秒

SD  T [LW 0]

A     T [LW 0]        //计时器计时到

=     #Motor                 //输出Motor = True

 

*32指针用于参数传递

//编写一个FC,作用是将输入DB块指定的区域 (实数) 求出平均值

//定义形参如下:

image012.png

图 6

//程序如下:

L     #DB_No

T     LW     0          //装载DB块号至LW0

OPN   DB [LW 0]                //并打开该DB块

 

L     #Data_1st

T     LD     2                         //装载第一个要计算的实数的32指针至LD0

 

L     0

T     LD     8                         //将'和'初始为 0

 

L     #Len                              //长度

NEXT:        T     LW     6             //实数的个数装载至LW6, 并且进入一个LOOP循环

L     DBD [LD 2]              //读取LD2指针位置的实数

L     LD     8

+R                                      //与'和'相加

T     LD     8                         //结果存到'和'中

L     LD     2                          //装入指针

L     P#4.0

+D                                      //指针加4个字节

T     LD     2                         //结果仍存入LD2,此时LD2指针指向下一个实数

 

L     LW     6                         //循环计数

LOOP  NEXT                        //LOOP循环的结束

 

L     #Len                         //将实数个数由INT转成REAL

ITD

DTR

T     LD    12

L     LD     8                          //'和'除以实数格式的实数个数

TAK

/R

T     #Average_out            //得到平均值,通过Average_out输出

 

►POINTER数据类型及参数传递

POINTER是一种用于传递指针的形参数据类型,长度为6个字节。用于向被调用的函数FC及函数块FB传递复合数据类型(如ARRAY、STRUCT及DT等)的实参。在被调用的函数FC及函数块FB内部可以间接访问实参的存储器。

格式如下:

image015.jpg

图 7

POINTER参数中,数据区含义如下:

16进制代码 数据区 简单描述
B#16#81 I 输入区
B#16#82 Q 输出区
B#16#83 M 标志位
B#16#84 DB 数据块
B#16#85 DI 背景数据块
B#16#86 L 区域数据区
B#16#87 V 上赋值的区域数据

表 1

若数据区为B#16#84,那么表示该POINTER指针是一个DB块地址,DB块号区域应当是所指向的DB块号(INT类型)并且不为零。

(请参考ANY数据类型举例)

►ANY数据类型及参数传递

ANY是一种用于传递指针的形参数据类型,可视为POINTER类型的扩展,较POINTER类型为复杂,长度为10个字节,增加的4字节,最高字节 (Byte 0) 固定为B#16#10,第二字节 (Byte 1) 为ANY指针所指向区域的数据类型,而接下来的2字节 (BYTE 3, 4) 组合为一个INT,为ANY指针所指定区域的长度,称为重复系数 (Repetition factor) 。其余6字节作用与POINTER类型相同。

格式如下

image017.jpg

图 8

 

其中数据类型含义为:

数据类型代码
十六进制代码 数据类型 简单描述
B#16#00 NIL
B#16#01 BOOL
B#16#02 BYTE 8位字节
B#16#03 CHAR 8位字符
B#16#04 WORD 16位字
B#16#05 INT 16位整形
B#16#06 DWORD 32位双字
B#16#07 DINT 32位双整形
B#16#08 REAL 32位浮点
B#16#09 DATE IEC日期
B#16#0A TIME_OF_DAY(TOD) 24小时时间
B#16#0B TIME IEC时间
B#16#0C S5TIME SIMATIC时间
B#16#0E DATE_AND_TIME(DT) 时钟
B#16#13 STRING 字符串
B#16#17 BLOCK_FB FB号
B#16#18 BLOCK_FC FC号
B#16#19 BLOCK_DB DB号
B#16#1A BLOCK_SDB SDB号
B#16#1C COUNTER 计数器
B#16#1D TIMER 定时器

表 2

 

编程举例:

//冒泡排序程序,算法原理请参考相关资料

//此例程仅提供存于DB块中的INT类型数据排序

//结果为INT数据由小到大排列,保存于原DB块中

//FC3块,形参定义如下:

image018.png

图 9

 

//输入参数Data(Any类型);输出参数Error(INT类型)

//若输出参数Error不为0, 则说明排序未进行,

//Error = 1, Data(ANY类型)输入指针无效

//Error = 2, Data(ANY类型)输入指针地址非DB地址

//Error = 3, Data(ANY类型)输入指针指定区域类型非INT类型

 

 

SET

SAVE

L     0

T     #Error

 

//将输入ANY指针'Data_In'复制到LB0~LB9

L     P##Data

LAR1

L     D [AR1,P#0.0]

T     LD     0

L     D [AR1,P#4.0]

T     LD     4

L     W [AR1,P#8.0]

T     LW     8

 

//ANY指针BYTE0是B#16#10

L     LB     0

L     B#16#10

==I

JCN   ERR1

 

//输入数据区是否为DB块

L     LB     6

L     B#16#84

==I

JCN   ERR2

 

//类型为INT

L     LB     1

L     B#16#5

==I

JCN   ERR3

 

//打开输入DB块

OPN   DB [LW 4]

 

//数据起始地址去掉数据区标识部分

L     LD     6

L     DW#16#FFFFFF

AD

T     LD    10

//计算最后一个存储单元指针保存至LD10

L     LW     2

L     2

*I

T     LD    14

L     L#2

-D

SLD   3

L     LD    10

+D

T     LD    10

 

//外循环计数LW20,循环次数为(数据个数-1)次

L     LW     2

L     1

-I

NXT2: T     LW    20

L     LD    10

LAR1

L     LW    20

 

//嵌套循环计数LW18,循环次数为(LW20)次

NXT1: T     LW    18

TAR1

L     P#2.0

-D

LAR1

 

//后一单元数据小于前一单元数据?

L     DBW [AR1,P#2.0]

L     DBW [AR1,P#0.0]

<I

JCN   L1

 

//否,交换2单元数据

L     DBW [AR1,P#2.0]

L     DBW [AR1,P#0.0]

T     DBW [AR1,P#2.0]

POP

T     DBW [AR1,P#0.0]

 

L1:   L     LW    18

LOOP  NXT1

L     LW    20

LOOP  NXT2

JU    EXIT

//错误码1,ANY指针有错

ERR1: L     1

T     #Error

JU    EXIT

 

//错误码2,输入数据区不是DB块

ERR2: L     2

T     #Error

JU    EXIT

 

//错误码3,输入数据类型不是INT

ERR3: L     3

T     #Error

 

EXIT:     SET

SAVE

 

在OB1程序中调用举例:

A     M      0.0

FP    M      0.1

JCN   EXIT

CALL  FC     3                 //FC3为上述排序程序

Data  :=P#DB3.DBX 0.0 INT 64  //参数Data, DB3中64个INT排序

Error  :=MW2

EXIT: NOP   0

weinxin
plc入门知识问答
所有PLC工程师都会关注的微信公众账号,只需输入您的问题,就会有答案

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: