开源PLC学习笔记01(再从51开始)——2013_11_7
*******************************背景介绍:
8月份从零开始学习PLC和单片机(之前看了2个月模拟电子和数字电子,现在感觉顺序反了,应该先入门单片机,反过来再理解电路更容易),说句实话,现在网上资料非常丰富,只要选对了入门资料(视频、开发板或软件等),入门还是比较容易。
PLC是利用三菱仿真软件入门的,再加上天天PLC的视频巩固一下,网上买了96元包邮的STM32仿三菱工控板,399买了触摸屏,做了几个简单试验,对如何利用STM32作PLC非常感兴趣。
感觉STM32 PLC不再是高利润产品,毕竟淘宝上一搜就是上百家在卖,所以更容易把重心放在学习上。
这里的热热闹闹的开源已经过去4年多了,当然我觉得这里的开源对现在仿三菱PLC的繁荣有着重要贡献。网上相关的PLC代码有好多种,下载看了,代码太长,真得很难入门。
借鉴自己单片机入门经历,打算遍简化代码遍理解,并以笔记的形式表现出来。另外,我现在没有作出一个PLC板子,也没能让下载的代码通讯成功,也没有理解到代码的十分之一,这是起点。
*********************************** 对我这样的初学者,首先是下载能实现仿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: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:34 static/image/common/back.gif
简易PLC仿真不包含通讯功能,其实命令只包含LD,OUT,SET和RST。16个输入端口,8个输出端口。
...
好像图片太大了,重新上传一个小一点的。
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 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 同楼主一起学习,这是很重要的基础,单片机控制方面的编程尽量按照PLC梯形图的思路。 很不错啊 支持楼主
本帖最后由 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是什么定义。 挺不错!希望楼主坚持完成做好! {:lol:}协议倒是 有。 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是一个会用到累加器的无符号字符型变量。
很不错 也前来学习学习 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的值。
收藏,希望坚持下去 谢谢楼主写的细致。 本帖最后由 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,结论不变。
标记下
· MARK,,占位 太好了,向您学习 好,支持 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:33 编辑
为了使每个帖子里要表达的主体更加清晰和一致,端口定义的理解将放在笔记02中。本帖子可能还会根据对PLC指令理解的加深,而更新。
开源PLC学习笔记02(再从51开始)——2013_11_8
笔记01的内容是精简PLC仿真的引出,理解几个常用PLC指令的51实现,从而对入门有个初步认识。 学习PLC,谢谢楼主。 唉,花这么多时间学习一种过时的技术! dongfangjian 发表于 2013-11-8 18:29 static/image/common/back.gif
唉,花这么多时间学习一种过时的技术!
呵呵,你没仔细看背景介绍,我现在是感兴趣想学习,如果想开发一种跟上的技术肯定不会花时间再学PLC。 我说的是51这种架构的芯片,而不是PLC,而且这个软件离真正的PLC还差得很远。 dongfangjian 发表于 2013-11-8 20:11 static/image/common/back.gif
我说的是51这种架构的芯片,而不是PLC,而且这个软件离真正的PLC还差得很远。 ...
明白你的意思了,不过51是资料比较丰富的,我一开始就看STM32的代码,理解都没法入门。 必须MARK 支持楼主 不错,支持楼主!先从简单的一步一个脚印打好基础。 支持楼主! 楼主好样的。。。。 佩服楼主啊!一起学习!正好也在研究! 学习中,{:smile:}{:victory:} 跟你学习,顶 学习,学习 先 mark,,,移植想学PLC,,觉得自动控制挺有意思的,,, 正在学习自动控制,紧跟楼主的脚步。不管是哪一种MCU总是要从零开始的 一步一步跟着老大学! 跟着楼主学习~~ 跟随楼主的脚步,这第一篇笔记我也学的差不多了,感谢楼主的无私分享,不然真找不到从何处下手 从头开始一步步跟着学习! 好贴,收藏了慢慢消化~ 跟着楼主学习 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; }
怎么感觉第二条不对!这样可以实现复位么。。。
{:handshake:}{:handshake:}{:handshake:}{:handshake:} 你好,源代码哪里下载的,可否给你链接? 支持,,, 看了一下时间,隔了这么久。PLC的思路值得学习的。收获满满 了解学习下谢谢分享 千里之行始于足下,支持楼主!不知道楼主现在进行的咋样啦 跟着楼主学着理解PLC通讯部分与软元件与单片机内部地址,很棒的帖子,好好吸收学习 lz发布的笔记不错!
页:
[1]