微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 浅谈用单片机模拟PLC(山寨三菱系列)

浅谈用单片机模拟PLC(山寨三菱系列)

时间:12-01 来源:互联网 点击:
读书的时候因为学的自动化所以一直以为PLC是控制的王道,经常鄙视楼下电子系搞单片机的,而且灰常2B的认为单片机都TM弱电太娇气不耐艹玩单片机的都是吊丝!所以经常混迹于PLC实验室电子实验室居然只去了几次,然而随着对单片机和PC机的了解逐渐加深,越来越觉得自己当年的自己太傻太天真了哎……

个人觉得PLC和单片机的关系就好比图章和圆珠笔一样,图章操作简单傻子能盖出漂亮的图案但缺点也显而易见灵活性太差了你不能用图章盖出一些复杂的图案,圆珠笔就正好相反虽然操作难度大点但灵活性强了n个数量级。

既然单片机的灵活性那么强那么我们能用单片机来模拟PLC吗,很明显是可以的而且PLC的核心其实也是单片机,那么该怎么模拟PLC呢?PLC分程序和硬件部分,硬件部分主要是做好外围电路设计,实现PLC的IO输入输出功能,一般用光耦做IO口电路设计提高单片机的抗干扰能力,做好稳定的电源设计,电源是可靠性的基础。其实模拟PLC的关键再于程序部分,思路是写个编译器把梯形图编译成 单片机能执行的机器码,但写编译器工程太大了,我们只是模拟又不是造PLC所以不用考虑写那种直接把梯形图编译成机器码的编译器了,我们可以把编译过程分解为梯形图—>指令表—>C51代码—>机器码,这样的话问题就简单多了梯形图转指令表可以手工完成或者写个图形编辑程序来完成但这不是重点,指令表转C51代码才是模拟PLC的灵魂所在,虽然是个伪编译器但每条指令的翻译都是蛋疼的过程,我肯定是没办法把所有的三菱指令都模拟出来的,要完成这个任务还得认真学学编译原理啊……



这是PLC模拟程序的运行截图,对应指令表的逻辑,发现运行结果是正确的,虽然只完成了几条最简单指令的翻译而且与反指令还存在问题但毕竟思路是正确的完成只是时间问题了,太晚了不搞了果然比泥玛搬砖还辛苦想问题的时候根本睡不了……艾玛

下面是我的模拟程序,因为只实现了几条指令而且还并不完善所以编译程序和PLC指令表程序混在一起的,但这只是个思路因为我发现有些指令按我的办法基本不能实现但也算是个开始后面再慢慢改进吧,如果你想做一个更牛的可以去参考http://www.51hei.com/mcu/1985.html 下面是模拟编译的程序:

#include

//指令表模拟
#define AND &&
#define ANI && !
#define LD if(
#define LDI if( !
#define OUT )

//输入输出指令模拟
#define X000 P1_0
#define Y000 P2_0=1; else P2_0=0;
#define X001 P1_1
#define Y001 P2_1=1; else P2_1=0;
#define X002 P1_2
#define Y002 P2_2=1; else P2_2=0;
#define X003 P1_3
#define Y003 P2_3=1; else P2_3=0;
#define X004 P1_4
#define Y004 P2_4=1; else P2_4=0;
#define X005 P1_5
#define Y005 P2_5=1; else P2_5=0;
#define X006 P1_6
#define Y006 P2_6=1; else P2_6=0;
#define X007 P1_7
#define Y007 P2_7=1; else P2_7=0;

//输入输出口资源定义
int P1_0,P2_0,P1_1,P2_1,P1_2,P2_2,P1_3,P2_3,P1_4,P2_4,P1_5,P2_5,P1_6,P2_6,P1_7,P2_7;

//初始化函数
void chushihua()
{
P1_0=0;
P2_0=0;
P1_1=0;
P2_1=0;
P1_2=0;
P2_2=0;
P1_3=0;
P2_3=0;
P1_4=0;
P2_4=0;
P1_5=0;
P2_5=0;
P1_6=0;
P2_6=0;
P1_7=0;
P2_7=0;

}

//显示输入输出状态
void shurushuchu()
{
printf("输入输出口状态表");
printf("X0->%d X1->%d X2->%d X3->%d X4->%d X5->%d X6->%d X7->%d",P1_0,P1_1,P1_2,P1_3,P1_4,P1_5,P1_6,P1_7);

printf("Y0->%d Y1->%d Y2->%d Y3->%d Y4->%d Y5->%d Y6->%d Y7->%d",P2_0,P2_1,P2_2,P2_3,P2_4,P2_5,P2_6,P2_7);
}

//采集输入状态
void shuru()
{
printf("请更新输入点状态");
printf("X0<-");
scanf("%d",&P1_0);
printf("X1<-");
scanf("%d",&P1_1);
printf("X2<-");
scanf("%d",&P1_2);
printf("X3<-");
scanf("%d",&P1_3);
printf("X4<-");
scanf("%d",&P1_4);
printf("X5<-");
scanf("%d",&P1_5);
printf("X6<-");
scanf("%d",&P1_6);
printf("X7<-");
scanf("%d",&P1_7);
}

int main()
{
int x=0;
chushihua();
while(1)
{
shuru();
//进入PLC指令表程序部分编译器主体完工的话就能把这部分直接拿出来通过编译器编译了
LD X000
AND X002
ANI X001
OUT Y000
LD X003
AND X004
ANI X006
AND X007
OUT Y001

shurushuchu();
}
return 0;
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top