oldbeginner 发表于 2013-11-8 11:26:53

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

本帖最后由 oldbeginner 于 2013-11-8 12:33 编辑

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

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

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


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

oldbeginner 发表于 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 charBYTE;                                        //可以按字节寻址
}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   datarX[_X_BYTE];

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

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

liuruoshui 发表于 2013-11-8 12:23:01

默默的支持楼主!

oldbeginner 发表于 2013-11-8 12:29:37

oldbeginner 发表于 2013-11-8 12:17 static/image/common/back.gif
看来C语音也需要再回顾加深一下了,端口的定义需要理解下面的结构和联合体。

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



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

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

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

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

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

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

oldbeginner 发表于 2013-11-8 12:53:22

本帖最后由 oldbeginner 于 2013-11-8 12:59 编辑

oldbeginner 发表于 2013-11-8 12:29 static/image/common/back.gif
我刚开始看下面的的定义时云里雾里的,摸不着门,不过,现在可以解决了。
//------------------------- ...

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

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

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

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

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

//位元件 X,Y 存储位
extern TYPE_BIT_BYTE   datarX , rY;

搜一下,若本文件 引用别的文件中的全局变量一定要加上extern 声明一下,http://zhidao.baidu.com/link?url=j7gCL7jnOsbOvKwovJd-1CdbqURHKsYzUHXi8ooq2Jx-kz9LaIu3qgm7jNxC0cRzT2U0dUVHC5ChADZstKT8aq。

activeleo 发表于 2013-11-8 13:09:28

资格帖子要严重支持下........

oldbeginner 发表于 2013-11-8 13:10:20

oldbeginner 发表于 2013-11-8 12:53 static/image/common/back.gif
现在就可以理解端口刷新,我刚开始理解为初始化是不正确的。
//--------------------------------------- ...

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


仿真和最小代码



hyghyg1234 发表于 2013-11-8 13:52:30

很通俗易懂,顶

leey 发表于 2013-11-8 14:10:28

学习了,楼主继续,楼主加油!!

oldbeginner 发表于 2013-11-9 15:32:17

oldbeginner 发表于 2013-11-8 13:10 static/image/common/back.gif
比我想象地内容要少,看起来在理解简单命令上进展还是比较顺利。暂时先不理解其它的命令,开始通讯代码方 ...


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

LJM4U 发表于 2013-11-10 19:16:12

快快MARK

YSYJ 发表于 2014-3-5 13:51:54

楼主学习的非常仔细,紧跟

yx20016 发表于 2015-6-23 10:16:22

支持楼主,继续学习中

四平八稳 发表于 2015-8-20 18:10:03

学习学习,很好的入门资料,

qrsgcslqg2011 发表于 2015-9-21 13:49:15

支持楼主!

ggggidtf520 发表于 2017-3-29 21:26:30

楼主 , 我支持你我在一点一点的学习,为你这帖子 我买了 阿莫的帐号~~~~楼主 加油

sanjianke 发表于 2017-9-14 15:48:05

这几天都在看楼主的帖子,学到了很多PLC的知识,收获良多。。。理解PLC的实现原理很有帮助,这种思想可以学习。。

tangly2017 发表于 2017-11-17 17:24:18

受教了,谢谢楼主的分享!!

xuwuhan 发表于 2019-8-26 17:23:51

花时间好好看。

zbin06 发表于 2020-5-26 10:12:11

学习了,支持支持
页: [1]
查看完整版本: 开源PLC学习笔记02(再从51开始)——2013_11_8