完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
梯形图显示到编译--软PLC的实现
PLC(Programmable Logic Controller 可编程逻辑控制器)是在工业环境下使用的数字逻辑操作系统。其编程语言有我们最为熟悉的梯形图,本篇文章将从梯形图的原理、编译、运行,实现一个软PLC。 一、基本原理 梯形图可以理解为一个电路图,通过梯形图上的元件的通断来控制整个程序逻辑。元件的状态只有“通”和“断”;元件的关系可以分为“与”、“或”、“非”。是不是似曾相识?这里我们把含有逻辑关系的元件当做一个逻辑块;通过这些逻辑块最终输出到元件——输出块。 如下图: 图1 简单梯形图 从母线出发,连接逻辑块到输出块的通路称为输出图。如上图为一个输出图。 只有一个逻辑块和输出块的图称为最简图,如下图所示: 图2 最简图 有了上面的基本原理,接下来就可以抽象梯形图,从而实现梯形图的显示和编译。 二、算法原理 1、初始状态将每个元件当做一个逻辑块或者输出块。如图1中的M000、X000等为逻辑块,Y001、Y002为输出块 2、取出一个输出图。 3、合并相邻输出块、输出块 4、如果合并后为最简图则返回第2步取下一个输出图,不是则继续3步 伪代码如下: if( getNextOutputGraph() ) { if( !isTheSimpleGraph() ) { shiftGraph(); } } outputPLCInstructions(); 图1的梯形图处理结果如下,输出PLC指令: 三、运行 将上面编译出来的PLC指令,输入到PLCCore,使用解析运行将模拟PLC运行。图中灰色表示元件导通,双击元件可以改变元件状态,如果双击M001导通,则Y001和Y002导通一次。 下面是已经支持的指令表,PLCCore是在三菱PLC下参考制作,可以直接模拟三菱PLC的程序 static InsItem g_insItems[] = { {{dinsDEBUG}, sinsNOP-1, “DEBUG”, 1,0, ARG_COIL_G }, {{dinsLD}, sinsLD, “LD”, 1,0, ARG_COIL_BIT}, {{dinsLDI}, sinsLDI, “LDI”, 1,0, ARG_COIL_BIT}, {{dinsLDP}, sinsLDP, “LDP”, 1,0, ARG_COIL_BIT}, {{dinsLDF}, sinsLDF, “LDF”, 1,0, ARG_COIL_BIT}, {{dinsAND}, sinsAND, “AND”, 1,0, ARG_COIL_BIT}, {{dinsANI}, sinsANI, “ANI”, 1,0, ARG_COIL_BIT}, {{dinsANDP}, sinsANDP, “ANDP”, 1,0, ARG_COIL_BIT}, {{dinsANDF}, sinsANDF, “ANDF”, 1,0, ARG_COIL_BIT}, {{dinsOR}, sinsOR, “OR”, 1,0, ARG_COIL_BIT}, {{dinsORI}, sinsORI, “ORI”, 1,0, ARG_COIL_BIT}, {{dinsORP}, sinsORP, “ORP”, 1,0, ARG_COIL_BIT}, {{dinsORF}, sinsORF, “ORF”, 1,0, ARG_COIL_BIT}, {{dinsANB}, sinsANB, “ANB”, 0,0, 0}, {{dinsORB}, sinsORB, “ORB”, 0,0, 0}, {{dinsMPS}, sinsMPS, “MPS”, 0,0, 0}, {{dinsMRD}, sinsMRD, “MRD”, 0,0, 0}, {{dinsMPP}, sinsMPP, “MPP”, 0,0, 0}, {{dinsINV}, sinsINV, “INV”, 0,0, 0}, {{dinsMEP}, sinsMEP, “MEP”, 0,0, 0}, {{dinsMEF}, sinsMEF, “MEF”, 0,0, 0}, {{dinsOUT}, sinsOUT, “OUT”, 1,0, ARG_COIL_X | ARG_COIL_Y | ARG_COIL_M }, {{dinsOUTT}, sinsOUTT, “OUT”, 2,0, ARG_COIL_T,ARG_COIL_DATA}, {{dinsOUTC}, sinsOUTC, “OUT”, 2,0, ARG_COIL_C,ARG_COIL_DATA}, {{dinsOUT}, sinsOUTMS, “OUT”, 1,0, ARG_COIL_M }, {{dinsOUTS}, sinsOUTMS, “OUT”, 1,0, ARG_COIL_S }, {{dinsSET}, sinsSET, “SET”, 1,0, ARG_COIL_X | ARG_COIL_Y | ARG_COIL_M }, {{dinsSETS}, sinsSETMS, “SET”, 1,0, ARG_COIL_S }, {{dinsSET}, sinsSETMS, “SET”, 1,0, ARG_COIL_M }, {{dinsRST}, sinsRST, “RST”, 1,0, ARG_COIL_X | ARG_COIL_Y | ARG_COIL_M }, {{dinsRSTTC}, sinsRSTMSTC,“RST”, 1,0, ARG_COIL_T | ARG_COIL_C }, {{dinsRSTS}, sinsRSTMSTC,“RST”, 1,0, ARG_COIL_S }, {{dinsRST}, sinsRSTMSTC,“RST”, 1,0, ARG_COIL_M }, {{dinsPLS}, sinsPLS, “PLS”, 1,0, ARG_COIL_X | ARG_COIL_Y | ARG_COIL_M | ARG_COIL_S }, {{dinsPLF}, sinsPLF, “PLF”, 1,0, ARG_COIL_X | ARG_COIL_Y | ARG_COIL_M | ARG_COIL_S }, {{dinsSTL}, sinsSTL, “STL”, 1,0, ARG_COIL_S}, {{dinsRET}, sinsRET, “RET”, 0,0, 0}, {{dinsMC}, sinsMC, “MC”, 1,0, ARG_COIL_N }, {{dinsMCR}, sinsMCR, “MCR”, 1,0, ARG_COIL_N }, {{dinsNOP}, sinsNOP, “NOP”, 0,0, 0}, {{dinsEND}, sinsEND, “END”, 0,0, 0}, {{dinsADD}, sinsADD, “ADD”, 3,0, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V }, {{dinsSUB}, sinsSUB, “SUB”, 3,0, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V }, {{dinsMUL}, sinsMUL, “MUL”, 3,0, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V }, {{dinsDIV}, sinsDIV, “DIV”, 3,0, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V }, {{dinsINC}, sinsINC, “INC”, 1,0, ARG_COIL_D | ARG_COIL_V }, {{dinsDEC}, sinsDEC, “DEC”, 1,0, ARG_COIL_D | ARG_COIL_V }, {{dinsMOV}, sinsMOV, “MOV”, 2,0, ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V }, {{dinsCMP}, sinsCMP, “CMP”, 3,0, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_M}, {{dinsCJ}, sinsCJ, “CJ”, 1,0, ARG_COIL_P}, {{dinsCJP}, sinsCJP, “CJP”, 1,0, ARG_COIL_P}, {{dinsSRET}, sinsSRET, “SRET”, 0,0, 0}, {{dinsFEND}, sinsFEND, “FEND”, 0,0, 0}, {{dinsCALL}, sinsCALL, “CALL”, 1,0, ARG_COIL_P}, {{dinsP}, sinsP, “P”, 1,0, ARG_COIL_P}, {{dinsDADD}, sinsDADD, “DADD”, 3,1, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V}, {{dinsDSUB}, sinsDSUB, “DSUB”, 3,1, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V}, {{dinsDMUL}, sinsDMUL, “DMUL”, 3,1, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V}, {{dinsDDIV}, sinsDDIV, “DDIV”, 3,1, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V}, {{dinsDINC}, sinsDINC, “DINC”, 1,1, ARG_COIL_D | ARG_COIL_V}, {{dinsDDEC}, sinsDDEC, “DDEC”, 1,1, ARG_COIL_D | ARG_COIL_V}, {{dinsDMOV}, sinsDMOV, “DMOV”, 2,1, ARG_COIL_DATA,ARG_COIL_D | ARG_COIL_V}, {{dinsDCMP}, sinsDCMP, “DCMP”, 3,1, ARG_COIL_DATA,ARG_COIL_DATA,ARG_COIL_M}, {{dinsLD_E}, sinsLD_E, “LD=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsAND_E}, sinsAND_E, “AND=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsOR_E}, sinsOR_E, “OR=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLD_NE}, sinsLD_NE, “LD《》”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsAND_NE}, sinsAND_NE, “AND《》”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsOR_NE}, sinsOR_NE, “OR《》”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLD_B}, sinsLD_B, “LD》”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsAND_B}, sinsAND_B, “AND》”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsOR_B}, sinsOR_B, “OR》”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLD_EB}, sinsLD_EB, “LD》=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsAND_EB}, sinsAND_EB, “AND》=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsOR_EB}, sinsOR_EB, “OR》=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLD_S}, sinsLD_S, “LD《”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsAND_S}, sinsAND_S, “AND《”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsOR_S}, sinsOR_S, “OR《”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLD_ES}, sinsLD_ES, “LD《=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsAND_ES}, sinsAND_ES, “AND《=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsOR_ES}, sinsOR_ES, “OR《=”, 2,0, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLDD_E}, sinsLDD_E, “LDD=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsANDD_E}, sinsANDD_E, “ANDD=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsORD_E}, sinsORD_E, “ORD=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLDD_NE}, sinsLDD_NE, “LDD《》”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsANDD_NE}, sinsANDD_NE,“ANDD《》”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsORD_NE}, sinsORD_NE, “ORD《》”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLDD_B}, sinsLDD_B, “LDD》”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsANDD_B}, sinsANDD_B, “ANDD》”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsORD_B}, sinsORD_B, “ORD》”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLDD_EB}, sinsLDD_EB, “LDD》=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsANDD_EB}, sinsANDD_EB,“ANDD》=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsORD_EB}, sinsORD_EB, “ORD》=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLDD_S}, sinsLDD_S, “LDD《”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsANDD_S}, sinsANDD_S, “ANDD《”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsORD_S}, sinsORD_S, “ORD《”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsLDD_ES}, sinsLDD_ES, “LDD《=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsANDD_ES}, sinsANDD_ES,“ANDD《=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsORD_ES}, sinsORD_ES, “ORD《=”, 2,1, ARG_COIL_DATA,ARG_COIL_DATA}, {{dinsDDRVA}, sinsDDRVA, “DDRVA”, 4,1, ARG_COIL_DATA, ARG_COIL_DATA, ARG_COIL_Y, ARG_COIL_Y }, {{dinsDDRVI}, sinsDDRVI, “DDRVI”, 4,1, ARG_COIL_DATA, ARG_COIL_DATA, ARG_COIL_Y, ARG_COIL_Y }, {{dinsDRVA}, sinsDRVA, “DRVA”, 4,0, ARG_COIL_DATA, ARG_COIL_DATA, ARG_COIL_Y, ARG_COIL_Y }, {{dinsDRVI}, sinsDRVI, “DRVI”, 4,0, ARG_COIL_DATA, ARG_COIL_DATA, ARG_COIL_Y, ARG_COIL_Y }, }; 由于项目很久没有维护,PLCCore使用c语言编写,已经成功跑在Stm32上,windows模拟器也是同个PLCCore。但界面使用MFC,后面整理完会将项目开源。敬请期待。 |
|
|
|
只有小组成员才能发言,加入小组>>
918浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 10:27 , Processed in 0.689871 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号