博途使用多重背景数据块+SCL+UDT实现过程控制标准化

本文介绍了西门子博途软件中如何利用多重背景数据块实现类似C#的单例模式,以及如何通过用户定制数据类型(UDT)进行结构化编程。以电机控制为例,详细阐述了输入输出变量的设置、电机状态的判断及模拟量转换,并展示了如何在PLC数据类型中创建UDT变量和电机控制集合。尽管博途在多态方面仍有待提升,但其封装特性已经使得PLC编程更加接近面向对象的编程理念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博途的多重背景数据块, 类似于C# 中的单例模式. 通过一个静态变量即可访问到目标对象的所有方法.
UDT为用户定制数据类型, 可以使用结构体等方法, 使编程结构化和简单化.

以电机控制为例.
1, 先做一个电机控制的模版…

Input			
IStartBtn	Bool	false	非保持
IStopBtn	Bool	false	非保持
IResetBtn	Bool	false	非保持
IEmergencyBtn	Bool	false	非保持
IContact	Bool	false	非保持
IAi1	Int	0	非保持


Output			
QRunning	Bool	false	非保持
QMonitorStatus	Int	0	非保持
QAo1	Real	0.0	非保持


Static			
StRunFlag	Bool	false	非保持
StAlarmFlag	Bool	false	非保持
StMotorStatus	Int	0	非保持
IEC_Timer_0_Instance	TON_TIME		非保持
UpperiLimit	Real	0.0	非保持
LowLimit	Real	0.0	非保持
IEC_Timer_0_Instance_1	TON_TIME		非保持
			
Temp			
Temp1	Real		

在这里插入图片描述

REGION 电机启动信号
    #StRunFlag := (#IStartBtn OR #StRunFlag) AND NOT #IStopBtn AND NOT #IEmergencyBtn AND NOT #StAlarmFlag;
    //(启动按钮 或者 正在运行(自锁))  且 没有按下停止 且没有按下急停 且没有报警
END_REGION

REGION 电机故障
    #IEC_Timer_0_Instance_1(IN:=#StRunFlag AND #IStopBtn,
                            PT:=t#3s);
    
    IF #IEC_Timer_0_Instance_1.Q THEN
        #StAlarmFlag := 1;
    END_IF;
    #IEC_Timer_0_Instance(IN := (#StRunFlag AND NOT #IContact) OR (NOT #StRunFlag AND #IContact),
                          PT := t#3S); // 正在运行且接触器未吸合 或者 (没有正在运行且接触器吸合)
    
    IF #IEC_Timer_0_Instance.Q THEN
        #StAlarmFlag := 1;
    END_IF;
    
END_REGION

REGION 电机状态
    IF #StRunFlag AND NOT #StAlarmFlag AND #IContact THEN
        #StMotorStatus := 1; //发出了启动信号, 而且没有报警, 且接触器吸合
        
    ELSIF (#StRunFlag AND NOT #IContact) OR (NOT #StRunFlag AND #IContact) AND NOT #StAlarmFlag THEN
        #StMotorStatus := 2; // 1,发出了启动信号, 但接触器没有吸合 2,没有发出启动, 且接触器吸合,且报警
        
    ELSIF #StRunFlag AND NOT #IContact AND NOT #StAlarmFlag THEN
        #StMotorStatus := 4; //启动了, 且 接触器没有吸合 且没有报警
        
    ELSIF #StAlarmFlag THEN
        #StMotorStatus := 8; //出现报警 停止发出启动信号
        #StRunFlag := 0;
    ELSE
        #StMotorStatus := 0;
    END_IF;
END_REGION

REGION 复位
    IF #IResetBtn THEN
        #StMotorStatus := 1;
        #StAlarmFlag := 0;
    END_IF;
    
    
END_REGION

REGION io映射
    #QRunning := #StRunFlag;
    #QMonitorStatus := #StMotorStatus;
    
END_REGION

REGION 模拟量转化
    #Temp1 := NORM_X(MIN := 0, VALUE := #IAi1, MAX := 27648);
    #QAo1 := SCALE_X(MIN := #LowLimit, VALUE := #Temp1, MAX := #UpperiLimit);
   
END_REGION

在这里插入图片描述

2, 再建一个电机控制集合FB2, 拖动FB1的电机控制结构进入, 选择多重背景数据块

在这里插入图片描述

在这里插入图片描述

这时, 3个电机的数据会出现在FB2的静态变量中, 而不是新建DB块.

在这里插入图片描述

3, 在PLC数据类型中, 建立一个UDT变量MotorUDT1
MotorUDT1使用结构体定义输入和输出变量:

I	Struct	
IStartBtn	Bool	false
IStopBtn	Bool	false
IResetBtn	Bool	false
IEmergencyBtn	Bool	false
IContact	Bool	false
IAi1	Int	0
Q	Struct	
QRunning	Bool	false
QMonitorStatus	Int	0
QAo1	Real	0.0

在这里插入图片描述

4, 再在程序块中建立DB9: 电机控制集合1DB, 实现对UDT的实例化. 这里可以使用array of “motorUDT1”

在这里插入图片描述
在OB1中引用FB2 则 OB1会自动生成DB块 DB9

在这里插入图片描述
在这里插入图片描述

总结: 面向对象的三大特征是 继承 封装 多态 , 博途很好的完成了封装, 继承目前只有单例模式(背景数据块), 多态还做的很不好. 但是可以将字段定义为static, 用In和Out 做get set 将字段暴露出来. PLC编程的发展, 离主流面向对象语言还有很大的差距.

#include "pch.h"


extern "C" _declspec(dllexport) int Add(int a, int b)//extern 外部引用入口 dllexport 可以导出
{
	return a + b;
}

    public class CPPTest
    {

        [DllImport("MyFirstCPPDll.dll",EntryPoint="Add",CharSet =CharSet.Ansi,CallingConvention =CallingConvention.Cdecl)]
        public static extern int Add(int a, int b);

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值