搜索
bottom↓
回复: 19
打印 上一主题 下一主题

开源PLC学习笔记02(再从51开始)——2013_11_8

[复制链接]

出0入0汤圆

跳转到指定楼层
1
发表于 2013-11-8 11:26:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 oldbeginner 于 2013-11-8 12:33 编辑

******************************
在笔记01中,引出了可仿真的精简PLC 51版本,主要是为了研究PLC指令的实现,不能通讯,也只有有限的几个常用命令。这样能更容易把精力集中在理解指令如何实现上,而不会被庞杂的更多的其它功能而影响,而其它功能也会遵循类似方法,一个一个地被研究,最后再综合在一起。
******************************

简短复习一下笔记01,它的核心主体是通过51实现简单的PLC命令,PLC命令是人工输入的,但是符合PLC编程逻辑,并通过仿真实现,不需要开发板很方便。

从图中可看出,二当家(main_PLC)中的代码和PLC中编程逻辑是一致的,实现的功能如下图,


非常生动,我也是这样被吸引才开始写学习笔记的。在笔记01中主要理解了程序流程和LD OUT SET RST指令,在笔记02中将要理解输入端口和输出端口的定义。
*******************************

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

2
 楼主| 发表于 2013-11-8 12:17:34 | 只看该作者
看来C语音也需要再回顾加深一下了,端口的定义需要理解下面的结构和联合体。

//定义一个只能按位域寻址的新变量类型
typedef struct {
  unsigned char BIT0: 1;
  unsigned char BIT1: 1;
  unsigned char BIT2: 1;
  unsigned char BIT3: 1;
  unsigned char BIT4: 1;
  unsigned char BIT5: 1;
  unsigned char BIT6: 1;
  unsigned char BIT7: 1;
}TYPE_BIT;  

//定义一个既能按位域寻址也可按字节寻址的新变量类型
typedef union {
  TYPE_BIT       BIT;      //可以按位域寻址

  unsigned char  BYTE;                                        //可以按字节寻址
}TYPE_BIT_BYTE;  

***********************************
结构在51中用的很多,union需要再学习一下,搜一下找到重点:union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。http://see.xidian.edu.cn/cpp/html/450.html

看了union的定义之后,基本明白了用法,也可以理解按位域或按字节寻址。
只看输入端口:
1、 16个输入端口,    编号:X0-X7 X10-X17
#define   _X_num      16

2、 16个输入端口,所占内存字节数
#define   _X_BYTE     (_X_num + 7) / 8  

_X_BYTE的计算结果是 (16+7)/8=2,也就是输入端口是双字节,双字节就是16位二进制

3、  位元件 X 存储位
TYPE_BIT_BYTE   data  rX[_X_BYTE];

TYPE_BIT_BYTE和_X_BYTE已经分析了,
使用TYPE_BIT_BYTE来理解对我这样的初学者有些复杂,我还是先理解为结构体,如果在后面的理解中出现问题再更换。

TYPE_BIT   data  rX[2]
可以理解了,TYPE_BIT是个结构体,定义了8个二进制位(类似寄存器),输入端口有2个结构体,正好是16位,对应X0--X7和X10--X17。

出0入16汤圆

3
发表于 2013-11-8 12:23:01 | 只看该作者
默默的支持楼主!

出0入0汤圆

4
 楼主| 发表于 2013-11-8 12:29:37 | 只看该作者
oldbeginner 发表于 2013-11-8 12:17
看来C语音也需要再回顾加深一下了,端口的定义需要理解下面的结构和联合体。

//定义一个只能按位域寻址的 ...



我刚开始看下面的的定义时云里雾里的,摸不着门,不过,现在可以解决了。
//-------------------------------------------------------------------------------------//
//  位元件 X存储位                                                     //
//-------------------------------------------------------------------------------------//
#define    _X0_       rX[0].BIT.BIT0   
#define    _X1_       rX[0].BIT.BIT1   
#define    _X2_       rX[0].BIT.BIT2   
#define    _X3_       rX[0].BIT.BIT3   
#define    _X4_       rX[0].BIT.BIT4   
#define    _X5_       rX[0].BIT.BIT5   
#define    _X6_       rX[0].BIT.BIT6   
#define    _X7_       rX[0].BIT.BIT7   
#define    _X10_      rX[1].BIT.BIT0   
#define    _X11_      rX[1].BIT.BIT1   
#define    _X12_      rX[1].BIT.BIT2   
#define    _X13_      rX[1].BIT.BIT3   
#define    _X14_      rX[1].BIT.BIT4   
#define    _X15_      rX[1].BIT.BIT5   
#define    _X16_      rX[1].BIT.BIT6   
#define    _X17_      rX[1].BIT.BIT7  

rx[0]是一个定义了8位二进制的结构体,因为实际上多用了一个联合体,所以中间多出了一个bit(对我来说,理解难度增加了一倍)。还是按照结构体的思想(去掉联合体)。则上面变为
//-------------------------------------------------------------------------------------//
// 把rx作为结构体数组, 位元件 X存储位                                                     //
//-------------------------------------------------------------------------------------//
#define    _X0_       rX[0].BIT0   
#define    _X1_       rX[0].BIT1   
#define    _X2_       rX[0].BIT2   
#define    _X3_       rX[0].BIT3   
。。。。。。
#define    _X7_       rX[0]..BIT7   
#define    _X10_      rX[1].BIT0   
。。。。。。。
#define    _X17_      rX[1].BIT7  

这样看起来清洁多了,也更好理解。

