Просмотр полной версии : Глюк при записи по адресу
superqwerty
11.09.2008, 15:00
Обнаружил странное поведение программы при записи по некоторому адресу:
%QW256;
%QW257;
p0 := ADR(%QW256);
p1 := p0 + 2;
p2 := p1 + 2;
p0^ := 5; (* запишет *)
p1^ := 6; (* запишет *)
p2^ := 7; (* не запишет, т.к. адрес просто не указан в коде!!! *)
Почему не происходит запись по указателю p2? Если вверху дописать: %QW258; то все заработает.
Филоненко Владислав
11.09.2008, 20:43
Компилятор говорит о ошибке или значение переменной не меняется? Если второе - то какая переменная должна меняться? Запись, несомненно произойдёт. Но переменной то нет. Это место компилятор может использовать для своих нужд и тогда последствия такой записи вообще не предсказуемы.
Пришлите проект того, что бы Вам хотелось сделать. Может чего подскажем?
superqwerty
12.09.2008, 14:30
Компилятор говорит о ошибке или значение переменной не меняется? Если второе - то какая переменная должна меняться? Запись, несомненно произойдёт. Но переменной то нет. Это место компилятор может использовать для своих нужд и тогда последствия такой записи вообще не предсказуемы.
Пришлите проект того, что бы Вам хотелось сделать. Может чего подскажем?
Задача:
Для обмена данными между PLC и SCADA системой по modbus в PLC выделена некоторая область памяти (в моем случае - %QW256..%QW511). Хотелось автоматизировать процесс записи в эту память, например так:
UtInitBuf(ADR(%QB512), 512);
UtWriteWord(some_word_1);
UtWriteWord(some_word_2);
UtWriteWord(some_word_3);
UtWriteBit(some_bool_1);
UtWriteBit(some_bool_2);
UtWriteBit(some_bool_3);
Функция инициализации буфера:
FUNCTION UtInitBuf : BOOL
VAR_INPUT
buf : POINTER TO BYTE;
maxBytes : DWORD;
END_VAR
VAR
END_VAR
gUtBufPtr := buf;
gUtBufMaxBytes := maxBytes;
gUtByteNum := 0;
gUtBitNum := 0;
UtInitBuf := TRUE;
Функция записи в буфер:
FUNCTION UtWriteWord : BOOL
VAR_INPUT
value : WORD;
END_VAR
VAR
p : POINTER TO WORD;
END_VAR
IF (gUtBitNum > 0) THEN
gUtByteNum := gUtByteNum + 1;
gUtBitNum := 0;
END_IF;
IF (gUtByteNum + 2 > gUtBufMaxBytes) THEN
UtWriteWord := FALSE;
RETURN;
END_IF;
p := gUtBufPtr + gUtByteNum;
p^ := value;
gUtByteNum := gUtByteNum + 2;
UtWriteWord := TRUE;
Если использовать буфер в области данных контроллера, то все работает правильно:
buf : array [0..255] of byte;
UtInitBuf(adr(buf), 256);
UtWriteWord(1);
UtWriteWord(2);
UtWriteWord(3);
UtWriteBit(true);
UtWriteBit(false);
UtWriteBit(true);
...
А вот если передать в качестве буфера указатель на область modbus, то записывается значение только первого бита\байта\слова.
Стало интересно, почему?
Написал тестовую программу, она отлично компилируется и выполняется:
(* просто в коде указываем адреса первой и второй переменных в области modbus, адрес третьей не указываем *)
%QW256;
%QW257;
p0 := ADR(%QW256); (* указатель на первую *)
p1 := p0 + 2; (* указатель на вторую *)
p2 := p1 + 2; (* указатель на третью *)
p0^ := 5; (* записываем первую, SCADA читает ее по modbus и видит 5 *)
p1^ := 6; (* записываем вторую, SCADA читает ее по modbus и видит 6 *)
p2^ := 7; (* записываем третью, SCADA читает ее по modbus и видит 0!!! *)
Странно, пробуем так:
%QW258;
p0 := ADR(%QW256); (* указатель на первую *)
p1 := p0 + 2; (* указатель на вторую *)
p2 := p1 + 2; (* указатель на третью *)
p0^ := 5; (* записываем первую, SCADA читает ее по modbus и видит 5 *)
p1^ := 6; (* записываем вторую, SCADA читает ее по modbus и видит 0!!! *)
p2^ := 7; (* записываем третью, SCADA читает ее по modbus и видит 7!!! *)
Вывод - при записи в область modbus зачем-то необходимо явно указывать адрес.
Филоненко Владислав
12.09.2008, 15:14
А у Вас случаем не ограниченная лицензия?
superqwerty
12.09.2008, 17:03
Хм, ну у меня контроллер wago а также диск с wago IO pro 32, там codesys и таргеты. Как вроде бы лицензия только на среду выполнения надо, т.е. контроллер или soft plc?
Филоненко Владислав
12.09.2008, 20:23
А, ну так мы не знаем, насколько работоспособен Wago. Может бракованный экземпляр. Или память кончилась. Сколько у него памяти?
А что говорят в техподдержке Wago?
Интересно, у них есть русская техподдержка?
Малышев Олег
13.09.2008, 14:18
Я бы предположил, что скорее всего проблема выравнивании. Думаю, Тех поддержка Ваго Вам лучше поможет чем Овен.
superqwerty
15.09.2008, 09:46
Попробую узнать у ваго. Возможно это особенность codesys.
superqwerty
15.09.2008, 10:07
Обнаружен способ решения проблемы:
mem AT %QW256 : ARRAY [0..10] OF WORD;
mem[0] := 5;
mem[1] := 4;
mem[2] := 3;
mem[3] := 2;
mem[4] := 1;
и все работает
Всем спасибо за внимание :)
Powered by vBulletin® Version 4.2.3 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot