基于通用型MCU 的开源PLC 上下位机指令一致性研究

2021-04-28 03:12王庭有张才勇
化工自动化及仪表 2021年2期
关键词:堆栈编程语言指令

罗 骁 王庭有 张才勇

(昆明理工大学机电工程学院)

昆明理工大学机电工程学院张才勇设计搭建的小微型嵌入式PLC 以STM32MCU 为CPU的核心硬件,采用层叠式设计,由3 块PCB 板叠加构成。 顶层PCB 板为整个PLC 的核心板块,集成MCU 芯片、EEPROM 芯片、485 通信接口和输入输出提示灯。 二层PCB 板为PLC 与控制对象的输入输出交流层,包含光耦输入、继电器输入等外设元件。 底层PCB 板是PLC 的电源层,集成了交流转直流的多个降压模块,可为PLC 和外接模块供电。该小微型嵌入式PLC 的特点在于有极强的通用性和定制性,用户可以根据自身需求的不同, 对PLC 的核心板进行裁剪或添加外设,即可在不同控制情景下实现用途。

目前, 小微型PLC 具有较高的市场占有率,并以其较高的性价比逐渐替代传统小型PLC 设备,相比于现有的整块式PLC,开发层叠结构的PLC 扩展性更好、更灵活。 因此笔者对层叠结构的小微型嵌入式PLC 上下位机指令一致性进行研究,并设计实验验证指令的实现情况。

1 PLC 指令实现

1.1 编程语言的选择

根据国际电工委员会制定的工业控制编程语言标准IEC 1131-3,PLC 的编程语言包括以下5 种:梯形图语言(LD)、指令表语言(IL)、功能模块图语言(FBD)、顺序功能流程图语言(SFC)和结构化文本语言(ST)[1]。其中,指令表语言是与汇编语言类似的一种助记符编程语言,和汇编语言一样由操作码和操作数组成。 在无计算机的情况下,适合采用PLC 手持编程器对用户程序进行编制。 同时,指令表语言与梯形图语言一一对应,在PLC 编程软件下可以相互转换[2]。

由于其他编程语言编写的控制程序最终都需要转换为指令序列来执行,并且利用指令表语言编写的程序通常可以以最高速度运行[3~5],因此笔者选择指令表语言作为PLC 编程软件使用的编程语言。

1.2 指令实现

1.2.1 基本逻辑运算

PLC 中最基本的运算方式是逻辑运算,基本逻辑运算包含“与”、“或”、“非”3 种运算,其余的逻辑运算均以此为基础实现,因此首先要实现基本逻辑运算(图1)。

1.2.2 逻辑堆栈

逻辑堆栈是PLC 在进行逻辑运算时用于存储运算结果和中间值的区域, 是PLC 运行的基础,一般采用整段连续的区域作为逻辑堆栈[6]。栈深关系到PLC 的运算能力,将PLC 的逻辑堆栈栈深和指针定义如下:

图1 基本逻辑运算定义

上述代码定义了逻辑堆栈的栈深为40,顶层作为运算结果的存储区, 余下39 层用于存储运算的中间值。 使用栈顶指针logical_array_pointer操作堆栈,当有数据入栈时,丢弃底层数据,将堆栈内容依次下移,腾空栈顶单元压入数据;当有数据出栈时,弹出顶层数据,将堆栈内容依次上移,栈底单元补0。

定义逻辑堆栈后,需要PLC 来实现对堆栈的操作,因此要定义操作堆栈的指令,如图2 所示。

图2 部分堆栈操作指令定义

2 编程软件与PLC 指令一致性

为了保证PLC 严格按照所编指令进行工作,需要将PLC 能够识别的数字编码与编程软件所用的操作码和操作数一一对应起来,表1 给出了部分操作码和操作数对应的编码。 将表1 所示的操作码(操作数)对应的编码写入文件ins.m 中,并加入MATLAB,以保证编写出的PLC 指令能够正确编译。

表1 部分操作码和操作数对应的编码

PLC 要执行指令, 首先需要识别指令函数,具体实现方法为:每当执行完任一指令后,指向用户程序存储区的指针会根据本条指令的占用内存自动向下偏移m(m=1,3,6)个字节,以达到正确取址和执行下一条指令的目的。 例如执行只有操作码的LPS 指令,执行指令后指针向下偏移1 个字节, 继续执行下一条指令。 若执行OUT Q0 指令, 操作码OUT 占1 个字节,Q0 占2 个字节,则执行该指令后指针向下偏移3 个字节。 然后编写ins_exc.c 文件,在其中定义用户程序执行函数user_pro_exc (), 该函数的执行流程如图3所示。

