Как известно, TIA Portal использует косвенную адресацию, но, одновременно с этим, не запрещена и прямая адресация. Для этого в Data Block надо просто снять галочку в разделе Attributes под названием Optimized block access (это для версии TIA Portal V13 SP1).
В общем и целом адресация пародирует S7-200, только нет привычных нормальных команд (типа ANDB и т.д.), приходится обходиться тем, что есть в языке SCL.
Однако, и с этим оказались проблемы.
Описание проблемы я разместил на сайте Siemens.
Вот вам русское описание этого примера.
Я создал data block DB1 с именем "HMI_DB". Добавил в него 4 переменных:
var1 Real DB1.DBD0
var2 Real DB1.DBD4
var3 Word DB1.DBW8
var4 Word DB1.DBW10
Я хочу использовать HMI_DB.var3 и HMI_DB.var4 как буфер для моих операций пересылки байтов.
В частности, данная операция востребована при приёме и дальнейшем использовании данных по интерфейсу RS485, где данные принимаются по количеству слов данных.
Итак, я хочу передать два слова данных из HMI_DB.var1 в два отдельных слова HMI_DB.var3 и HMI_DB.var4, затем я хочу передать результат из var3 и var4 в переменную var2:
"HMI_DB".var1 := 24.7; // (для примера), это 16#41C5_999A
-------------
%DB1.DBW8 := %DB1.DBW0; // 16#41C5
%DB1.DBW10 := %DB1.DBW2; // 16#999A
%DB1.DBD4 := %DB1.DBD8; // (oops!) 16#4E83_8B33
Нежданчик! Программа автоматически конвертировала (DINT_TO_REAL), хотя никто этого не просил, значение 16#41C5_999A (что является 1,103,468,954 в DEC-формате) в 16#4E83_8B33 (что является 1.103469e+009 в Real-формате).
Если я напишу таким образом, то всё работает нормально:
%DB1.DBW4 := %DB1.DBW8;
%DB1.DBW6 := %DB1.DBW10;
Вот такая интересная система конвертации в TIA Portal, т.е. среда разработки как бы "знает", что %DB1.DBD4 имеет тип Real. Какая умная среда разработки, правда? Да, не совсем. Попробуем написать вот такое присвоение:
%DB1.DBD0 := 24.7;
И что мы видим? На такую запись компилятор отругался следующим сообщением:
Datatype "LReal" cannot be converted implicitly to datatype "DWord".
Вот так вот, т.е. компилятор "знает", что DBD - это Real и производит автоматическое преобразование из других форматов, когда его об этом не просят, ну, а когда такому DBD типа Real пытаешься напрямую присвоить число с плавающей точкой, вот тогда компилятор прикидывается шлангом и не может выполнить очевидное преобразование, сообщая, что DBD - это же DWord, а ему тут дробные числа, видите ли, подсовывают.
В обсуждении на форуме Siemens разъясняют, что компилятор просто не умеет автоматически преобразовывать LReal в DWord, т.е. число с плавающей точкой компилятор всегда понимает как LReal, а если его присваивают переменной типа Real, то автоматом происходит преобразование LREAL_TO_REAL. Таким образом, для присвоения DWord дробного числа требуется два поочерёдного преобразования: LREAL_TO_REAL, а затем - REAL_TO_DINT, чего компилятор делать автоматически не умеет.
В общем и целом адресация пародирует S7-200, только нет привычных нормальных команд (типа ANDB и т.д.), приходится обходиться тем, что есть в языке SCL.
Однако, и с этим оказались проблемы.
Описание проблемы я разместил на сайте Siemens.
Вот вам русское описание этого примера.
Я создал data block DB1 с именем "HMI_DB". Добавил в него 4 переменных:
var1 Real DB1.DBD0
var2 Real DB1.DBD4
var3 Word DB1.DBW8
var4 Word DB1.DBW10
Я хочу использовать HMI_DB.var3 и HMI_DB.var4 как буфер для моих операций пересылки байтов.
В частности, данная операция востребована при приёме и дальнейшем использовании данных по интерфейсу RS485, где данные принимаются по количеству слов данных.
Итак, я хочу передать два слова данных из HMI_DB.var1 в два отдельных слова HMI_DB.var3 и HMI_DB.var4, затем я хочу передать результат из var3 и var4 в переменную var2:
"HMI_DB".var1 := 24.7; // (для примера), это 16#41C5_999A
-------------
%DB1.DBW8 := %DB1.DBW0; // 16#41C5
%DB1.DBW10 := %DB1.DBW2; // 16#999A
%DB1.DBD4 := %DB1.DBD8; // (oops!) 16#4E83_8B33
Нежданчик! Программа автоматически конвертировала (DINT_TO_REAL), хотя никто этого не просил, значение 16#41C5_999A (что является 1,103,468,954 в DEC-формате) в 16#4E83_8B33 (что является 1.103469e+009 в Real-формате).
Если я напишу таким образом, то всё работает нормально:
%DB1.DBW4 := %DB1.DBW8;
%DB1.DBW6 := %DB1.DBW10;
Вот такая интересная система конвертации в TIA Portal, т.е. среда разработки как бы "знает", что %DB1.DBD4 имеет тип Real. Какая умная среда разработки, правда? Да, не совсем. Попробуем написать вот такое присвоение:
%DB1.DBD0 := 24.7;
И что мы видим? На такую запись компилятор отругался следующим сообщением:
Datatype "LReal" cannot be converted implicitly to datatype "DWord".
Вот так вот, т.е. компилятор "знает", что DBD - это Real и производит автоматическое преобразование из других форматов, когда его об этом не просят, ну, а когда такому DBD типа Real пытаешься напрямую присвоить число с плавающей точкой, вот тогда компилятор прикидывается шлангом и не может выполнить очевидное преобразование, сообщая, что DBD - это же DWord, а ему тут дробные числа, видите ли, подсовывают.
В обсуждении на форуме Siemens разъясняют, что компилятор просто не умеет автоматически преобразовывать LReal в DWord, т.е. число с плавающей точкой компилятор всегда понимает как LReal, а если его присваивают переменной типа Real, то автоматом происходит преобразование LREAL_TO_REAL. Таким образом, для присвоения DWord дробного числа требуется два поочерёдного преобразования: LREAL_TO_REAL, а затем - REAL_TO_DINT, чего компилятор делать автоматически не умеет.