oldbeginner 发表于 2013-11-7 19:09:48

开源PLC学习笔记01(再从51开始)——2013_11_7

*******************************
背景介绍:
      8月份从零开始学习PLC和单片机(之前看了2个月模拟电子和数字电子,现在感觉顺序反了,应该先入门单片机,反过来再理解电路更容易),说句实话,现在网上资料非常丰富,只要选对了入门资料(视频、开发板或软件等),入门还是比较容易。

   PLC是利用三菱仿真软件入门的,再加上天天PLC的视频巩固一下,网上买了96元包邮的STM32仿三菱工控板,399买了触摸屏,做了几个简单试验,对如何利用STM32作PLC非常感兴趣。

   感觉STM32 PLC不再是高利润产品,毕竟淘宝上一搜就是上百家在卖,所以更容易把重心放在学习上。

    这里的热热闹闹的开源已经过去4年多了,当然我觉得这里的开源对现在仿三菱PLC的繁荣有着重要贡献。网上相关的PLC代码有好多种,下载看了,代码太长,真得很难入门。

   借鉴自己单片机入门经历,打算遍简化代码遍理解,并以笔记的形式表现出来。另外,我现在没有作出一个PLC板子,也没能让下载的代码通讯成功,也没有理解到代码的十分之一,这是起点。
***********************************

oldbeginner 发表于 2013-11-7 19:26:13

   对我这样的初学者,首先是下载能实现仿PLC完整代码,因为开源的PLC的MCU不再是热门的,所以这方面未能如愿。

   我刚开始一上来就看STM32的代码(论坛里的,http://www.amobbs.com/thread-5554905-1-1.html),果然又长又难理解,下载到片子里也不能通讯。

   又看4年前简易PLC的代码(http://www.amobbs.com/thread-3608835-1-2.html),没有MCU没法试,这没什么问题,尽管有详细的注释,这个代码一样复杂。

   看了简易PLC仿真帖子(http://www.amobbs.com/thread-3592500-1-3.html),感觉入门应该从这里开始。

   PLC的通讯协议应该是最难的,这个入门放在后面,先入门PLC指令在单片机内的实现,上面简易PLC仿真这方面做得非常不错。
   我在这个基础上只保留了能让仿真运行的代码,这样代码就很短,理解PLC指令的实现就变得门槛低了。尽管这样,剩下的代码对我还是有挑战性,不过难度较完整的代码下降了一个数量级。

    在后面的学习笔记01,我将尽量理解剩余的代码,看是否能换成适合我的形式。
*******************************************************************

oldbeginner 发表于 2013-11-7 19:34:09

oldbeginner 发表于 2013-11-7 19:26 static/image/common/back.gif
对我这样的初学者,首先是下载能实现仿PLC完整代码,因为开源的PLC的MCU不再是热门的,所以这方面未能如 ...



   简易PLC仿真不包含通讯功能,其实命令只包含LD,OUT,SET和RST。16个输入端口,8个输出端口。

   函数非常少,只有:
   1、主函数;
   2、端口初始化;
   3、LD和OUT的函数;
   4、PLC运行函数。

   这一部分的难点和重点集中在数据定义上。

oldbeginner 发表于 2013-11-7 19:39:00

oldbeginner 发表于 2013-11-7 19:34 static/image/common/back.gif
简易PLC仿真不包含通讯功能,其实命令只包含LD,OUT,SET和RST。16个输入端口,8个输出端口。

    ...

好像图片太大了,重新上传一个小一点的。

oldbeginner 发表于 2013-11-7 19:53:02

oldbeginner 发表于 2013-11-7 19:39 static/image/common/back.gif
好像图片太大了,重新上传一个小一点的。



主函数,非常喜欢简单的主函数。超过10行代码的函数都不喜欢,不包括符号和if、while类似语句。
void main(void)
{
        while (1)
    {
                //初始化IO端口,必须
                RefreshIO();   
               
                //PLC执行去找二当家的,当老大就是好
                main_PLC();
        }
}

oldbeginner 发表于 2013-11-7 20:04:56

oldbeginner 发表于 2013-11-7 19:53 static/image/common/back.gif
主函数,非常喜欢简单的主函数。超过10行代码的函数都不喜欢,不包括符号和if、while类似语句。
void m ...



PLC执行函数,在这里是手工把PLC命令输入,毕竟刚开始不能通讯。

用到了5个命令,后3个命令是通过宏定义的:
1、LD
2、OUT
3、SET
4、RST
5、END

minzhuzhongguo 发表于 2013-11-7 20:32:27

同楼主一起学习,这是很重要的基础,单片机控制方面的编程尽量按照PLC梯形图的思路。

renpeng009 发表于 2013-11-7 20:32:50

很不错啊

lcmdw 发表于 2013-11-7 20:38:51

支持楼主

oldbeginner 发表于 2013-11-7 20:41:28

本帖最后由 oldbeginner 于 2013-11-7 20:54 编辑

oldbeginner 发表于 2013-11-7 20:04 static/image/common/back.gif
PLC执行函数,在这里是手工把PLC命令输入,毕竟刚开始不能通讯。

用到了5个命令,后3个命令是通过宏定 ...



现在开始第一对函数的学习,LD和OUT,这是PLC中常用的指令,实话实说,三菱PLC仿真软件通关后,我还是不会LD,因为我一直用梯形图学习编程的。知道表达什么意思基本就可以了。

void _LD(unsigned char a)
{
ACC_BIT <<= 1;
ACC_BIT |= a;
}

先将上面表达式变为,缩写对初学者是一种负担(现在同时在学C语言)。
void _LD(unsigned char a)
{
ACC_BIT = ACC_BIT<<1;
ACC_BIT = ACC_BIT | a;
}

这里需要了解ACC_BIT是什么定义。

liuruoshui 发表于 2013-11-7 21:07:20

挺不错!希望楼主坚持完成做好!

jetli 发表于 2013-11-7 21:10:15

{:lol:}协议倒是 有。

oldbeginner 发表于 2013-11-7 21:16:52

oldbeginner 发表于 2013-11-7 20:41 static/image/common/back.gif
现在开始第一对函数的学习,LD和OUT,这是PLC中常用的指令,实话实说,三菱PLC仿真软件通关后,我还是 ...



找到ACC_BIT定义,是无符号字母类型,
//位运算器及 7级中间过渡栈
unsigned char   dataACC_BIT;      

我需要查找资料 data表示什么,在入门的时候见过code。现在到时候来理解一下了,同样网上找资料(我一般找好几个,对比一下)。
************************************
http://blog.sina.com.cn/s/blog_81bc3add0101347t.html。

data: 固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最小
data --->   可寻址片内ram

bdata --->   可位寻址的片内ram
idata --->  可寻址片内ram,允许访问全部内部ram
pdata ---> 分页寻址片外ram
xdata ---> 可寻址片外ram
code ---> 程序存储区 (64k 地址范围)
***************************************
引出了acc,网上搜一下资料http://zhidao.baidu.com/question/440331825.html,累加器,累加器ACC是一个8位的存储单元,是用来放数据的。不知道怎样利用ACC做运算,暂时搁置,边研究边学。

花了一些精力,基本得出这样一个分析结果,ACC_BIT是一个会用到累加器的无符号字符型变量。


Cortex_M3 发表于 2013-11-7 21:22:23

很不错 也前来学习学习

oldbeginner 发表于 2013-11-7 21:48:38

oldbeginner 发表于 2013-11-7 21:16 static/image/common/back.gif
找到ACC_BIT定义,是无符号字母类型,
//位运算器及 7级中间过渡栈
unsigned char   dataACC_BIT;...

我是看了OUT函数后,理解了LD函数的。还得放张图片来说明。


以上图为例,X0只有0或1两种情况,将两者的函数合在一起:

1、 ACC_BIT= ACC_BIT << 1;
   
2、 ACC_BIT=ACC_BIT | a;

3、return(ACC_BIT & 0x01);
*************************
利用二进制,如果第一次使用,ACC_BIT=0000 0000;,
1、ACC_BIT左移一位后,还是0000 0000;
2、后面的a就是图中的X0,只有0或1两种情况
      A:a=0,ACC_BIT=0000 0000
      B:a=1,ACC_BIT=0000 0001

3、ACC_BIT & 0x01,
      A:a=0,ACC_BIT=0000 0000
                              &0000 0001
          返回值为0;
      B:a=1,ACC_BIT=0000 0001
                              &0000 0001
          返回值为1。

如果不是第一次使用,则可以假设ACC_BIT=xxxx xxxx; (x可以是0,也可以是1,不确定)
       其实只要左移1位,填充的是0,返回值就是a的值。

JACK847070222 发表于 2013-11-7 21:49:54

收藏,希望坚持下去

jack_yu 发表于 2013-11-7 21:53:43

谢谢楼主写的细致。

oldbeginner 发表于 2013-11-7 22:24:15

本帖最后由 oldbeginner 于 2013-11-7 22:52 编辑

oldbeginner 发表于 2013-11-7 21:48 static/image/common/back.gif
我是看了OUT函数后,理解了LD函数的。还得放张图片来说明。






学习了LD和OUT之后再学习SET和RST就轻松了,因为方法一致。

#define_SET(a)      if ((ACC_BIT & 0x01) != 0){ a = 1; }

变为
            if ((ACC_BIT & 0x01) != 0)
                   {
                      a = 1;
                   }

要理解SET,还需要和LD联合在一起

将LD和SET函数合在一起分析,要做参数修改,因为都采用虚参数a,容易混淆,所以将LD中的参数改为x,SET中的参数改为y:

1、 ACC_BIT= ACC_BIT << 1;
   
2、 ACC_BIT=ACC_BIT | x;
         
3、if ((ACC_BIT & 0x01) != 0)
          {
                  y = 1;
         }
*********************************
剩下的工作就是复制粘贴,然后修改
*************************
利用二进制,如果第一次使用,ACC_BIT=0000 0000;,
1、ACC_BIT左移一位后,还是0000 0000;
2、LD函数中的参数x就是图中的X0,值为0或1
      A:x=0,ACC_BIT=0000 0000
      B:x=1,ACC_BIT=0000 0001

3、ACC_BIT & 0x01,
      A:x=0,ACC_BIT=0000 0000
                              &0000 0001
          此时SET函数的y没被赋值,保持原来状态;
      B:x=1,ACC_BIT=0000 0001
                              &0000 0001
          此时SET函数的y=1;。

如果不是第一次使用,则可以假设ACC_BIT=xxxx xxxx; (x可以是0,也可以是1,不确定)
       其实只要左移1位,填充的是0,ACC_BIT=xxxx xxxx0,结论不变。

huqinglun 发表于 2013-11-7 23:17:46

标记下
·

feverkim 发表于 2013-11-7 23:46:28

MARK,,占位

PCH 发表于 2013-11-8 07:17:57

太好了,向您学习

abc336666 发表于 2013-11-8 08:12:43

好,支持

oldbeginner 发表于 2013-11-8 11:11:25

oldbeginner 发表于 2013-11-7 22:24 static/image/common/back.gif
学习了LD和OUT之后再学习SET和RST就轻松了,因为方法一致。

#define_SET(a)      if ((ACC_BIT &...

学好SET后,RST实际上也可以理解了,#define_RST(a)      if ((ACC_BIT & 0x01) != 0){ a = 0; },只是赋值不同,SET是置位,RST是复位。

**************
现在可以进入到端口定义和端口初始化函数。
先看端口定义:



对初学者来说,还是比较复杂的,还需要再看PLC_Memory.c中的定义:
//位元件 X 存储位
TYPE_BIT_BYTE   datarX;

//位元件 Y 存储位                                
TYPE_BIT_BYTE   datarY;   

要理解上面的定义,还需要看PLC_Configure.h中的定义(真绕,多费精力):
// 16个输入端口,    编号:X0-X7 X10-X17
#define   _X_num      16
          
// 8个输出端口,    编号:Y0-Y7
#define   _Y_num      8           

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

// 8个输出端口,所占内存字节数
#define   _Y_BYTE   (_Y_num + 7) / 8   

oldbeginner 发表于 2013-11-8 11:32:34

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

为了使每个帖子里要表达的主体更加清晰和一致,端口定义的理解将放在笔记02中。本帖子可能还会根据对PLC指令理解的加深,而更新。
开源PLC学习笔记02(再从51开始)——2013_11_8

笔记01的内容是精简PLC仿真的引出,理解几个常用PLC指令的51实现,从而对入门有个初步认识。

edawn 发表于 2013-11-8 14:44:15

学习PLC,谢谢楼主。

dongfangjian 发表于 2013-11-8 18:29:43

唉,花这么多时间学习一种过时的技术!

oldbeginner 发表于 2013-11-8 19:49:54

dongfangjian 发表于 2013-11-8 18:29 static/image/common/back.gif
唉,花这么多时间学习一种过时的技术!

呵呵,你没仔细看背景介绍,我现在是感兴趣想学习,如果想开发一种跟上的技术肯定不会花时间再学PLC。

dongfangjian 发表于 2013-11-8 20:11:43

我说的是51这种架构的芯片,而不是PLC,而且这个软件离真正的PLC还差得很远。

oldbeginner 发表于 2013-11-8 20:35:47

dongfangjian 发表于 2013-11-8 20:11 static/image/common/back.gif
我说的是51这种架构的芯片,而不是PLC,而且这个软件离真正的PLC还差得很远。 ...

明白你的意思了,不过51是资料比较丰富的,我一开始就看STM32的代码,理解都没法入门。

LJM4U 发表于 2013-11-10 19:15:29

必须MARK

canxauto 发表于 2013-11-19 18:03:19

支持楼主

zlq2000 发表于 2013-11-19 19:13:42

不错,支持楼主!先从简单的一步一个脚印打好基础。

fayuanye 发表于 2013-11-19 22:39:01

支持楼主!

lmt50211 发表于 2013-11-21 13:38:58

楼主好样的。。。。

zqd311107 发表于 2013-12-2 11:28:57

佩服楼主啊!一起学习!正好也在研究!

xuxe2005 发表于 2013-12-2 21:33:17

学习中,{:smile:}{:victory:}

JACK847070222 发表于 2014-1-1 21:37:25

跟你学习,顶

minicatcatcn 发表于 2014-1-1 22:47:32

学习,学习

hyf88 发表于 2014-3-3 10:16:43

先 mark,,,移植想学PLC,,觉得自动控制挺有意思的,,,

YSYJ 发表于 2014-3-5 13:11:39

正在学习自动控制,紧跟楼主的脚步。不管是哪一种MCU总是要从零开始的

ZHW0117 发表于 2014-4-7 16:57:49

一步一步跟着老大学!

Nailkwo 发表于 2014-7-18 10:17:58

跟着楼主学习~~

瓶子 发表于 2014-11-24 23:03:28

跟随楼主的脚步,这第一篇笔记我也学的差不多了,感谢楼主的无私分享,不然真找不到从何处下手

tjx0512 发表于 2015-3-10 14:39:11

从头开始一步步跟着学习!

蓝蓝的恋 发表于 2015-5-14 11:07:20

好贴,收藏了慢慢消化~

yx20016 发表于 2015-6-23 10:13:52

跟着楼主学习

zgl_mcu 发表于 2015-6-23 19:00:42

oldbeginner 发表于 2013-11-8 11:11
学好SET后,RST实际上也可以理解了,#define_RST(a)      if ((ACC_BIT & 0x01) != 0){ a = 0; }, ...

#define_SET(a)      if ((ACC_BIT & 0x01) != 0){ a = 1; }

#define_RST(a)      if ((ACC_BIT & 0x01) != 0){ a = 0; }
怎么感觉第二条不对!这样可以实现复位么。。。

ddcour 发表于 2016-1-4 20:48:59

{:handshake:}{:handshake:}{:handshake:}{:handshake:}

hspydf 发表于 2016-7-28 09:30:51

你好,源代码哪里下载的,可否给你链接?

ggggidtf520 发表于 2017-3-29 20:55:14

支持,,,

sanjianke 发表于 2020-1-8 18:36:15

看了一下时间,隔了这么久。PLC的思路值得学习的。收获满满

tdchenke 发表于 2020-1-9 16:45:40

了解学习下谢谢分享

lj0755 发表于 2020-3-26 12:24:21

千里之行始于足下,支持楼主!不知道楼主现在进行的咋样啦

Wolves_control 发表于 2020-4-3 17:36:34

跟着楼主学着理解PLC通讯部分与软元件与单片机内部地址,很棒的帖子,好好吸收学习

fengyunyu 发表于 2020-4-4 14:14:49

lz发布的笔记不错!
页: [1]
查看完整版本: 开源PLC学习笔记01(再从51开始)——2013_11_7