************************************
输出端口采用同样方法,只有8个输出端口

#define    _Y0_       rY[0].BIT.BIT0   
#define    _Y1_       rY[0].BIT.BIT1   
#define    _Y2_       rY[0].BIT.BIT2   
#define    _Y3_       rY[0].BIT.BIT3   
#define    _Y4_       rY[0].BIT.BIT4   
#define    _Y5_       rY[0].BIT.BIT5   
#define    _Y6_       rY[0].BIT.BIT6   
#define    _Y7_       rY[0].BIT.BIT7
  
理解为
#define    _Y0_       rY[0].BIT0   
#define    _Y1_       rY[0].BIT1   
#define    _Y2_       rY[0].BIT2   
#define    _Y3_       rY[0].BIT3   
#define    _Y4_       rY[0].BIT4   
#define    _Y5_       rY[0].BIT5   
#define    _Y6_       rY[0].BIT6   
#define    _Y7_       rY[0].BIT7  


************************************
这样输入端口和输出端口的定义就清楚了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

5
 楼主| 发表于 2013-11-8 12:53:22 | 只看该作者
本帖最后由 oldbeginner 于 2013-11-8 12:59 编辑
oldbeginner 发表于 2013-11-8 12:29
我刚开始看下面的的定义时云里雾里的,摸不着门,不过,现在可以解决了。
//------------------------- ...


现在就可以理解端口刷新,我刚开始理解为初始化是不正确的。
//------------------------------------------------------------------------------------------------------------
//X输入,Y输出刷新
//------------------------------------------------------------------------------------------------------------
static void RefreshIO(void)
{
        rX[0].BYTE =~P1;
         rX[1].BYTE =~P2;

        P0 = rY[0].BYTE;
}
********************
果然,在这里需要理解为联合体,好在代码短小。

输出最好理解,先看
P0 = rY[0].BYTE;
P0是输出端口,因为联合体内只有一个空间,所以BYTE对应rY[0](在前面的分析中理解为结构体)的8个二进制位。

再看输入端口,
rX[0].BYTE =~P1;
多了一个取反,这时再看电路图,按键的另一端接地,这样当按键按下时,端口是低电平(为0),但是在程序逻辑里要表示为1,所以取反。
同理 rX[1].BYTE =~P2;

这个端口刷新函数为什么定义为静态函数?搜一下,也可以理解。
静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多。
关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
****************************
在PLC_Configure.h中
//  位运算器及 7级中间过渡栈
extern unsigned char   data  ACC_BIT;                        

//  位元件 X,Y 存储位
extern TYPE_BIT_BYTE   data  rX[_X_BYTE] , rY[_Y_BYTE];

搜一下,若本文件 引用别的文件中的全局变量  一定要加上extern 声明一下,http://zhidao.baidu.com/link?url ... 0dUVHC5ChADZstKT8aq

出0入0汤圆

6
发表于 2013-11-8 13:09:28 | 只看该作者
资格帖子要严重支持下........

出0入0汤圆

7
 楼主| 发表于 2013-11-8 13:10:20 | 只看该作者
oldbeginner 发表于 2013-11-8 12:53
现在就可以理解端口刷新,我刚开始理解为初始化是不正确的。
//--------------------------------------- ...

比我想象地内容要少,看起来在理解简单命令上进展还是比较顺利。暂时先不理解其它的命令,开始通讯代码方面的笔记。


仿真和最小代码



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

8
发表于 2013-11-8 13:52:30 | 只看该作者
很通俗易懂,顶

出0入0汤圆

9
发表于 2013-11-8 14:10:28 | 只看该作者
学习了,楼主继续,楼主加油!!

出0入0汤圆

10
 楼主| 发表于 2013-11-9 15:32:17 | 只看该作者
oldbeginner 发表于 2013-11-8 13:10
比我想象地内容要少,看起来在理解简单命令上进展还是比较顺利。暂时先不理解其它的命令,开始通讯代码方 ...


接下来就是通讯方面的解读,从笔记03开始
http://www.amobbs.com/thread-5558291-1-1.html

出0入0汤圆

11
发表于 2013-11-10 19:16:12 | 只看该作者
快快MARK

出0入0汤圆

12
发表于 2014-3-5 13:51:54 | 只看该作者
楼主学习的非常仔细,紧跟

出0入0汤圆

13
发表于 2015-6-23 10:16:22 | 只看该作者
支持楼主,继续学习中

出0入0汤圆

14
发表于 2015-8-20 18:10:03 来自手机 | 只看该作者
学习学习,很好的入门资料,

出0入0汤圆

15
发表于 2015-9-21 13:49:15 | 只看该作者
支持楼主!

出0入0汤圆

16
发表于 2017-3-29 21:26:30 | 只看该作者
楼主 , 我支持你  我在一点一点的学习  ,为你这帖子 我买了 阿莫的帐号~~~~  楼主 加油

出0入0汤圆

17
发表于 2017-9-14 15:48:05 | 只看该作者
这几天都在看楼主的帖子,学到了很多PLC的知识,收获良多。。。理解PLC的实现原理很有帮助,这种思想可以学习。。

出0入0汤圆

18
发表于 2017-11-17 17:24:18 | 只看该作者
受教了,谢谢楼主的分享!!

出0入0汤圆

19
发表于 2019-8-26 17:23:51 | 只看该作者
花时间好好看。

出0入0汤圆

20
发表于 2020-5-26 10:12:11 | 只看该作者
学习了,支持支持
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-23 17:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表