Как "располовинить" DWORD?

Автор Izergill, 14 ноября 2016, 15:37:18

Izergill

Добрый день!
Из контроллера приходят данные: два слова, упакованные в одну переменную типа DWORD. Как можно извлечь эти две переменные?

Simple-Scada

#1
Здравствуйте.

Это можно сделать следующим скриптом:
Код: pascal
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := Word(varDWord.AsInt shr 16);
  aLowWord := Word(varDWord.AsInt);
end.

, где varDWord - переменная с контроллера, типа DWord, которую нужно разложить на слова. aHiWord - старшее слово. aLowWord - младшее слово. При этом не забывайте, что для корректной работы у DWord переменной должна быть выбрана шкала в Simple-Scada с диапазоном 0..4294967295. Типу данных DWord в Simple-Scada 2 соответствует тип LongWord.

Izergill

А возможно ли обратное преобразование: две переменные типа Word в одну типа LongWord?

Simple-Scada

Конечно, обратным способом:
Код: pascal
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := 1883;  // для примера
  aLowWord := 52501;  // для примера
  varDWord.Value := LongWord(aHiWord shl 16) or aLowWord;
end.

Izergill

Насколько я понимаю переменные aHiWord и aLowWord являются локальными для процедуры. А возможно ли "разобрать" переменную, которую мы берем из OPC и "половинки" присвоить внутренним переменным? И по какому событию это можно сделать?

Simple-Scada

Переменные с OPC-сервера мало чем отличаются от локальных переменных, поэтому здесь принцип такой же.

Из переменной OPC-сервера varDWord (тип LongWord) в две внутренние переменные varHiWord и varLowWord (типа Word):
Код: pascal
begin
  varHiWord.Value := Word(varDWord.AsInt shr 16);
  varLowWord.Value := Word(varDWord.AsInt);
end.

ЦитироватьИ по какому событию это можно сделать?
Лучше всего по изменению переменной varDWord, т.е. по событию OnDataChange. Сейчас для этого придется создать объект (например Поле), связать его с переменной varDWord, перейти к OnDataChange-скрипту этого объекта и вставить в него код, которые представлен выше. В будущем можно будет создавать OnDataChange скрипты без создания объекта.

Teodor

Цитата: Simple-Scada от 14 ноября 2016, 16:31:06Конечно, обратным способом:
Код: pascal
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := 1883;  // для примера
  aLowWord := 52501;  // для примера
  varDWord.Value := LongWord(aHiWord shl 16) or aLowWord;
end.
У меня сегодня подобная конструкция не срабтала ввиду провтыка LongWord()... пришлось срагулить:
Код: pascal
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := 1883;  // для примера
  aLowWord := 52501;  // для примера
  varDWord.Value := aHiWord*65536 + aLowWord;
end.