技术论坛

 回复:用最简单方法完成这道编程题

返回主题列表
作者 主题
Auto_w
游民

经验值:131
发帖数:88
精华帖:1
楼主    2005-12-27 21:19:45
主题:用最简单方法完成这道编程题
有7个二通阀,每个阀上有2个DC24V线圈,2个到位信号DC24V。工作原理:一个线圈得电后,阀动作,动作到位后到位信号反馈(DC24V),如线圈得电后3S,到位信号无反馈,则报警。
- -(T1)——/——(Alarm)
如每个这样做,算最笨的做法。。。请考虑。。
zhangli0
至圣

经验值:48087
发帖数:17127
精华帖:63
    2005-12-31 23:09:21
精华帖  主题:回复:用最简单方法完成这道编程题
做一个功能块,一个输入res,(反馈),两个输出out,alarm(控制输出和报警),静态变量bool:tag1,tag2,over;real:tag3_sp,tag3其它的我就不写了,只写关键部分。
a out
fp tag1
s tag2
a tag2
jcn m1
l 0.5
l tag3
+r
t tag3
l tag3_sp
>=r
s over
a out
a over
an res
=alarm
an out
r tag2
r over
这段程序写在fb块中,在中断中调用,中断周期0.5秒。使用的是中断计时,没有使用系统的计时器。

活到老,学到老!为了生活学习吧!
老兵veteran
至圣

经验值:59333
发帖数:9984
精华帖:505
    2006-01-03 17:22:06
精华帖  主题:回复:用最简单方法完成这道编程题
定义Q0.0-Q1.5分别对应14个电磁阀;I0.0-I1.5分别对应14个位置开关;Q2.0-Q3.5分别对应14个报警输出。

ORGANIZATION_BLOCK OB 1
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1

BEGIN
NETWORK
TITLE =

L QW 0;
L IW 0;
XOW ;
T MW 0;
L MW 2;
AW ;
T QW 2;


END_ORGANIZATION_BLOCK

ORGANIZATION_BLOCK "CYC_INT5"
TITLE = "Cyclic Interrupt"
VERSION : 0.1

BEGIN
NETWORK
TITLE =

CALL FC 1 (
sa := M 0.0,
alarm := M 2.0,
comparor := DB1.DBW 0);
CALL FC 1 (
sa := M 0.1,
alarm := M 2.1,
comparor := DB1.DBW 2);
CALL FC 1 (
sa := M 0.2,
alarm := M 2.2,
comparor := DB1.DBW 4);
CALL FC 1 (
sa := M 0.3,
alarm := M 2.3,
comparor := DB1.DBW 6);
CALL FC 1 (
sa := M 0.4,
alarm := M 2.4,
comparor := DB1.DBW 8);
CALL FC 1 (
sa := M 0.5,
alarm := M 2.5,
comparor := DB1.DBW 10);
CALL FC 1 (
sa := M 0.6,
alarm := M 2.6,
comparor := DB1.DBW 12);
CALL FC 1 (
sa := M 0.7,
alarm := M 2.7,
comparor := DB1.DBW 14);
CALL FC 1 (
sa := M 1.0,
alarm := M 3.0,
comparor := DB1.DBW 16);
CALL FC 1 (
sa := M 1.1,
alarm := M 3.1,
comparor := DB1.DBW 16);
CALL FC 1 (
sa := M 1.2,
alarm := M 3.2,
comparor := DB1.DBW 18);
CALL FC 1 (
sa := M 1.3,
alarm := M 3.3,
comparor := DB1.DBW 20);
CALL FC 1 (
sa := M 1.4,
alarm := M 3.4,
comparor := DB1.DBW 22);
CALL FC 1 (
sa := M 1.5,
alarm := M 3.5,
comparor := DB1.DBW FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
sa : BOOL ;
END_VAR
VAR_OUTPUT
alarm : BOOL ;
END_VAR
VAR_IN_OUT
comparor : INT ;
END_VAR
BEGIN
NETWORK
TITLE =

AN #sa;
JC M001; //如果有阀的动作而没有检测开关信号,则开始计时,否则就不报警。
L 1;
L #comparor;
+I ;
T #comparor;
L 40; //该数的取值等于4S/定时中断时间,本例为100ms.
>=I ;
JC M002;
JU M003;
M001: L 0;
T #comparor;
CLR
= #alarm
JU M003;
M002: SET ;
= #alarm;
M003: NOP 0;
END_FUNCTION

24);

END_ORGANIZATION_BLOCK

天生不宜做胜利者,自来没有胜利的欲望,只是不甘失败,十分十分不甘心失败。木心
月夜水明楼
侠客

经验值:662
发帖数:402
精华帖:3
    2006-01-10 14:50:11
精华帖  主题:回复:用最简单方法完成这道编程题
七组阀,每个阀为双线圈,因而最多能同时工作的线圈个数为7个
I0.0-I0.7;I2.0-I2.7为阀的开关,I1.0-I1.7;I3.0-I3.7为返回信号
Q4.0-Q4.7;Q6.0-Q6.7对应十四个线圈
Q5.0-Q5.7;Q7.0-Q7.7对应十四个报警信号
DB1.DBX0.0为报警复归信号

可做如下类似控制(只做了三组,其它相同):

//OB1 "Main Program Sweep (Cycle)"
A(
O I 0.0
O Q 0.0
)
AN I 0.1
= Q 4.0


A(
O I 0.1
O Q 0.1
)
AN I 0.0
= Q 4.1


A(
O I 0.2
O Q 0.2
)
AN I 0.3
= Q 4.2


A(
O I 0.3
O Q 0.3
)
AN I 0.2
= Q 4.3


A(
A Q 4.0
AN I 1.0
O
A Q 4.1
AN I 1.1
O
A Q 4.2
AN I 1.2
O
A Q 4.3
AN I 1.3
)
FP M 20.0
S M 10.0



A M 10.0
JNB M001
CALL SFC 32
OB_NR :=20
DTIME :=T#3S
SIGN :=MW0
RET_VAL:=MW2
M001: A BR
R M 10.0


A DB1.DBX 0.0
FP M 20.2
S M 10.2



A M 10.2
JNB M002
CALL SFC 32
OB_NR :=20
DTIME :=T#1MS
SIGN :=MW30
RET_VAL:=MW32
M002: A BR
R M 10.2


A(
O I 1.0
O I 1.1
O I 1.2
O I 1.3
)
FP M 20.1
S M 10.1



A M 10.1
JNB M003
CALL SFC 33
OB_NR :=20
RET_VAL:=MW4
M003: A BR
R M 10.1


CALL SFC 34
OB_NR :=20
RET_VAL:=MW6
STATUS :=MW8
NOP 0

//OB20 "Time Delay Interrupt"

SET
= Q 5.0
= Q 5.1
= Q 5.2
= Q 5.3


A DB1.DBX 0.0
R Q 5.0
R Q 5.1
R Q 5.2
R Q 5.3
liwenqun
奇侠

经验值:6852
发帖数:5293
精华帖:25
    2006-01-14 21:44:01
精华帖  主题:回复:用最简单方法完成这道编程题
采用SFC64 只做了一个阀门的控制的FB 其他的一样就可以了

ORGANIZATION_BLOCK "main"
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1


VAR_TEMP
OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
OB1_SCAN_1 : BYTE ; //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
OB1_PRIORITY : BYTE ; //Priority of OB Execution
OB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)
OB1_RESERVED_1 : BYTE ; //Reserved for system
OB1_RESERVED_2 : BYTE ; //Reserved for system
OB1_PREV_CYCLE : INT ; //Cycle time of previous OB1 scan (milliseconds)
OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)
OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)
OB1_DATE_TIME : DATE_AND_TIME ; //Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =

