博图使用PEEK、POKE进行IO映射

博图 S7120、SCL语言编程、PEEK、POKE指令、IO映射

简介

有时候我们需要把一个变量映射到IO域上,比如把一个大小为16的数组变量对应到输出的Q0.0到Q1.7,如果一个一个赋值的话过于啰嗦,此时我们就可以使用SCL语言的PEEK、POKE指令,进行变址寻址映射

本文参考于西门子帮助中心网站:
http://www.ad.siemens.com.cn/productportal/Prods/S7-1200_PLC_EASY_PLUS/07-Program/03-instruction/03-Address/03-PEEK_POKE.html

背景

以停车场项目为例,共有20个车位,每个车位对应一个传感器和一个红灯。为方便程序编写,分别用DB块中的大小为20的数组变量表示车位传感器和红灯。用循环数组方式赋值就可以很方便的一次性将20个灯状态赋值。
博图使用PEEK、POKE进行IO映射_第1张图片但问题是,如何将数组中的输入输出变量,方便快捷的映射为I点和Q点呢?

SCL语言

首先说一下SCL语言,它可以很方便的完成梯形图中需要很多指令才能完成的工作,就像C语言写程序一般,主要用IF…THEN/FOR/WHILE语句去构造条件、循环、判断这样的结构,在这些结构中再次添加指令,去实现逻辑判断。所有程序的编写都是在纯文本的环境下编辑,但不像梯形图那么直观。

PEEK与POKE

使用S7-1200 ,SCL 编程语言的 PEEK 和 POKE 指令,可以实现对 I/O、M 存储器和数据块的读取或写入。
指令适用条件:

  • 只用于 SCL 编程语言;
  • 软件从TIA PORTAL V11 SP2起;
  • S7-1200 CPU 固件从 V2.2起;
  • 适用操作数,I、Q、M、DB;
  • DB必须是非优化访问的块。

因为我们是对I点、Q点寻址,所以使用 PEEK_BOOL和 POKE_BOOL指令。

PEEK_BOOL指令

PEEK_BOOL指令用来读取输入(I)、输出(Q)、存储器(M)或数据块(DB)变量的位。PEEK指令将获取的数据值以返回值的方式赋值给对应的变量。
PEEK_BOOL指令格式:
在这里插入图片描述其中,参数area,根据数据所在区域的不同有四种取值。

area值 类型 说明
16#81 I 输入区变量
16#82 Q 输出区变量
16#83 M M区变量
16#84 DB 数据块变量

POKE_BOOL指令

POKE _BOOL指令可以用来对输入(I)(一般不使用)、输出(Q)、存储器(M)或数据块(DB)变量地址进行写操作。POKE 指令可在指令体内将结果传递给对应变量。
PEEK_BOOL指令格式:
在这里插入图片描述参数area的取值同PEEK。

开始

首先新建一个FC块,命名为IO映射,语言选择SCL博图使用PEEK、POKE进行IO映射_第2张图片打开新建的块,上方拉出块接口,在其中新建两临时变量。其中i作为循环变量,io_offset成为IO域起始地址的偏移量。
博图使用PEEK、POKE进行IO映射_第3张图片在指令→基本指令→移动操作→读/写存储器中,找到PEEK_BOOL和POKE_BOOL指令,双击方便输入。
博图使用PEEK、POKE进行IO映射_第4张图片在FC块中输入如下代码

FOR #i := 0 TO 19 DO  //I -> 输入 
    #io_offset := #i + 8 * 2 + 0;//从I2.0开始
    "数组变量".车位传感器[#i] :=
     	PEEK_BOOL(area := 16#81,//16#81为I
                  dbNumber := 0,
                  byteOffset := #io_offset / 8,
                  bitOffset := #io_offset MOD 8);
END_FOR;

FOR #i := 0 TO 19 DO  //输出 -> Q
    #io_offset := #i + 8 * 4 + 0;//从Q4.0开始
    POKE_BOOL(area := 16#82, //16#82为Q
              dbNumber := 0,
              byteOffset := #io_offset / 8,
              bitOffset := #io_offset MOD 8,
              value := "数组变量".停车位红灯[#i]);
END_FOR

在这里
如果映射的地址是连续的存储空间,这种方法可以使用FOR循环赋值。容易发现规律,数组元素下标从0开始逐个加1,如果I/O点是从0.0开始,对应的输入地址的位变量是从0到7再往复,而字节地址是先是8个0,然后是8个1……所以总结是字节地址是下标整除8的商,位地址是下标整除8的余数,换成编程语言就是字节地址是下标/8,位地址是下标MOD8。如果字节地址不是从0.0开始,在循环的开始加一个偏移量就可以了。然后就可以利用FOR循环来快速实现逐个位的赋值。

你可能感兴趣的:(开发语言)