Просмотр полной версии : переменные произвольно меняют значения, как это может быть???
Здравствуйте возникла следующая проблемма:
Есть подпрограмма, в ней производится опрос счетчика...по шагам примерный код:
CASE Step OF
0:
(*Запрос 1*)
Step:=1;
Timer(IN:=TRUE, PT:=PollingDelay );
1:
Timer();
IF Timer.Q THEN
Timer(IN:=FALSE);
Step:=2;
END_IF
2:
(*Запрос 2*)
Step:=3;
Timer(IN:=TRUE, PT:=PollingDelay );
3:
Timer();
IF Timer.Q THEN
Timer(IN:=FALSE);
Step:=4;
END_IF
4:
(*Запрос 2*)
Step:=5;
Timer(IN:=TRUE, PT:=PollingDelay );
5:
Timer();
IF Timer.Q THEN
Timer(IN:=FALSE);
Step:=0;
END_IF
END_CASE
Так вот переменная Step ведет себя обсолютно непонятно....она может ВДРУГ:) получить значение 66 или 95486 или.....ну вобщем как это возможно ведь присвоение везде явное переменная объявлена в этом программном блоке.
Я понимаю что в блок CASE можно добавить ELSE и там например обнулять Step, НО!!!!!!!!!!!! Каккой может быть ELSE если значения присваиваю я!!!!
Самое интересное, есть еще один блок CASE в другой подпрограмме этого проэкта.....в нем переменная NextTime ведет себя точно также
Terrano1992
03.11.2010, 07:29
переменная Step ведет себя обсолютно непонятно
Изменять внутри блока CASE значение его переменной-селектора - как-то "не по фэншую", плохой стиль... Может сработать нормально, а может и глюкануть: кто его знает, какой именно исполняемый код генерируется используемым компилятором с учетом всяческих оптимизаций?
Попробуйте присваивать новое значение внутри CASE некой созданной для этого вспомогательной переменной, а сразу после блока CASE переписывать ее значение в Step. Оно и как-то "академичней" будет, и все сомнения снимет.
При объявлении Step: word:=0; <- так делали?
глобальных переменных с аналогичными именами нет?
если экспортировать данный кусок программы в пустую проблема остается?
и выложенный текст программы находится в функциональном блоке или в функции? тута поконкретней пожалуйста :-)
ввел параметр tempStep и изменяю его внутри блока CASE
сразу после блока CASE присваиваю Step:=tempStep;
эфект тот же (((
PROGRAM MercuryPoll
VAR
command1:ARRAY [0..10] OF BYTE:= 16#42, 16#01, 16#02, 16#02, 16#02, 16#02, 16#02, 16#02, 16#02, 16#98, 16#A4;
command2:ARRAY [0..5] OF BYTE:= 16#42, 16#08, 16#16, 16#11, 16#5B, 16#F2;
command3:ARRAY [0..5] OF BYTE:= 16#42, 16#08, 16#16, 16#21, 16#5B, 16#E6;
command4:ARRAY [0..5] OF BYTE:= 16#00, 16#05, 16#00, 16#00, 16#10, 16#25;
PollingDelay:TIME:=T#500ms
Timer:TON;
Step: UINT:=0; tempStep:UINT:=0;
END_VAR
CASE Step OF
(*Çàïðîñ íà îòêðûòèå êàíàëà ñâÿçè*)
0:
WriteCOM(Command:=ADR(command1) ,CommandLength:=11 ,PortNumber:=0);
tempStep:= 1;
Timer(IN:=TRUE, PT:=PollingDelay );
(*Îæèäàíèå ìåæäó çàïðîñàìè*)
1:
Timer();
IF Timer.Q THEN
IF NOT ReadCOM.Busy THEN
ReadCOM.Reset :=TRUE;
END_IF
timer(IN:=FALSE, PT:=T#0s );
tempStep:= 2;
END_IF
2:
WriteCOM(Command:=ADR(command2) ,CommandLength:=6 ,PortNumber:=0);
tempStep:= 3;
Timer(IN:=TRUE, PT:=PollingDelay );
3:
IF (NOT ReadCOM.Busy) AND (ReadCOM.ResponseLength=12) THEN
U1int:= (ReadCOM.Response[1]*16#10000+ReadCOM.Response[3]*16#100+ReadCOM.Response[2]);
U2int:= (ReadCOM.Response[4]*16#10000+ReadCOM.Response[6]*16#100+ReadCOM.Response[5]);
U3int:= (ReadCOM.Response[7]*16#10000+ReadCOM.Response[9]*16#100+ReadCOM.Response[8]);
U1:=U1int/(EXPT(10,2));
U2:=U2int/(EXPT(10,2));
U3:=U3int/(EXPT(10,2));
END_IF
timer();
IF timer.Q THEN
IF NOT ReadCOM.Busy THEN
ReadCOM.Reset :=TRUE;
END_IF
timer(IN:=FALSE, PT:=T#0s );
tempStep:= 4;
END_IF
4:
WriteCOM(Command:=ADR(command3) ,CommandLength:=6 ,PortNumber:=0);
tempStep:= 5;
Timer(IN:=TRUE, PT:=PollingDelay );
5:
IF (NOT ReadCOM.Busy) AND (ReadCOM.ResponseLength=12) THEN
i1int:= (ReadCOM.Response[1]*16#10000+ReadCOM.Response[3]*16#100+ReadCOM.Response[2]);
i2int:= (ReadCOM.Response[4]*16#10000+ReadCOM.Response[6]*16#100+ReadCOM.Response[5]);
i3int:= (ReadCOM.Response[7]*16#10000+ReadCOM.Response[9]*16#100+ReadCOM.Response[8]);
i1:=i1int/(EXPT(10,3));
i2:=i2int/(EXPT(10,3));
i3:=i3int/(EXPT(10,3));
END_IF
timer();
IF timer.Q THEN
IF NOT ReadCOM.Busy THEN
ReadCOM.Reset :=TRUE;
END_IF
timer(IN:=FALSE, PT:=T#0s );
tempStep:= 6;
END_IF
6:
WriteCOM(Command:=ADR(command4) ,CommandLength:=6 ,PortNumber:=0);
tempStep:= 7;
Timer(IN:=TRUE, PT:=PollingDelay );
7:
IF (NOT ReadCOM.Busy) AND (ReadCOM.ResponseLength=19) THEN
CurrentEnergy:= (ReadCOM.Response[2]*16#1000000+
ReadCOM.Response[1]*16#10000+
ReadCOM.Response[4]*16#100+
ReadCOM.Response[3]);
END_IF
timer();
IF timer.Q THEN
IF NOT ReadCOM.Busy THEN
ReadCOM.Reset :=TRUE;
END_IF
timer(IN:=FALSE, PT:=T#0s );
tempStep:= 0;
END_IF
END_CASE
Step:=tempStep;
глюк случается на 6 или на 7 шаге если их исключить, тоесть в 5 шаге присваивать 0 то все работает
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot