2.2 S7-400 CPU的存储区

2.2.1 数制

(1)二进制数 二进制数的1位(bit)只能取0和1这两个不同的值,可以用来表示开关量(或称数字量)的两种不同的状态,例如触点的断开和接通,线圈的通电和断电等。如果该位为1,表示梯形图中对应的位编程元件(例如位存储器M和输出过程映像Q)的线圈“通电”,其常开触点接通,常闭触点断开,以后称该编程元件为1状态,或称该编程元件ON(接通)。如果该位为0,对应的编程元件的线圈和触点的状态与上述的相反,称该编程元件为0状态,或称该编程元件OFF(断开),二进制常数用2#表示,例如2#1111_0110_1001_0001是16位二进制常数在编程手册和编程软件中,位编程元件的1状态和0状态常用TURE和FALSE来表示。

(2)十六进制数 十六进制的16个数字是0~9和A~F(对应于十进制数10~15),每个数字占二进制数的4位。B#16#、W#16#、DW#16#分别用来表示十六进制字节、字和双字常数,例如W#16#13AF,在数字后面加“H”也可以表示十六进制数,例如16#13AF可以表示为13。

十六进制数的运算规则为逢16进1,例如B#16#3C=3×16+12=60。

(3)BCD码 BCD码用4位二进制数表示一位十进制数,例如十进制数9对应的二进制数为1001。4位二进制数共有16种组合,有6种(1010~1111)没有在BCD码中使用。

BCD码的最高4位二进制数用来表示符号,16位BCD码字的范围为-999~+999。32位BCD码双字的范围为-9999999~+9999999。

BCD码实际上是十六进制数,但是各位之间的关系是逢10进1。十进制数可以很方便地转换为BCD码,例如十进制数296对应的BCD码为W#16#296,或2#0000 0001 0010 1000。

二进制整数2#0000 0001 0010 1000对应的十进制数也是296,因为它的第3位、第5位和第8位为1,对应的十进制数为28+25=23=256+32+8=296。

2.2.2 基本数据类型

STEP7有3种数据类型:

①基本数据类型;

②用户通过组合基本数据类型生成的复合数据类型;

③可用来定义传送FB(功能块)和FC(功能)参数的参数类型。

下面介绍STEP7的基本数据类型:

(1)位(bit) 位数据的数据类型为BOOL(布尔)型,在编程软件中BOOL变量的值1和0常用英语单词TURE(真)和FALSE(假)来表示。

位存储单元的地址由字节地址和位地址组成,例如I3.2中的区域标识符“I”表示输入(Input),字节地址为3,位地址为2(见图2-5)。这种存取方式称为“字节,位”寻址方式。输入字节IB3(B是Byte的编写)由I3.0~I3.7这8位组成。

图2-5 位数据的存放

(2)字节(Byte) 8位二进制数组成1个字节(Byte,见图2-5),其中的第0位为最低位(LSB),第7位为最高位(MSB)。

(3)字(Word) 相邻的两个字节组成一个字,字用来表示无符号数。MW100是由MB100和MB101组成的1个字(见图2-6),MB100为高位字节。MW100中的M为区域标识符,W表示字,100为字的起始字节MB100的地址。字的取值范围为W#16#0000~W#16#FFFF。

图2-6 字节、字和双字

(4)双字(Double Word) 两个字组成1个双字,双字用来表示无符号数。MD100是由MB100~MB103组成的1个双字(见图2-6),MB100为高位字节、D表示双字,100为双字的起始字节MB100的地址。双字的取值范围为DW#16#0000_0000~DW#16#FFFF_FFFF。

(5)16位整数(INT,Integer) 整数是有符号数,整数的是高位为符号位,最高位为0时为正数,为1时为负数,取值范围为-32768~32767。整数用补码来表示,正数的补码就是它的本身,将一个正数对应的二进制数的各位求反后加1,可以得到绝对值与它相同的负数的补码。

(6)32位整数(DINT,Double Integer) 32位整数的是高位为符号位,取值范围为-2147483648~217483647。