A M 0.0; //开阀给定信号
= L 20.0;
BLD 103;
A M 0.1; //关阀给定信号
= L 20.1;
BLD 103;
A I 0.0; //阀门开到位信号
= L 20.2;
BLD 103;
A I 0.1; //阀门关到位信号
= L 20.3;
BLD 103;
CALL "FMCtrl" , DB 1 (
Open := L 20.0,
Close := L 20.1,
OpenLimit := L 20.2,
CloseLimit := L 20.3,
QOpen := Q 0.0,//开阀
QClose := Q 0.1,//关阀
QOAlarm := Q 0.2,//开阀报警
QCAlarm := Q 0.3);//关阀报警
NOP 0;
END_ORGANIZATION_BLOCK
FUNCTION_BLOCK "FMCtrl"
TITLE ="阀门开关+报警"
VERSION : 0.1


VAR_INPUT
Open : BOOL ; //开阀信号
Close : BOOL ; //关阀信号
OpenLimit : BOOL ; //阀门开到位信号
CloseLimit : BOOL ; //阀门关到位信号
END_VAR
VAR_OUTPUT
QOpen : BOOL ; //开阀输出
QClose : BOOL ; //关阀输出
QOAlarm : BOOL ; //开阀超时报警
QCAlarm : BOOL ; //关阀超时报警
END_VAR
VAR
OP1 : BOOL ; //中间变量1
OP2 : BOOL ; //中间变量2
P_1 : BOOL ; //中间脉冲变量1
P_2 : BOOL ; //中间脉冲变量2
Openretnow : TIME ; //开阀的现在时间
Openretstart : TIME ; //开阀的起始时间
Closeretnow : TIME ; //关阀的现在时间
Closeretstart : TIME ; //关阀的起始时间
END_VAR
VAR_TEMP
Opentempnow : DINT ; //转换后开阀的现在时间
Opentempstart : DINT ;//转换后开阀的起始时间
Opentempsub : DINT ; //转换后开阀输出的时间
Closetempnow : DINT ; //转换后关阀的现在时间
Closetempstart : DINT ;//转换后关阀的起始时间
Closetempsub : DINT ; //转换后关阀输出的时间
END_VAR
BEGIN
NETWORK
TITLE =Temporary placeholder variable

