Показано с 1 по 9 из 9

Тема: Глюк при записи по адресу

  1. #1

    По умолчанию Глюк при записи по адресу

    Обнаружил странное поведение программы при записи по некоторому адресу:

    %QW256;
    %QW257;

    p0 := ADR(%QW256);
    p1 := p0 + 2;
    p2 := p1 + 2;

    p0^ := 5; (* запишет *)
    p1^ := 6; (* запишет *)
    p2^ := 7; (* не запишет, т.к. адрес просто не указан в коде!!! *)


    Почему не происходит запись по указателю p2? Если вверху дописать: %QW258; то все заработает.

  2. #2

    По умолчанию

    Компилятор говорит о ошибке или значение переменной не меняется? Если второе - то какая переменная должна меняться? Запись, несомненно произойдёт. Но переменной то нет. Это место компилятор может использовать для своих нужд и тогда последствия такой записи вообще не предсказуемы.
    Пришлите проект того, что бы Вам хотелось сделать. Может чего подскажем?

  3. #3

    По умолчанию

    Цитата Сообщение от Филоненко Владислав Посмотреть сообщение
    Компилятор говорит о ошибке или значение переменной не меняется? Если второе - то какая переменная должна меняться? Запись, несомненно произойдёт. Но переменной то нет. Это место компилятор может использовать для своих нужд и тогда последствия такой записи вообще не предсказуемы.
    Пришлите проект того, что бы Вам хотелось сделать. Может чего подскажем?
    Задача:
    Для обмена данными между 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 зачем-то необходимо явно указывать адрес.

  4. #4

    По умолчанию

    А у Вас случаем не ограниченная лицензия?

  5. #5

    По умолчанию

    Хм, ну у меня контроллер wago а также диск с wago IO pro 32, там codesys и таргеты. Как вроде бы лицензия только на среду выполнения надо, т.е. контроллер или soft plc?

  6. #6

    По умолчанию

    А, ну так мы не знаем, насколько работоспособен Wago. Может бракованный экземпляр. Или память кончилась. Сколько у него памяти?
    А что говорят в техподдержке Wago?
    Интересно, у них есть русская техподдержка?

  7. #7

    По умолчанию

    Я бы предположил, что скорее всего проблема выравнивании. Думаю, Тех поддержка Ваго Вам лучше поможет чем Овен.

  8. #8

    По умолчанию

    Попробую узнать у ваго. Возможно это особенность codesys.

  9. #9

    По умолчанию

    Обнаружен способ решения проблемы:

    mem AT %QW256 : ARRAY [0..10] OF WORD;

    mem[0] := 5;
    mem[1] := 4;
    mem[2] := 3;
    mem[3] := 2;
    mem[4] := 1;

    и все работает

    Всем спасибо за внимание

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •