Вход

Просмотр полной версии : не могу выйти из бесконечного цикла FOR



Kiselev
17.01.2012, 14:48
Добрый день! не могу понять почему переменная Var1 продолжает расти до переполнения:
PROGRAM PLC_PRG
VAR
Counter: INT;
Var1: INT;
END_VAR

--------


FOR Counter:=1 TO 5 DO
Var1:= Var1+1;
END_FOR;

Kiselev
17.01.2012, 17:57
И Counter что-то завис на 6. Да ?
ну с Counter понятно- выполнилось условие, но почему тело цикла-то выполняется? в чем ошибка?

Gans
17.01.2012, 18:11
ну с Counter понятно- выполнилось условие, но почему тело цикла-то выполняется? в чем ошибка?
Извините, а что Вы ожидали получить? Программа PLC_PRG по умолчанию в CoDeSys вертится постоянно, вот из неё и надо вызывать другие программы (Например: prgOtoplenie), функциональный блоки (Например: fnbDetectAlarm) и тд.

lara197a
17.01.2012, 19:41
Или поместите FOR во внутрь IF. Также для выхода в теле цикла используют EXIT.
А так у Вас каждый цикл программы, как верно заметил Виктор Родиков повторяется Ваш FOR/

Киналь
19.01.2012, 13:55
ну с Counter понятно- выполнилось условие, но почему тело цикла-то выполняется? в чем ошибка?

Потому что программа в ПЛК фактически выглядит так:

WHILE(1) DO
PLC_PRG();
END_WHILE

Подставьте вместо PLC_PRG() свою программу и поймёте, почему цикл получается «бесконечным».

Yegor
20.01.2012, 09:13
А он не предлагал ничего городить вроде.

ksn33
20.01.2012, 12:06
1 PLC_PRG постоянно циклически вызывается контролером
2 при первом вызове PLC_PRG переменная Var1 не определена и может принять любое значение (к примеру Х)
3 выполняется цикл FOR после выполнении его переменная Var1 принимает значение Х+5, переменная Counter значение 6
4 заканчивается выполнение PLC_PRG
5 следующий вызов PLC_PRG
6 переменная Var1 имеет значение (х+5)
7 выполняется цикл FOR после выполнения цикла переменная Var1 принимает значение (х+5+5) переменная Counter значение 6
8 заканчивается выполнение PLC_PRG
и так далее выполняются пункты 5-8
Просматриваю программу видим бесконечно растущую переменную Var1 и переменную Counter имеющую значение 6

Kiselev
23.01.2012, 09:33
1 PLC_PRG постоянно циклически вызывается контролером
2 при первом вызове PLC_PRG переменная Var1 не определена и может принять любое значение (к примеру Х)
3 выполняется цикл FOR после выполнении его переменная Var1 принимает значение Х+5, переменная Counter значение 6
4 заканчивается выполнение PLC_PRG
5 следующий вызов PLC_PRG
6 переменная Var1 имеет значение (х+5)
7 выполняется цикл FOR после выполнения цикла переменная Var1 принимает значение (х+5+5) переменная Counter значение 6
8 заканчивается выполнение PLC_PRG
и так далее выполняются пункты 5-8
Просматриваю программу видим бесконечно растущую переменную Var1 и переменную Counter имеющую значение 6

Извините за глупый вопрос, но я не понимаю почему инструкция в цикле продолжает работать (переменная Var1 инкрементируется) при достижении Counter значения 6.

ПРоблему я победил - перед циклом поставил Var1:=0. Все работает как надо. но почему это работает я не понимаю. Тем более что по умолчанию Var1 и так равен 0.

ksn33
23.01.2012, 10:12
Смотри, цикл у тебя, к примеру выполнился первый раз (Var1 стало к примеру 5) а далее ПЛК опять циклически вызывает PLC_PRG цикл начинает выполняться второй раз а значение Var1 осталось то предыдущим (5) поэтому оно опять увеличивается на 5(теперь оно 10)! Далее опять вызывается PLC_PRG и цикл выполняется третий раз и так далее... Когда ты поставил Var1:=0 перед выполнением цикла то каждый раз перед выполнением цикла у тебя значение Var1 обнуляется поэтому оно не превышает 5. Так яснее?
PS За наличие вопросов извиняться не надо, хуже когда их нет