(7)32位浮点数 浮点数又称实数(REAL),浮点数可以表示为1.m×2E,例如123.4可表示为1.234×102。符合ANSI/IEEE 754—1985的基本格式的浮点数可表示为

浮点数=1.m×2E

e=E+127(1≤e≤254),为8位整数。

ANSI/IEEE标准浮点数格式如图2-7所示,共占用一个双字(32位)。最高位(第31位)为浮点数的符号位,最高位为0时为正数,为1时为负数,8位指数占23~30位;因为规定尾数的整数部分总是为1,只保留了尾数的小数部分m(0~22位)。浮点数的表示范围为±1.175495/10-38~±3.402823×1038

图2-7 浮点数的结构

浮点数的优点是用很小的存储空间(4B)可以表示非常大和非常小的数。PLC输入和输出的数值大多是整数(例如模拟量输入值和模拟量输出值),用浮点数来处理这些数据需要进行整数和浮点数之间的相互转换,浮点数的运算速度比整数运算的慢得多。

(8)常数的表示方法 常数值可以是字节、字或双字,CPU以二进制方式存储常数,常数也可以用十进制、十六进制ASCII码或浮点数形式来表示。如表2-1所示。

表2-1 常数  

B#16#,W#16#,DW#16#分别用来表示十六进制字节、字和双字常数。2#用来表示二进制常数,例如2#1101 1010。

L#为32位双整数常数,例如L#+5。

P#为地址指针常数,例如P#M2.0是M2.0的地址。

S5T#是16位S5时间常数,格式为S5T#aD_bH_cM_dS_eMS。其中a,b,c,d,e分别是日、小时、分、秒和毫秒的数值。输入时可以省掉下画线,例如S5T#4S30MS=4s30ms,S5T#2H15M30S=2小时15分30秒。

S5时间常数的取值范围为S5T#0H_0M_0MS_S5T#2H_46M_30S_0MS,时间增量为10ms。

T#为带符号的32位IEC时间常数,例如T#1D_12H_30M_0S_250MS,时间增量为1ms,取值范围为T#24D_20H_31M_23S_648MS_T#24D_20H_31M_23S_647MS。

DATE是IEC日期常数,例如D#2004.1.15。取值范围为D#1990.1.1~D#2168.12.31。

TOD#是32位实时时间(Time of day)常数,时间增量为1ms,例如TOD#23:50:45:300。

B(b1,b2)B(b1,b2,b3,b4)用来表示2个字节或4个字节常数。

C#为计数器常数(BCD码),例如C#250。

8位ASCII字符用单引号表示,例如‘ABC’。

2.2.3 复合数据类型与参数类型

(1)复合数据类型 通过组合基本数据类型和复合数据类型可以生成下面的数据类型:

①数组(ARRAY)将一组同一类型的数据组合在一起,形成一个单元。

②结构(STRUCT)将一组不同类型的数据组合在一起,形成一个单元。

③字符串(STRING)是最多有254个字符(CHAR)的一维数组。

④日期和时间(DATE-AND-TIME)用于存储年、月、日、时、分、秒、毫秒和星期,占用8个字节,用BCD格式保存。星期天的代码为1,星期一~星期六的代码为2~7。

例如DT#2004-07-15-12:30:15.200为2004年7月15日12时30分15.2秒。

⑤用户定义的数据类型UDT(User-Defined Data Types):由用户将基本数据类型和复合数据类型组合在一起,形成的新的数据类型。

可以在数据块DB和变量声明表中定义复合数据类型。

(2)参数类型 参数类型是为在逻辑块之间传递参数的形参(Formal Parameter,形式参数)定义的数据类型:

①TIMER(定时器)和COUNTER(计数器):指定执行逻辑块时要使用的定时器和计数器,对应的实参(Actual Parameter,实际参数)应为定时器或计数器的编号,例如T3,C21。

②BLOCK(块):指定一个块用作输入和输出,参数声明决定了使用的块的类型,例如FB、FC、DB等。块参数类型的实参应为同类型的块的绝对地址编号(例如FB2)或符号名(例如“motor”)。

③POINTER(指针):指针指向一个变量的地址,即用地址作为实参。例如P#50.0是指向M50.0的双字地址指针。

④ANY:用于实参的数据类型未知或实参可以使用任意数据类型的情况,占10B。

2.2.4 CPU的存储区分布

S7 CPU的存储器有3个基本区域(见图2-8)。

图2-8 存储区分布

(1)装载存储器 装载存储器可能是RAM和FEPROM,用于保存不包含符号地址和注释的用户程序和系统数据(组态,连接和模块参数等)。有的CPU有集成的装载存储器,有的可用微存储器卡(MMC)来扩展,CPU31XC的用户程序只能装入插入式的MMC。

断电时数据保存在MMC存储器中,因此数据块的内容基本上被永久保留。下载程序时,用户程序(逻辑块和数据块)被下载到CPU的装载存储器,CPU把可执行部分复制到工作存储器,符号表和注释保存在编程设备中。

(2)工作存储器 它是集成的高速度存取的RAM存储器,用于存储CPU运行时的用户程序和数据,例如组织块、功能块、功能和数据块。为了保证程序执行的快速性和不过多地占用工作存储器,只有与程序执行有关的块被装入工作存储器。

STL程序中的数据块可以被标识为“与执行无关”(UNLINKED),它们只是存储在装载存储器中。有必要时可以用SFC20“BLKMOV”将它们复制到工作存储器。复位CPU的存储器时,RAM中的程序被清除,FEPROM中的程序不会被清除。

(3)系统存储器 系统存储器是CPU为用户程序提供的存储器组件,被划分为若干个地址区域。使用指令可以在相应的地址区内对数据直接进行寻址。系统存储器为不能扩展的RAM,用于存放用户程序的操作数据,例如过程映像输入、过程映像输出、位存储器、定时器和计数器、块堆栈(B堆栈)、中断堆栈(I堆栈)和诊断缓冲区等。

系统存储器还提供临时存储器(局域数据堆栈,即L堆栈),用来存储程序块被调用时的临时数据。访问局域数据比访问数据块中的数据更快,用户生成块时,可以声明临时变量(TEMP),它们只在执行该块时有效,执行完后就被覆盖了。

(4)外设I/O存储区 通过外设I/O存储区(PI和PQ),用户可以不经过过程映像输入和过程映像输出,直接访问输入模块和输出模块。不能以位为单位访问外设I/O存储区,只能以字节、字和双字为单位访问。

2.2.5 系统存储器

(1)过程映像输入/输出(I/O)表 在扫描循环开始时,CPU读取数字量输入模块的输入信号的状态,并将它们存入过程映像输入表(Process Image Input,PII)中。

用户程序访问PLC的输入(I)和输出(Q)地址区时,不是去读写数字信号模块中的信号状态,而是访问CPU中的过程映像区。在扫描循环中,用户程序计算输出值,并将它们存入过程映像输出表(Process Image Output,PIQ)。在循环扫描开始时将过程映像输出表的内容写入数字量输出模块。

I和Q均可以按位、字节、字和双字来存取,例如I0.0、IB0、IW0和ID0。

与直接访问I/O模块相比,访问映像表可以保证在整个程序周期内,过程映像的状态始终一致。即使在程序执行过程中接在输入模块的外部信号状态发生了变化,过程映像表中的信号状态仍然保持不变,直到下一个循环被刷新。由于过程映像保存在CPU的系统存储器中,访问速度比直接访问信号模块快得多。见表2-2。

表2-2 系统存储区  

输入过程映像在用户程序中的标识符为I,是PLC接收外部输入的数字量信号的窗口。输入端可以外接常开触点或常闭触点,也可以接多个触点组成的串并联电路。PLC将外部电路的通/断状态读入并存储在输入过程映像中,外部输入电路接通时,对应的输入过程映像为ON(1状态);反之为OFF(0状态)。在梯形图中,可以多次使用输入过程映像的常开触点和常闭触点。

输出过程映像在用户程序中的标识符为Q,在循环周期开始时,CPU将输出过程映像的数据传送给输出模块,再由后者驱动外部负载。如果梯形图中Q0.0的线圈“通电”,继电器型输出模块中对应的硬件继电器的常开触点闭合,使接在Q0.0对应的输出端子的外部负载工作。输出模块中每一个硬件继电器仅有一对常开触点,但是在梯形图中,每一个输出位的常开触点和常闭触点都可以多次使用。

除了操作系统对过程映像的自动刷新外,S7-400 CPU可以将过程映像划分为最多15个区段,这意味着如果需要可以独立于循环,刷新过程映像表的某些区段,用STEP7指定的过程映像区段中的每一个I/O地址不再属于OB1过程映像输入/输出表。需要定义哪些I/O模块地址属于哪些过程映像区段。

可以在用户程序中用SFC(系统功能)刷新过程映像。SFC26“UPDAT-PI”用来刷新整个或部分过程映像输入表,SFC27“UPDAT-PQ”用来刷新整个或部分过程映像输出表。

某些CPU也可以调用OB(组织块)由系统自动地对指定的过程映像分区刷新。

(2)内部存储器标志位(M)存储器区 内部存储器标志位用来保存控制逻辑的中间操作状态或其他控制信息。虽然名为“位存储器区”,表示按位存取,但是也可以按字节、字或双字来存取。

(3)定时器(T)存储器区 定时器相当于继电器系统中的时间继电器。给定时器分配的字用于存储时间基值和时间值(0~999)。时间值可以用二进制或BCD码方式读取。

(4)计数器(C)存储器区 计数器用来累计其计数脉冲上升沿的次数,有加计数器、减计数器和加减计数器。给计数器分配的字用于存储计数当前值(0~999),计数值可以用二进制或BCD码方式读取。

(5)数据块(DB)与背景数据块(DI) DB为数据块,DBX是数据块中的数据位,DBB、DBW和DBD分别是数据块中的数据字节、数据字和数据双字。

DI为背景数据块,DIX是背景数据块中的数据位,DIB、DIW和DID分别是背景数据块中的数据字节、数据字和数据双字。

(6)外设I/O区(PI/PQ) 外设输入(PI)和外设输出(PQ)区允许直接访问本地的和分布式的输入模块和输出模块。可以按字节(PIB或PQB)、字(PIW或PQW)或双字(PID或PQD)存取,不能以位为单位存取PI和PQ。

2.2.6 CPU中的寄存器

(1)累加器(ACCUX) 32位累加器用于处理字节、字或双字的寄存器。S7-300有两个累加器(ASCII和ACCU2),S7-400有4个累加器(ACCU1~ACCU4)。可以把操作数送入累加器,并在累加器中进行运算和处理,保存在ACCU1中的运算结果可以传送到存储区。处理8位或16位数据时,数据放在累加器的低端(右对齐)。

(2)状态字寄存器(16位) 状态字(见图2-9)是一个16位的寄存器,用于存储CPU执行指令的状态。状态字中的某些位用于决定某些指令是否执行和以什么样的方式执行,执行指令时可能改变状态字中的某些位,用位逻辑指令和字逻辑指令可以访问和检测它们。

图2-9 状态字的结构

①首次检测位 状态字的第0位称为首次检测位(FC),若该位的状态为0,则表明一个梯形逻辑网络的开始,或指令为逻辑串的第一条指令。CPU对逻辑串第一条指令的检测(称为首次检测)产生的结果直接保存在状态字的RLO位中,经过首次检测存放在RLO中的0或1称为首次检测结果。该位在逻辑串的开始时总是0,在逻辑串指令执行过程中该位为1,指出指令或与逻辑运算有关的转移指令(表示一个逻辑串结束的指令)将该位清0。

②逻辑运算结果(RLO) 状态字的第1位称为逻辑运算结果RLO(Result of Logic Operation)。该位用来存储执行位逻辑指令或比较指令的结果,RLO的状态为1,表示有能流流到梯形图中运算点处,为0则表示无能流流到该点。可以用RLO触发跳转指令。

③状态位(STA) 状态位的第2位称为状态位,执行位逻辑指令时,STA总是与该位的值一致。

④或位(OR) 状态字的第3位称为或位(OR),在先逻辑“与”后逻辑“或”的逻辑运算中,OR位暂存逻辑“与”的操作结果,以便进行后面的逻辑“或”运算。其他指令将OR位复位。

⑤溢出位(OV) 状态字的第4位称为溢出位,如果算术运算或浮点数比较指令执行时出现错误(例如溢出、非法操作和不规范的格式),溢出位被置1。如果后面的同类指令执行结果正常,该位被清0。

⑥溢出状态保持位(OS) 状态字的第5位称为溢出状态保持位,或称为存储溢出位。OV位被置1时OS位也被置1,OV位被清0时OS仍保持,所以它保存了OV位,用于指明前面的指令执行过程中是否发生过错误。只有JOS(OS=1时跳转)指令、块调用指令和块结束指令才能复位OS位。

⑦条件码1(CC1)和条件码0(CC0) 状态字的第7位和第6位称为条件码1和条件码0。这两位综合起来用于表示在累加器1中产生的算术运算或逻辑运算的结果与0的大小关系、比较指令的执行结果或称位指令的移出位状态(见表2-3和表2-4)。

表2-3 算术运算后的CC1和CC0  

表2-4 指令执行后的CC1和CC0  

⑧二进制结果位(BR) 状态字的第8位称为二进制结果位。它将字处理程序与位处理联系起来,在一段既有位操作又有字操作的程序中,用于表示字操作结果是否正确。将BR位加入程序后,无论字操作结果如何,都不会造成二进制逻辑链中断。在梯形图的方框指令中,BR位与ENO有对应关系,用于表明方框指令是否被正确执行;如果执行出现了错误,BR位为0,ENO也为0;如果功能被正确执行,BR位为1,ENO也为1。

在用户编写的FB和FC程序中,必须对BR位进行管理,功能块正确执行后,使BR位为1,否则使其为0。使用SAVE指令可将RLO存入BR中,从而达到管理BR位的目的。当FB或FC执行无错误时,使RLO为1,并存入BR;否则在BR中存入0。状态字的9~15位未使用。

(3)数据块寄存器 DB和DI寄存器分别用来保存打开的共享数据块和背景数据块的编号。

(4)诊断缓冲区 诊断缓冲区是系统状态列表的一部分,包括系统诊断事件和用户定义的诊断事件的信息。这些信息按它们出现的顺序排列,第一行中是最新的事件。

诊断事件包括模块的故障、写处理的错误、CPU中的系统错误、CPU的运行模式切换错误、用户程序中的错误和用户用系统功能SFC 52定义的诊断错误。

2.2.7 寻址方式

操作数是指令操作或运算的对象,寻址方式是指令取得操作数的方式,操作数可以直接给出或间接给出。

(1)立即寻址 立即寻址的操作数直接在指令中,有些指令的操作数是惟一的,为简化起见不在指令中写出。表2-5是立即寻址的示例。下面是使用立即寻址的程序实例:

  SET    //把LO置1
  L 1352   //把常数1352装入累加器1
  AW W#16#3A12 //常数16#3A12与累加器1的低字相“与”,运算结果在累加器1的低字中。

表2-5 立即寻址举例  

(2)直接寻址 直接寻址在指令中直接给出存储器或寄存器的区域、长度和位置,例如用MW200指定位存储区中的字,地址为200;MB100表示以字节方式存取,MW100表示存取MB100、VB101组成的字,MD100表示存取MB100~MB103组成的双字。下面是直接寻址的程序实例:

  A  Q0.5
  L  MW4   //把MW4装入累加器1
  T  DHW2   //把累加器1低字中的内容传送给数据字DBW2

