我是电控阿甘,从事电气工作十余年,专注分享【电工基础知识 自动化控制知识】,助力电工入门和电工进阶电气工程师,点击右上方“关注”我,让我们共同进步,实现薪高一筹!
全文大约3400字,知识类文章阅读和休闲娱乐类文章阅读不同,需要阅读者在阅读过程中有一定的耐心和思考,阅读过程可能不会带给你短暂的快乐,但是认真看完,知识可以带给你长久的满足。
搞编程的人,无论是PLC编程还是别的什么编程肯定对直接寻址和间接寻址不陌生,因为编程的本质就是通过程序指令对数据进行操作。那么既然要对数据进行操作,总得先要找个地方存放数据,并且用的时候要能找到这个数据,那么具体到PLC中数据怎么存存储的?
以200SMART为例,首先讲内部存储器划分成了几个部分并加以命名,如M区、V区、T区等等,以M区为例,其数据存储如下图所示:
存储区表示方法
可以看到其最小储存数据单位是位,位里面的数据只能是0或者1,这显然是不足以满足我们使用的,比如我想储存一个100,一个位肯定是存不下的,这时候我们需要规定,8个连续的位合在一起称之为字节,这时候一个字节就可以存储100,里面就是以8个位的0和1组合表示的,也就是二进制,这就是解释了为什么老说计算机所有信息都是由一堆0和1组成的,PLC监控100的二进制表示如下图所示:
100的二进制表示
同样的道理我们定义的16个连续的位称之为一个字,32个连续的位称之为一个双字,显而易见的,存储单位越大其存储的内容肯定也就越多,以储存无符号整数为例,字节能表示的范围为0-255,而双字则是0-4294967295,并且无论任何表现形式,但是其本质上还是储存的一堆0和1,同样是上面例子中的100,不同格式显示值就不同,如下图所示:
100的不同格式显示
知道数据怎么存储之后,我们再来看一下如果我想对这个数据进行操作,我怎么能找到这个数据呢?到了今天的主题直接寻址和间接寻址。
先来看直接寻址,直接寻址分为绝对地址和符号寻址寻址。
绝对地址寻址的格式对于位来说就是存储区标识 字节地址 " . " "位地址",如M3.6代表M区的第3个字节的第6个位这个位,V200.0代表V区的第200个字节的第0个位这个位.
而对于字节(B)、字(W)、双字(D)寻址的格式则是存储区标识 类型 第一个字节地址.如VB100表示V区的字节类型的第100个字节开始的一个字节,VW100表示V区的字类型的第100个字节开始的2个字节,也就是VB100和VB101组成,同样的VD100表示表示V区的双字类型的第100个字节开始的4个字节,也就是VB100、VB101、VB102和VB103组成这四个字节组成。
符号寻址就更简单了,就是给绝对地址再起个给编程人员看的名字,比如M3.6起个名字叫启动按钮,那么你使用启动按钮和使用M3.6就是一回事。当程序足够多的时候如果满屏幕都是M0.1,V0.7,VB200,你根本不知道其含义,对于编程者和阅读者简直就是灾难。但如果屏幕上是启动按钮、停止按钮等这些有具体意义的符号的时候,我们就更容易编写和理解程序,因此在平时编程时候应尽量对每一个用到绝对地址赋予一个符号名。
接下来就到了很多朋友比较难理解的间接寻址了,先上官方间接寻址定义:间接寻址是指用指针来访问存储区的数据。指针以双字的形式存储其它存储区的地址,只能将 V 存储单元、L 存储单元或累加器寄存器(AC1、AC2、AC3)用作指针,S7-200 SMART CPU 允许指针访问下列存储区: I、Q、V、M、S、AI、AQ、SM、T(仅限当前值)和 C(仅限当前值)。不能使用间接寻址访问单个位或访问 HC、L 或累加器存储区。
如果没有一点计算机基础的朋友估计很难理解上面关于间接寻址的描述,看完理解不了没关系,如果很容易理解了我就不写这篇文章了,相信你跟着我的思路是完全可以理解间接寻址的,接下来我们就一起来看看吧。
首先呢,我们要知道上面的直接寻址中的绝对地址寻址比如V2.3、M4.5、VW100等其实还是西门子公司定义的区域标识,比如V区M区等,但是对于别的品牌的PLC就不一定是这些区域标识了,他可以起自己想叫的任何名字,但是这些存储区的底层都会有一个自己的编号地址,通常都是以字节为单位进行地址编号,这个不仅限于任何品牌的PLC这种小型计算机设备,而是所有类型的计算机都是如此,这个地址编号就如同你的身份证号码一样,在这台计算机的存储区中独一无二,就像如果知道这个人的身份证号码就能准确找到这个人一样,我们可以根据这个最底层的地址编号来找到这个地址中存储的数据,这就是所谓的间接寻址。
我们先来看一下200SMART中这个独一无二的地址编号长什么样子,请看下图,通过监控程序我们可以清楚地可以看到VB100的身份证号码是134217828,而VB101的身份证号码是134217829,同样的我们可以看到想要得到这个地址就需要用“&”这个符号加上要访问的存储区的首个字节地址即可,同样的这个字节的地址编号要使用一个双字的空间进行存储,图中VB100的地址编号使用VD1000存储,VB101的地址编号使用VD1004存储,而这个存储地址编号的变量就是指针,也就是VD1000和VD1004就叫指针,这么一看指针好像也没有那么难,无非就是一个普通的双字存储区,内部放了别的字节类型存储区的底层地址编号而已,就摇身一变成了指针了。
VB100和VB101的底层地址编号
有了这个底层的地址编号有什么用吗?当然有了!重点来了,我们可以根据这个地址编号来得到这个地址编号对应存储空间中的值,这就是间接寻址。具体怎么操作呢?很简单,使用“*”加上指针即可,如下图所示,可以很清晰的看到因为VD1000中放的是VB100的底层地址编号,也就是VD1000就是VB100的指针,那么通过“*”加上VD1000就可以得到的值就是VB100的值,即得到的值为123,同样的道理通过“*”加上VD1004就可以得到的值就是VB101的值,即得到的值为211。以VB100为例,我们为了得到里面的值绕了一个大弯,先通过“&”得到了VB100的底层地址存到VD1000中,再用“*”得到了底层地址对应存储空间中的值,相对于直接寻址,是不是相当“间接”了?叫个间接寻址一点都不过分吧。
取指针中的值
看到这里可能会想,这用间接寻址只是访问到字节,那如果想访问字和双字怎么办?很简单还是只关心第一个字节的底层地址即可,如果使用MOV_B指令访问的就是一个字节,如果使用MOV_W指令访问的就是一个字,如果使用MOV_DW访问的就是一个双字。一下图为例,可以看到无论访问VB100、VW100、VD100,只需要取VB100的底层地址编号即可,分别使用MOV_B、MOV_W、MOV_DW指令即可分别访问VB100、VW100、VD100中的值。
间接寻址字节、字、双字操作
讲了这么多,相信你已经很清楚直接寻址和间接寻址有了很清楚地认识,但是我知道你现在在想什么,你一定在想PLC中用直接寻址多方便快捷,搞个间接寻址绕来绕去一大圈,那么麻烦最终才得到个值,真是多此一举!是,对于上面的例子看起来间接寻址着实没啥用,但是我想告诉你,搞出来间接寻址这个东西绝对不是吃没没事干闲,而是在实际的编程中有一些情况使用直接寻址做起来基本上没办法做,但是如果使用间接寻址就比较简单了,比如VB0到VB199共200每个字节中都是整数,让你求出最大值,可以想一下如果用直接寻址你怎么做?写200个比较指令一个一个比较?想想就崩溃,那如果是1000个字节呢?同样类似的问题求200个字节中的整数和怎么做?直接寻址用200个加法指令一个一个加?类似的问题很多,此时如果用间接寻址加上FOR循环,几行指令就能轻松搞定,另外还有处理子程序接口超过16个等问题,当你碰到类似的直接寻址不好解决的情况时你才知道间接寻址有多好用。
好了,关于直接寻址和间接寻址今天就给大家聊到这里,后面我会用间接寻址方法来编写一个200个整数值求和的程序用来加深大家对间接寻址的理解,希望可以给大家的学习带来帮助。另外我的主页中有很多关于PLC基础知识的文章和视频,都是一些学习PLC必要的知识,同时考虑到初学者初次理解困难,全部采用大白话讲解的,有兴趣的可以去看下,希望这些文章和视频够帮到大家,如果还有其它关于电工和PLC的问题,可以下方留言讨论,谢谢大家。