A #Open;
AN #OpenLimit;
= L 24.0;
A L 24.0;
= #OP1;
A #OP1;
= #QOpen;
A L 24.0;
FP #P_1;
JNB _001;
CALL "TIME_TCK" (
RET_VAL := #Openretstart);
_001: NOP 0;
NETWORK
TITLE =

A #OP1;
= L 24.0;
A L 24.0;
JNB _002;
CALL "TIME_TCK" (
RET_VAL := #Openretnow);
_002: NOP 0;
A L 24.0;
JNB _003;
L #Openretstart;
T #Opentempstart;
_003: NOP 0;
A L 24.0;
JNB _004;
L #Openretnow;
T #Opentempnow;
_004: NOP 0;
A L 24.0;
JNB _005;
L #Opentempnow;
L #Opentempstart;
-D ;
T #Opentempsub;
_005: NOP 0;
A L 24.0;
A( ;
L #Opentempsub;
L L#3000;
>D ;
) ;
= #QOAlarm;
NETWORK
TITLE =Temporary placeholder variable

A #Close;
AN #CloseLimit;
= L 24.0;
A L 24.0;
= #OP2;
A #OP2;
= #QClose;
A L 24.0;
FP #P_2;
JNB _006;
CALL "TIME_TCK" (
RET_VAL := #Closeretstart);
_006: NOP 0;
NETWORK
TITLE =

A #OP2;
= L 24.0;
A L 24.0;
JNB _007;
CALL "TIME_TCK" (
RET_VAL := #Closeretnow);
_007: NOP 0;
A L 24.0;
JNB _008;
L #Closeretstart;
T #Closetempstart;
_008: NOP 0;
A L 24.0;
JNB _009;
L #Closeretnow;
T #Closetempnow;
_009: NOP 0;
A L 24.0;
JNB _00a;
L #Closetempnow;
L #Closetempstart;
-D ;
T #Closetempsub;
_00a: NOP 0;
A L 24.0;
A( ;
L #Closetempsub;
L L#3000;
>D ;
) ;
= #QCAlarm;
END_FUNCTION_BLOCK

怎么论坛改成这样了??
老兵veteran
至圣

经验值:59333
发帖数:9984
精华帖:505
    2006-01-16 10:44:10
精华帖  主题:回复:用最简单方法完成这道编程题
以上程序在网吧中编制,没有经过调试,可能也有语法错误,见谅,就算抛砖引玉吧.
这段程序没用SFB/SFC/T/C,也没用中断,是读OB1的扫描时间并条件累加/清零的,而且不存在溢出问题.
天生不宜做胜利者,自来没有胜利的欲望,只是不甘失败,十分十分不甘心失败。木心
伊默
至圣

经验值:19231
发帖数:4256
精华帖:118
    2006-02-03 15:04:51
精华帖  主题:回复:用最简单方法完成这道编程题



在OB1的局部变量中有一个"OB1_PREV_CYCLE"变量,就是用来记录上一扫描周期的时间, 拿这个变量不停的累加,就能粗略知道累积时间,这样就可以不用定时中断OB35,也不用SFB,也不用系统块内定义的定时脉冲,即可得到累积时间值了.
I can do it
scmyzq
游士

经验值:170
发帖数:122
精华帖:1
    2006-02-17 21:16:35
精华帖  主题:回复:用最简单方法完成这道编程题
煤造气好象也就要用出题老兄说的那种阀。

我做过类似的东西,约500个程控阀,只不过是每程控阀是1DO电磁阀加1DI阀检测,也是DO开或关时超过3~12s报警。
最早是用了“一个SFB4”的。后面看了大家的发言后觉得可以这样 用SCL写FB。
1、申明STA类型变量A:DINT、B:BOOL。将A:=A+OB1_PREV_CYCLE;
2、关键在于A的清零
IF DO <> B THEN(即A XOR B为真时,说明A有跳变)
A:=0;
B:=DO;
END_IF;
3:IF(A>3000~12000)THEN
IF DO AND NOT DI THEN
开报警;
END_IF;
IF NOT DO AND DI THEN
关报警;
END_IF;
END_IF;

其实就是用SFB4的多重背景也大不了多少。


Auto_w
游民

经验值:131
发帖数:88
精华帖:1
    2006-03-05 21:13:35
精华帖  主题:回复:用最简单方法完成这道编程题
很高兴看到这么多朋友在一起交流。其实这道题是我做工程中用的,我用的方法是利用中断做的:OB35(中断时间改为1000MS)调用做的FC。
这样可以节省资源和避免重复错用定时器和记数器(个人意见)。
这么多高手提供的方法,真叫人叫好,要努力学习啊,呵呵
游荡
侠客

经验值:828
发帖数:163
精华帖:7
    2006-03-10 21:49:27
精华帖  主题:回复:用最简单方法完成这道编程题
先写FB1:
VAR_INPUT
Driver : BOOL ;
FeedBack : BOOL ;
nowPast : INT ;
END_VAR
VAR_OUTPUT
Alarm : BOOL ;
END_VAR
VAR
myTime : INT ;
END_VAR
BEGIN
NETWORK
TITLE =
A #Driver;
AN #FeedBack;
A( ;
L #myTime;
L 3100;
<=I ;
) ;
JNB _001;
L #myTime;
L #nowPast;
+I ;
T #myTime;
_001: A( ;
ON #Driver;
O #FeedBack;
) ;
JNB _002;
L 0;
T #myTime;
_002: L #myTime;
L 3000;
>=I ;
= #Alarm;
END_FUNCTION_BLOCK
然后在OB1中调用:
CALL FB 1 , "Val1"
Driver := ///驱动信号
FeedBack:= //反馈
nowPast :=#OB1_PREV_CYCLE ///
Alarm := ///警告输出
SIEAUTO
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。