直接寻址举例见表2-6。

表2-6 直接寻址举例  

(3)存储器间接寻址 在存储器间接寻址指令中,给出一个作地址指针的存储器,该存储器的内容是操作数所在存储单元的地址。使用存储器间接寻址可以改变操作数的地址,在循环程序中经常使用存储器间接寻址。

地址指针可以是字或双字,定时器(T)、计数器(C)、数据块(DB)、功能块(FB)和功能(FC)编号范围小于65535,使用字指针就够了。

其他地址则要使用双字指针,如果要用双字格式的指针访问一个字、字节或双字存储器,必须保证指针的位编号为0,例如P#Q20.0。双字指针区域的格式如图2-10所示;位0~2为被寻址地址中位的编号(0~7),位3~18为被寻址的字节的编号(0~65535)。只有双字MD、LD、DBD和DID能作地址指针。下面是存储器间接寻址的例子:

  L QB[DBD 10] //将输出字节装入累加器1,输出字节的地址指针在数据双字DBD10中,如果DBD10的值为2#0000 0000 0000 0000 0000 0000 0010 0000,装入的是QB4
  A M[LD4]   //对存储器位作“与”运算,地址指针在数据双字LD4中如果LD4的值为2#0000 0000 0000 0000 0000 0000 0010 0011,则是对M4.3进行操作

图2-10 存储器间接寻址的双字指针格式

(4)寄存器间接寻址 S7中有两个地址寄存器AR1和AR2,通过它们可以对各存储区的存储器内容作寄存器间接寻址。地址寄存器的内容加上偏移量形成地址指针,后者指向数值所在的存储单元。

地址寄存器存储的双字地址指针见图2-11。其中第0~2位(xxx)为被寻址地址中位的编号(0~7),第3~18位(bbbb bbbb bbb bbbb)为被寻址地址的字节的编号(0~65535)。第24~26位(rrr)为被寻址地址的区域标识号,第31位x=0为区域内的间接寻址,第31位x=1为区域间的间接寻址。

图2-11 寄存器间接寻址的双字指针格式

第一种地址指针格式包括被寻址数值所在存储单元地址的字节编号和位编号,存储区的类型在指令中给出,例如L DBB[AR1,P#6.0],这种指针格式适用于在某一存储区内寻址,即区内寄存器间接寻址,第24~26位(rrr)应为0。

第二种地址指针格式的第24~26位还包含了说明数值所在存储区的存储区域标识符的编号rrr,用这几位可实现跨区寻址,这种指针格式用于区域间寄存器间接寻址。

区域间寄存器间接寻址的区域标识位如表2-7所示。

表2-7 区域间寄存器间接寻址的区域标识位  

如果要用寄存器指针访问一个字节、字或双字,必须保证指针中的位地址编号为0。

指针常数#P5.0对应的二进制数为2#0000 0000 0000 0000 0000 0000 0010 1000。下面是区内间接寻址的例子:

  L  P#5.0     //将间接寻址的指针装入累加器1
  LAR1      //将累加器1中的内容送到地址寄存器1
  A  M[AR1,P#2.3]        //AR1中的P#5.0加偏移量P#2.3,实际上是对M7.3进行操作
  =  Q[AR1,P#0.2]        //逻辑运算的结果送Q5.2
  L  DBW[AR1,P#18.0]        //将DBW23装入累加器1

下面是区域间间接寻址的例子:

  L  P#6.0     //将存储器位M6.0的双字指针装入累加器1
  LAR1    //将累加器1中的内容送到地址寄存器1
  T  W[AR1,P#50.0]        //将累加器1的内容传送到存储器字MW56

P#M6.0对应的二进制数为2#1000 0011 0000 0000 0000 0000 0011 0000。因为地址指针P#M6.0中已经包含有区域信息,使用间接寻址的指令TW[AR1,P#50]中没有必要再用地址标识符M。