Вход

Просмотр полной версии : переменные произвольно меняют значения, как это может быть???



AlexPC1
03.11.2010, 05:49
Здравствуйте возникла следующая проблемма:
Есть подпрограмма, в ней производится опрос счетчика...по шагам примерный код:

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 или.....ну вобщем как это возможно ведь присвоение везде явное переменная объявлена в этом программном блоке.

AlexPC1
03.11.2010, 05:53
Я понимаю что в блок CASE можно добавить ELSE и там например обнулять Step, НО!!!!!!!!!!!! Каккой может быть ELSE если значения присваиваю я!!!!

Самое интересное, есть еще один блок CASE в другой подпрограмме этого проэкта.....в нем переменная NextTime ведет себя точно также

Terrano1992
03.11.2010, 07:29
переменная Step ведет себя обсолютно непонятно
Изменять внутри блока CASE значение его переменной-селектора - как-то "не по фэншую", плохой стиль... Может сработать нормально, а может и глюкануть: кто его знает, какой именно исполняемый код генерируется используемым компилятором с учетом всяческих оптимизаций?
Попробуйте присваивать новое значение внутри CASE некой созданной для этого вспомогательной переменной, а сразу после блока CASE переписывать ее значение в Step. Оно и как-то "академичней" будет, и все сомнения снимет.

Gans
03.11.2010, 07:50
При объявлении Step: word:=0; <- так делали?
глобальных переменных с аналогичными именами нет?
если экспортировать данный кусок программы в пустую проблема остается?
и выложенный текст программы находится в функциональном блоке или в функции? тута поконкретней пожалуйста :-)

AlexPC1
03.11.2010, 08:23
ввел параметр tempStep и изменяю его внутри блока CASE
сразу после блока CASE присваиваю Step:=tempStep;
эфект тот же (((

AlexPC1
03.11.2010, 08:29
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
(*&#199;&#224;&#239;&#240;&#238;&#241; &#237;&#224; &#238;&#242;&#234;&#240;&#251;&#242;&#232;&#229; &#234;&#224;&#237;&#224;&#235;&#224; &#241;&#226;&#255;&#231;&#232;*)
0:
WriteCOM(Command:=ADR(command1) ,CommandLength:=11 ,PortNumber:=0);
tempStep:= 1;
Timer(IN:=TRUE, PT:=PollingDelay );

(*&#206;&#230;&#232;&#228;&#224;&#237;&#232;&#229; &#236;&#229;&#230;&#228;&#243; &#231;&#224;&#239;&#240;&#238;&#241;&#224;&#236;&#232;*)
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;

AlexPC1
03.11.2010, 08:31
глюк случается на 6 или на 7 шаге если их исключить, тоесть в 5 шаге присваивать 0 то все работает