Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 11

Тема: Вопрос DWORD

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    По умолчанию Вопрос DWORD

    Здравствуйте,
    Вопрос у меня простой (даже стыдно спрашивать):
    1. Правильно ли для сложения 4 байтов в DWORD будет так (маска входов МВ110-32ДН):
    DiDwAddr172:=SHL(Buffer[3] + DWORD#0,24)OR SHL(Buffer[2] + DWORD#0,16) OR SHL(Buffer[1] + DWORD#0,8)OR Buffer[0];
    2.Как правильно разложить DWORD на 4 байта (маска выходов МВ110-32Р)?

  2. #2

    По умолчанию

    проще всего использовать указатель на байт.
    pby: POINTER TO BYTE;
    преобразование в arby: ARRAY[0..3] OF BYTE;
    pby:=ADR(dw);
    arby[0]:=pby^;
    arby[1]:=(pby+1)^;
    arby[2]:=(pby+2)^;
    arby[3]:=(pby+3)^;
    по второму пункту думаю сам догадаешься
    Последний раз редактировалось slonegd; 03.02.2017 в 08:18.

  3. #3

    По умолчанию

    Цитата Сообщение от slonegd Посмотреть сообщение
    проще всего использовать указатель на байт.
    pby: POINTER TO BYTE;
    преобразование в arby: ARRAY[0..3] OF BYTE;
    pby:=ADR(dw);
    arby[0]:=pby^;
    arby[1]:=(pby+1)^;
    arby[2]:=(pby+2)^;
    arby[3]:=(pby+3)^;
    по второму пункту думаю сам догадаешься
    а без указателей как-то можно???

  4. #4

    По умолчанию

    Можно, как раз с помощью логики и SHL, но мне такое читать сложнее. Даже не пытаюсь разобраться в том примере, что приведен. Вообще нет ничего проще в отладке проверить правильность написанного, и запихнуть в функцию, чтоб больше не вспоминать об этих тонкостях.

  5. #5

    По умолчанию

    Цитата Сообщение от slonegd Посмотреть сообщение
    Можно, как раз с помощью логики и SHL, но мне такое читать сложнее. Даже не пытаюсь разобраться в том примере, что приведен. Вообще нет ничего проще в отладке проверить правильность написанного, и запихнуть в функцию, чтоб больше не вспоминать об этих тонкостях.
    Насколько я правильно понял, ваш пример разлаживает двойное слово на байты, а не на оборот( и это ответ на мой второй вопрос)??????
    Последний раз редактировалось a_gricaj; 03.02.2017 в 12:11.

  6. #6

    По умолчанию

    Ну да, перепутал вопросы.
    Наоборот так:
    pby:=ADR(arby[0]); //получаем адрес первого элемента массива
    pdw:=pBy; //записываем адрес в указатель на dword
    dw:=pdw^; //сохраняем значение в dword

    здесь pdw: POINTER TO DWORD;

  7. #7

    По умолчанию

    Цитата Сообщение от slonegd Посмотреть сообщение
    Ну да, перепутал вопросы.
    Наоборот так:
    pby:=ADR(arby[0]); //получаем адрес первого элемента массива
    pdw:=pBy; //записываем адрес в указатель на dword
    dw:=pdw^; //сохраняем значение в dword

    здесь pdw: POINTER TO DWORD;
    подскажите пожалуйста почему компилятор тут ругается
    Безымянный.png

    вроде сделал как у вас
    Последний раз редактировалось a_gricaj; 03.02.2017 в 15:45.

  8. #8

    По умолчанию

    видимо нельзя записывать так: (TempPtB+1)^;
    (давно не писал подзабыл правила, компилятор всегда поправит)
    попробуйте так:
    TempPtB:=TempPtB+1;
    Buffer[1]:=TempPtB^;

    а вообще тут цикл напрашивается:
    TempPtB:=ADR(...);
    FOR i:=0 TO 3 DO
    Buffer[i]:=TempPtB^;
    TempPtB:=TempPtB+1;
    END_FOR

    PS я когда то так же организовывал связь по модбасу, использовал кейс и просто перебирал все адреса и регистры в сети. Жизнь научила, что некоторые вещи надо опрашивать быстрее (датчики положения), а некоторые реже (датчики температуры), а некоторые вообще только при изменении (в моих системах это му110-6у). А то выходило, что необходимо больше секунды жать кнопку ПУСК где-то на установке, чтоб до проги дошло, что её нажали.
    PPS лучше использовать не числовые константы в кейсе (16, 17), а создать список и ссылаться на него (WriteInBuffer, ModBusFunction16). В скобках это пример, мне не известен смысл записи в 17 шаге, возможно это установка частоты привода, тогда и называть по смыслу.

  9. #9

    По умолчанию

    Цитата Сообщение от slonegd Посмотреть сообщение
    видимо нельзя записывать так: (TempPtB+1)^;
    (давно не писал подзабыл правила, компилятор всегда поправит)
    попробуйте так:
    TempPtB:=TempPtB+1;
    Buffer[1]:=TempPtB^;

    а вообще тут цикл напрашивается:
    TempPtB:=ADR(...);
    FOR i:=0 TO 3 DO
    Buffer[i]:=TempPtB^;
    TempPtB:=TempPtB+1;
    END_FOR

    PS я когда то так же организовывал связь по модбасу, использовал кейс и просто перебирал все адреса и регистры в сети. Жизнь научила, что некоторые вещи надо опрашивать быстрее (датчики положения), а некоторые реже (датчики температуры), а некоторые вообще только при изменении (в моих системах это му110-6у). А то выходило, что необходимо больше секунды жать кнопку ПУСК где-то на установке, чтоб до проги дошло, что её нажали.
    PPS лучше использовать не числовые константы в кейсе (16, 17), а создать список и ссылаться на него (WriteInBuffer, ModBusFunction16). В скобках это пример, мне не известен смысл записи в 17 шаге, возможно это установка частоты привода, тогда и называть по смыслу.
    Спасибо так заработало:
    TempPtB:=ADR(DoDwAddr236);
    Buffer[3]:=TempPtB^;
    TempPtB:=TempPtB+1;
    Buffer[2]:=TempPtB^;
    TempPtB:=TempPtB+1;
    Buffer[1]:=TempPtB^;
    TempPtB:=TempPtB+1;
    Buffer[0]:=TempPtB^;
    Так можно писать маску в МУ110-32Р
    Я и в Кейсе делаю запись по изменению..., а вот "создать список и ссылаться на него" вы меня заинтересовали, если не трудно подробней пожалуйста - не понял что вы имеете ввиду...
    Последний раз редактировалось a_gricaj; 03.02.2017 в 17:00.

  10. #10

    По умолчанию

    Хорошим тоном в программировании является не использовать каких либо чисел. Ваши числа 16, 17 по сути константы из списка. Создайте перечисление в типах данных и назовите все ваши шаги(состояния) подпрограммы. Причем числа им присваивать не обязательно компилятор сделает сам. Предположим перечисление назовем State. Объявим тип вашего Step как перечисление. (Step: State Теперь Step может принимать только значения из перечисления. Если назвать элементы перечислений со смыслом, то можно избавиться от комментариев типа
    16: (*Запись*)
    Теперь эта строка будет выглядеть
    State.Write:
    А переход на новый шаг оформится так:
    Step:=State.MB16Func;
    Write и MB16Func - это просто примеры элементов из перечисления.
    Подобный подход делает код не только более понятным, но и предотвращает ошибки, когда вы случайно записываете в step какое-то не то значение или выходите за границы.

    Действие в 16 степе логично не делать отдельным шагом, а впихнуть в 17:
    17:
    IF NOT(WriteAddr236.Enable) THEN
    ;(*запись в буфер*)
    END_IF
    (*далее действие 17 как оно у вас*)
    Это так называемое входное действие, которое выполняется только один раз при переходе к этому шагу.
    Вообще есть в codesys SFC язык, который эту концепцию в графическом виде показывает. Сам не пробовал, но надо бы уже.

Страница 1 из 2 12 ПоследняяПоследняя

Похожие темы

  1. Операции с DWORD
    от Технос в разделе Панели оператора (HMI)
    Ответов: 1
    Последнее сообщение: 24.10.2016, 17:53
  2. DWORD + DWORD
    от Технос в разделе Панели оператора (HMI)
    Ответов: 19
    Последнее сообщение: 24.08.2016, 11:24
  3. ПЛК 63 - DWORD в конфигурации
    от melky в разделе ПЛК63/73
    Ответов: 3
    Последнее сообщение: 13.10.2015, 18:12
  4. REAL 2 DWORD СП270
    от kenny_sk8 в разделе ПЛК1хх
    Ответов: 1
    Последнее сообщение: 08.10.2012, 14:40

Ваши права

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