图3 user_pro_exc()函数执行流程

如图3 所示,执行user_pro_exc()函数时,首先判断用户程序存储区内是否有用户程序,如果用户程序指针user_pro_storage_p 指向的地址内容为0,则说明没有用户程序,结束函数执行;反之,如果不为0,则执行construction()函数,该函数的执行流程如图4 所示。

图4 construction()函数执行流程

如图4 所示,开始执行construction()函数后,首先执行选择函数select()对用户程序中的指令进行选择,对于没有操作数的指令,如LPS 指令等直接执行后即结束该函数。 对于既有操作码又有操作数的指令, 如LD I0 指令等进一步匹配到sub_select()函数后再执行操作,sub_select()函数能为这些指令提供I、Q、M、C、T 等操作数。

完成PLC 对函数指令的识别工作后,即可达到使PLC 正确执行上位机用户程序指令的目的。

使用MATLAB GUI 工具设计简单的编程界面(图5),实现PLC 程序的编程、编译和下载功能。 该编程软件界面左侧为STL 指令编写区域,在此区域内编写所需的用户程序;右侧是编译提示区域, 当指令编写完成后点击编译按钮,编译提示区域会显示编译后的十六进制数。

图5 PLC 编程软件界面

3 PLC 指令验证实验

设计实验对PLC 的逻辑指令进行验证,实验指令包括:触点指令LD、A、O、LDN、AN、ON;逻辑堆栈指令ALD、OLD、LPS、LRD、LPP; 输出指令OUT。

在PC 端的PLC 编程软件中输入指令表指令,编译如图6 所示。

图6 PLC 指令

在4 个输出端口上各连接一个LED,当输出端口得电时二极管发光,输出端口不得电时二极管熄灭。

该实验中设计多种接通方案, 具体如下:仅I0 或I3 得电时,Q3 得电,其余回路不接通。 I0 和I2 得电时,仅Q3 得电,其余回路不接通;若同时再接通I4、I5 或I6,则在Q3 保持灯亮的情况下,分别有Q0、Q1 或Q2 灯亮,说明串联电路接通。I0和I3 得电时的情况与I0 和I2 得电情况一致。

通过实验,观察到如下现象:

a. 启动PLC,按下I0,Q3 得电,对应的LED点亮,其余LED 保持熄灭;断开I0,按下I3,Q3得电,对应的LED 点亮,其余LED 保持熄灭。

b. 接通I0 和I2 的同时,再按下I4,Q3 和Q0得电,对应的LED 点亮;断开I4,接通I5,Q3 和Q1 得电,对应的LED 点亮,其余LED 保持熄灭;断开I5,接通I6,Q3 和Q2 得电,对应的LED 点亮,其余LED 保持熄灭。

c. 接通I0 和I3 的同时,再按下I4,Q3 和Q0得电,对应的LED 点亮;断开I4,接通I5,Q3 和Q1 得电,对应的LED 点亮,其余LED 保持熄灭;断开I5,接通I6,Q3 和Q2 得电,对应的LED 点亮,其余LED 保持熄灭。

综上所述,实验结果与设计方案一致,说明使用笔者设计的指令表语言编程器编写的用户指令在下位机PLC 中得到了正确执行。

4 结束语

笔者使用MATLAB 编写出的PLC 指令表语言编程软件能够正确进行指令的编译,并且能够在STM32MCU 的下位机PLC 上正确执行, 说明上位机和下位机的指令具有一致性,是一个能实际应用的编程软件。

猜你喜欢
堆栈编程语言指令
基于行为监测的嵌入式操作系统堆栈溢出测试*
基于JavaScript编程语言之 闭包技术在焦点轮播上的应用
基于 Verilog HDL 的多周期 CPU 设计与实现
《单一形状固定循环指令G90车外圆仿真》教案设计
计算机软件开发的JAVA编程语言及其实际应用分析
浅谈不同编程语言对计算机软件开发的影响
基于堆栈自编码降维的武器装备体系效能预测
一种航天器软件进程堆栈使用深度的动态检测方法
高职计算机编程语言课程教学方法的相关分析
中断与跳转操作对指令串的影响