Просмотр полной версии : не могу выйти из бесконечного цикла FOR
Добрый день! не могу понять почему переменная Var1 продолжает расти до переполнения:
PROGRAM PLC_PRG
VAR
Counter: INT;
Var1: INT;
END_VAR
--------
FOR Counter:=1 TO 5 DO
Var1:= Var1+1;
END_FOR;
И Counter что-то завис на 6. Да ?
ну с Counter понятно- выполнилось условие, но почему тело цикла-то выполняется? в чем ошибка?
ну с Counter понятно- выполнилось условие, но почему тело цикла-то выполняется? в чем ошибка?
Извините, а что Вы ожидали получить? Программа PLC_PRG по умолчанию в CoDeSys вертится постоянно, вот из неё и надо вызывать другие программы (Например: prgOtoplenie), функциональный блоки (Например: fnbDetectAlarm) и тд.
lara197a
17.01.2012, 19:41
Или поместите FOR во внутрь IF. Также для выхода в теле цикла используют EXIT.
А так у Вас каждый цикл программы, как верно заметил Виктор Родиков повторяется Ваш FOR/
ну с Counter понятно- выполнилось условие, но почему тело цикла-то выполняется? в чем ошибка?
Потому что программа в ПЛК фактически выглядит так:
WHILE(1) DO
PLC_PRG();
END_WHILE
Подставьте вместо PLC_PRG() свою программу и поймёте, почему цикл получается «бесконечным».
А он не предлагал ничего городить вроде.
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
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.
Смотри, цикл у тебя, к примеру выполнился первый раз (Var1 стало к примеру 5) а далее ПЛК опять циклически вызывает PLC_PRG цикл начинает выполняться второй раз а значение Var1 осталось то предыдущим (5) поэтому оно опять увеличивается на 5(теперь оно 10)! Далее опять вызывается PLC_PRG и цикл выполняется третий раз и так далее... Когда ты поставил Var1:=0 перед выполнением цикла то каждый раз перед выполнением цикла у тебя значение Var1 обнуляется поэтому оно не превышает 5. Так яснее?
PS За наличие вопросов извиняться не надо, хуже когда их нет
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, то почему инструкция продолжает выполняться?
Потаму что каждый раз
т.е. Соunter каждый раз сбрасывается при выходе из цикла? все, теперь понял. спасибо.
Смотри, как работает 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
«Раскроем скобки»:
(* Такт 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 *)
(...)
Смотри, как работает 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?.
Все бесконечно зациклились :D :D :D на этой теме.Если долго обьяснять ,то и самому запутаться можно :D :D :D :D
а мне кажется что Kiselev просто прикалывается над учителями.
Powered by vBulletin® Version 4.2.3 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot