前言
本文分享一个自己编写的温度模拟量读取逻辑块。
一、功能概述
- 模拟量输入转换,并设置超量程(0-27648)报警:当输入值<0或>27648时,输出值为0或27648,同时报警;
- 设置采样频率:正常情况下,每个扫描周期计算一次,加上采样周期后在每个设定时间内计算一次;
- 具有滤波功能,可设置滤波次数(最大20);
- 可设置低低报警、低报警、高报警、高高报警数值;
- 当CPU启动时的第一个扫描周期,或按下“初始化按钮”后,将模拟量参数设置为默认值,其他情况下可在上位机界面修改。
二、温度模拟量读取程序编写
1.创建自定义数据类型
2.创建FB功能块“温度模拟量只读”
建立如下引脚变量:
3.编写程序
代码如下:
1.转换时间,把浮点数转换为时间
#Time := DINT_TO_TIME(REAL_TO_DINT(#HMI.CY_CYCLE * 1000.0) - 10); //DINT 1000转成TIME表示1S,若CY_CYCLE=1,则实际时间为1s
//“-10”是为了将1S分割成990ms低电平和10ms高电平
#LL_Time := DINT_TO_TIME(REAL_TO_DINT(#LL_T_Set * 1000.0));
#L_Time := DINT_TO_TIME(REAL_TO_DINT(#L_T_Set * 1000.0));
#H_Time := DINT_TO_TIME(REAL_TO_DINT(#H_T_Set * 1000.0));
#HH_Time := DINT_TO_TIME(REAL_TO_DINT(#HH_T_Set * 1000.0));
2.采样周期
#T[0](IN := NOT #T[1].Q, //T0延时990ms后接通,然后TI开始延时10ms,10ms后T1接通,T0断掉,T1断掉,T0重新开始延时990ms,循环往复
PT := #Time);
#T[1](IN := #T[0].Q,
PT := T#10ms);
#P0(CLK := #T[0].Q); //检测T0上升沿信号,触发模拟量转换计算,以此来实现每1s计算一次,即采样周期为1s
3.超量程报警
#AI := #AI_IN; //AI_IN是输入变量,无法赋值,故先将输入AI_IN暂存到AI里,之后用AI参与运算
IF #AI < #IN_MIN THEN
#AI := #IN_MIN;
#Over_Alarm_L := 1;
ELSE
#Over_Alarm_L := 0;
END_IF;
IF #AI > #IN_MAX THEN
#AI := #IN_MAX;
#Over_Alarm_H := 1;
ELSE
#Over_Alarm_H := 0;
END_IF;
IF #Over_Alarm_L OR #Over_Alarm_H THEN
#HMI.Over_Alarm := 1;
END_IF;
IF NOT #Over_Alarm_L AND NOT #Over_Alarm_H THEN
#HMI.Over_Alarm := 0;
END_IF;
4.计算输出值
#OUT_TC := ((INT_TO_REAL(#AI) - #IN_MIN) / (#IN_MAX - #IN_MIN)) * (#HMI.OUT_MAX - #HMI.OUT_MIN) + #HMI.OUT_MIN; //计算没有经过滤波的热电偶输出值
#OUT_RTD := INT_TO_REAL(#AI) / 10.0; //计算没有经过滤波的热电阻输出值
IF #HMI.Mode THEN //模式选择及输出
#OUT := #OUT_RTD;
ELSE
#OUT := #OUT_TC;
END_IF;
IF #P0.Q THEN
FOR #N := #HMI.Filt_Times TO 1 BY -1 DO //从最后一个值开始,依次将数组中的后一个值倒序赋给前一个值
#Filts[#N] := #Filts[#N - 1];
END_FOR;
#Filts[0] := #OUT; //将输出值赋给数组中的第一个值
#SUM := 0;
FOR #N := 0 TO #HMI.Filt_Times - 1 DO //计算滤波数组的和
#SUM := #SUM + #Filts[#N];
END_FOR;
#Filt_OUT := #SUM / #HMI.Filt_Times; //计算平均值
END_IF;
#AI_OUT := #Filt_OUT;
#HMI.AI_OUT := #Filt_OUT;
5.报警
//低低报
#T[2](IN := #AI_OUT <= #HMI.LL_Set AND NOT #HMI.LL_Act AND #HMI.LL_Set <> 0.0,
PT := #LL_Time);
IF #T[2].Q THEN
#HMI.LL_Alarm := 1;
#LL_Alarm := 1;
IF NOT #HMI.LL_Lock THEN
#HMI.LL_Latch := 1;
END_IF;
ELSE
#HMI.LL_Alarm := 0;
#LL_Alarm := 0;
END_IF;
//低报
#T[3](IN := #AI_OUT < #HMI.L_Set AND #AI_OUT > #HMI.LL_Set AND NOT #HMI.L_Act AND #HMI.L_Set <> 0.0,
PT := #L_Time);
IF #T[3].Q THEN
#HMI.L_Alarm := 1;
#L_Alarm := 1;
IF NOT #HMI.L_Lock THEN
#HMI.L_Latch := 1;
END_IF;
ELSE
#HMI.L_Alarm := 0;
#L_Alarm := 0;
END_IF;
//高报
#T[4](IN := #AI_OUT < #HMI.HH_Set AND #AI_OUT > #HMI.H_Set AND NOT #HMI.H_Act AND #HMI.H_Set <> 0.0,
PT := #L_Time);
IF #T[4].Q THEN
#HMI.H_Alarm := 1;
#H_Alarm := 1;
IF NOT #HMI.H_Lock THEN
#HMI.H_Latch := 1;
END_IF;
ELSE
#HMI.H_Alarm := 0;
#H_Alarm := 0;
END_IF;
//高高报
#T[5](IN := #AI_OUT >= #HMI.HH_Set AND NOT #HMI.HH_Act AND #HMI.HH_Set <> 0.0,
PT := #L_Time);
IF #T[5].Q THEN
#HMI.HH_Alarm := 1;
#HH_Alarm := 1;
IF NOT #HMI.HH_Lock THEN
#HMI.HH_Latch := 1;
END_IF;
ELSE
#HMI.HH_Alarm := 0;
#HH_Alarm := 0;
END_IF;
6.复位
IF #HMI.HMI_Rst THEN
#HMI.LL_Latch := 0;
#HMI.L_Latch := 0;
#HMI.H_Latch := 0;
#HMI.HH_Latch := 0;
END_IF;
IF NOT "AlwaysFALSE" THEN
#HMI.HMI_Rst := 0;
END_IF;
三、模拟量参数设置程序编写
1.创建FB功能块“模拟量参数设定”
建立如下引脚变量:
2.编写程序
1.在FB功能块“模拟量参数设定”中,调用FB功能块“温度模拟量只读”。
2.其它代码如下:
IF #FirstScan OR #模拟量参数设定初始化 THEN
#HMI.OUT_MAX := #OUT_MAX;
#HMI.OUT_MIN := #OUT_MIN;
#HMI.LL_Set := #LL_Set;
#HMI.L_Set := #L_Set;
#HMI.H_Set := #H_Set;
#HMI.HH_Set := #HH_Set;
#HMI.CY_CYCLE := #CY_CYCLE;
#HMI.Filt_Times := #Filt_Times;
#HMI.Mode := #Mode;
END_IF;