Kiselev
23.01.2012, 13:30
ksn33, большое спасибо-мне понятна логика работы ПЛК и вызова PLC_PRG, но я не понимаю следующего из справки Кодесис:
"С помощью FOR можно программировать повторяющиеся процессы.
Синтаксис:
INT_Var :INT;
FOR <INT_Var> := <INIT_VALUE> TO <END_VALUE> {BY <Step size>} DO
<Instructions>
END_FOR
Часть конструкции, заключенная в фигурные скобки, не обязательна.
<Instructions> выполняются, пока счетчик <INT_Var> не больше <END_VALUE>. Это условие проверяется перед выполнением <Instructions>, поэтому раздел <Instructions> не выполняется, если <INIT_VALUE> больше <END_VALUE>.
Всякий раз, когда выполняются <Instructions>, значение <INIT_VALUE>, увеличивается на <Step_size>."

В моем примере, если Значение Counter уже больше 5, то почему инструкция продолжает выполняться?

Kiselev
23.01.2012, 15:47
Потаму что каждый раз

т.е. Соunter каждый раз сбрасывается при выходе из цикла? все, теперь понял. спасибо.

ksn33
23.01.2012, 17:26
Смотри, как работает for:
1 перед первым выполнение цикла переменной Соunter присваивается значение 1
2 выполняется первый раз тело цикла до END_FOR
3 переменной Соunter присваивается значение +1(2)
4 выполняется второй раз тело цикла до END_FOR
5 переменной Соunter присваивается значение +1(3)
6 выполняется третий раз тело цикла до END_FOR
7 переменной Соunter присваивается значение +1(4)
8 выполняется четвертый раз тело цикла до END_FOR
9 переменной Соunter присваивается значение +1(5)
10 выполняется пятый раз тело цикла до END_FOR
11 переменной Соunter присваивается значение +1(6)
12 поскольку Соunter больше 5 дальнейшая часть программы выполняется после END_FOR

Yegor
24.01.2012, 06:20
«Раскроем скобки»:

(* Такт 0 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 5 *)

(* Такт 1 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 10 *)

(* Такт 2 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 15 *)

(* Такт 3 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 20 *)

(* Такт 4 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 25 *)

(* Такт 5 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 30 *)

(...)

(* Такт 412380 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 2061905 *)

(* Такт 412381 *)
FOR Counter := 1 TO 5 DO
Var1 := Var1 + 1;
END_FOR;
(* Var1 = 2061910 *)

(...)

Kiselev
24.01.2012, 10:37
Смотри, как работает for:
1 перед первым выполнение цикла переменной Соunter присваивается значение 1
2 выполняется первый раз тело цикла до END_FOR
3 переменной Соunter присваивается значение +1(2)
4 выполняется второй раз тело цикла до END_FOR
5 переменной Соunter присваивается значение +1(3)
6 выполняется третий раз тело цикла до END_FOR
7 переменной Соunter присваивается значение +1(4)
8 выполняется четвертый раз тело цикла до END_FOR
9 переменной Соunter присваивается значение +1(5)
10 выполняется пятый раз тело цикла до END_FOR
11 переменной Соunter присваивается значение +1(6)
12 поскольку Соunter больше 5 дальнейшая часть программы выполняется после END_FOR

т.е. Counter'у при следующем вызове (текущее значение 6) присвоится 1, и Var1 продолжит инкрементироваться? а присваивая Var1:=0 перед циклом ,я фактически ограничиваю ее приращение в следуещем прогоне после того, как Сounter стал равен 6?.

rovki
24.01.2012, 14:32
Все бесконечно зациклились :D :D :D на этой теме.Если долго обьяснять ,то и самому запутаться можно :D :D :D :D

BETEP
24.01.2012, 16:42
а мне кажется что Kiselev просто прикалывается над учителями.