PUTBIT не совсем соответствует Вашему описанию задачи, либо её не правильно сформулировали, либо не заглядывали во внутрь DC32, потому что в лоджике есть PUTBIT
ЗЫ на катринке то, что я до этого написал в ST
Вид для печати
PUTBIT не совсем соответствует Вашему описанию задачи, либо её не правильно сформулировали, либо не заглядывали во внутрь DC32, потому что в лоджике есть PUTBIT
ЗЫ на катринке то, что я до этого написал в ST
capzap возможно, но работает так же как и в Лоджике DC32.
Допустил ошибку при копировании функции, сейчас проверю ваш вариант на ST для сравнения.
Что-то ваш вариант при входном значении 31 выдает 0
15 на входе должно в dword на выходе дать 1 в 15-м бите. число 32768, не выходит каменный цветок у функции почему-то
ага, уже разобрался. Почитал справку по SHL и заменил все на DWORD
Вот сижу, соображаю, как заставить свигаться биты по кругу, но не среди 8-ми битов, а по выбору, например среди 5-ти младших, и чтобы 5-й бит шел на 1-й..... ?
Следующая проблема... Когда размер файла созданного и редактируемого посредством SysLibFile становится 1кб (1024байт), данные в него перестают добавляться. Как можно решить эту проблему?
capzap может у меня хромает логика, но если эту же функцию написать с параметрами BYTE то вроде как должны значения меняться согласно входным переменным.
0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32, 6 = 64, 7 = 128, 8 = 1
однако 8 = 0 и так до 31, 32 = 1, то есть Codesys где-то кладет на BYTE и продолжает считать все через DWORD. Думаю с WORD будет та же петрушка. Или я где-то что-то не учитываю ?
capzap то, что 8 это 9-й разряд я понимаю, но это относится к word и dword. Суть то в другом, в работе функции битового сдвига SHL по отношению к BYTE а не по отношению к DWORD, что он делает постоянно, независимо от явного указания переменных. Вроде как 8 это уже разряд следующего байта и если параметр задан Byte то функция должна вернуться к началу. Ведь когда параметр DWORD и мы на вход подаем 32-й разряд функция возвращается в начало и на выходе ставит 1. И так по кругу. По отношению же к BYTE и WORD функция на это плюет. ИМХО - не логично.
capzap не путаю. Правильнее было бы в справочной информации по функции указать, что она работает только с DWORD. но это имхо.
Кстати ROL тоже с BYTE косячит, если не ошибаюсь... попробую проверить щас.
ROL так не косячит, 128 потом опять 1 и по кругу.
capzap читаем внимательно HELP
SHR
res:= SHR(in,n) Побитный сдвиг операнда in вправо на n бит с дополнением нулями слева.
Входные переменные и результат должны быть типа BYTE, WORD или DWORD.
Фактически SHL сдвигает не операнд, а регистр, который ессно 32-х разрядный. Маленькая, но ошибка в документации.
ROL и ROR соответственно честно работают с операндами.
Жаль что Вы не поняли о чем я намекал в предыдущем посте
capzap я понял на что вы намекали, что при 64-х разрядном ПЛК бит сдвигался бы от 0 до 63 позиций за счет разрядности регистра процессора. Ну так в HELP тогда так и надо указывать, что SHL и SHR сдвигают РЕГИСТР а не ОПЕРАНД. Нет ? я опять не прав и не умею читать по русски ?
Операнд in может иметь любой тип, вот он и сдвигается и если смещение вышло за разрядность то результат будет ноль, но так как больше 32 разрядов быть не может, то при смещении на 32 в байте снова появляется единица. Все правильно написано и работает так же
capzap только это не отражено в документации. я об этом. Намотаю на ус, больше все равно ничего не остается.
а при dword выход за разрядность почему не дает 0 ? :)
палка о двух концах, не находите ?
Дворд и так имеет по максимуму разрядность, вот и перескакивает на единицу. В лоджике как происходит этот процесс?
capzap в Лоджике нельзя жестко задать операндом BYTE, поэтому проверить реакцию не получится. Сами же об этом выше писали.
capzap Dword там ведет себя аналогично, при записи бита выше 31 не выдает 0, а идет по кругу.
Тут другая головная боль, как заставить биты крутиться не по 8-ми, а по 5-ти без расчета ручками. например мне надо сделать ротацию кондюков по времени из 5-ти устройств в режиме 3+2, при одном пороге температуры перейти на 4+1, при втором пороге запустить все 5. Так же при выводе одного опять же перейти на 4+1 с соблюдением порога температуры.
Когда BYTE весь полный (используем 8 устройств) проблем с ROL нет, а вот когда он неполный надо расчитывать на лету, и вот на лету у меня и не получается. Могу только жестко забить нужные значения например для 3+2. Более простого способа чем ROL как-то даже не придумаю... Разве что весь макрос от AI! перенести, но там тоже не все меня устраивает, хотя им проще управлять...
Еще один вопрос вспомнил, который хотел задать. Если я сделал библиотеку (функцию, блок) и всю ее переношу в Retain переменные, она полностью будет сохранять свои значения или надо заботиться именно о переменных, чтобы сохранить данные ?
Есть еще команда MOD она может помочь в таких делах
capzap не совсем понимаю, как он может помочь.
Использую маску по методу исключения, ну или можно инвертировать сигнал.
Например при штатном режиме 3+2 идут комбинации byte
3, 6, 12, 24 - потом должно идти 17 (первое и последнее устройство), потом опять 3 и так далее.
При переходе на режим 4+1 комбинация уже другая 1, 2, 4, 8, 16, 1.
А например вариант 3+3 (основной режим) уже вовсе
(3+3) 7, 14, 28, 56, 49, 35, 7
перешли на (4+2) 15, 30, 60, 57, 51, 39, 15
а на (5+1) 31, 62, 61, 59, 55, 47, 31
Я вот пока закономерности не особо вижу, как можно универсально написать, чтобы это все можно было менять на лету например через переменную ModBUS или еще как, не перепрошивая ПЛК.
Кое какая закономерность есть, только как ее применить, вопрос....когда 3 устр. в резерве, после двух старших битов (когда хвост ползет на начало) по MOD получается 7, 14, 28 (как инверсия 3 запущенных устройств)
когда 2 устр. в резерве то по MOD 3, 6, 12, 24
когда 1 устр. то по MOD 1, 2, 4, 8, 16
capzap спасибо, попробую разобраться в ST и как-то потом применить. Мне правда непонятно, почему MOD 31 ? в смысле непонятно, как расчитать это самое число для MOD
так, для данного примера с MOD 31 разобрался. но тут два устройства, не так сложно. а при 3-х два разных MOD надо будет как-то объединять...
Вот бы еще научиться ST примеры быстро переводить в CFС :), а то пока соображу как и чего ....
Из этого:
сделал вывод - melky не знает как работает SHL
Просто надо внимательно читать HELP (в данном случае :))
Ошибок нет. Все по чесному.Цитата:
Побитный сдвиг операнда in вправо на n бит с дополнением нулями слева...
А просто нужно имитировать работу проца. Например у вас регистр из 5 бит. Имитируем ROL на байте.Цитата:
как заставить биты крутиться не по 8-ми, а по 5-ти без расчета ручками.
b := ROL(b,1);
b.0 := b.5; он же - OF
b.5 := 0; и его нету как бы
Выбираем ПОУ. Правая кнопа. Конвертировать. FBD - кастрированный CFCЦитата:
ST примеры быстро переводить в CFС
Валенок я пытаюсь внимательно читать HELP и по моему мнению ОПЕРАНД это то, что на входе, для SHL в Codesys либо BYTE, либо WORD, либо DWORD.
И если при записи в DWORD значения 32 мы получаем на выходе 1 и идем по кругу
То логично предположить что и указав, что работаем с BYTE и записи на вход 8 тоже должны получить 1 на выходе
В обоих случаях происходит переполнение ОПЕРАНДА (нет такой "буквы" по счету в данном "слове").
Тут одно из двух, либо при работе с байтом и записи на входе 8 должна быть на выходе 1-ца, либо при работе с двойным словом и записи 32 на входе должен быть 0 на выходе.
Просто перевести не проблема, проблема адаптировать код ST к моим условиям, так как пример не имеет обвязки необходимой. В общем более менее разобрался с переводом в CFC
"Выбираем ПОУ. Правая кнопа. Конвертировать. FBD - карованный CFC"
Я бы не предложил фбд, там такой гемор начнется если джампов много
Я этой фразы вообще не понимаю. Изобразите вызов на чём-нибудь. С указанием типовЦитата:
И если при записи в DWORD значения 32 мы получаем на выходе 1 и идем по кругу
PS
Только щас заметил. SHL - нули справа. Но это мелочи
Для того чтоб по окончании разрядности типа данных увидеть снова единичку начиная с нулевого разряда существуют ROL/ROR-ы.И если уж Вы озаботились документацией на SHL, то что скажете про ADD, эффект то тот же (см. картинку). Правда я что то не вижу появляющуюся единицу, а вот единицу сместить на 32 в лево снова появилась
Тоже покопался.
Хелп - в норме. Компилятор на выхлопе - под вопросом.
Сформулирую так. Битовые сдвиги до занесения результата в память(переменную) реализуются через что-то типа внутреннего цикла c однократным сдвигом, но размер этого цикла перед операцией зачищается до модуля 32 (N <- N AND 31). Вот тут и порылось.
На это косвенно указывает и результат
2 <- SHL(1,33) или SHL(1,65). Т.е. SHL(1,1)
Более правильно было бы еще сначала сравнить N c 31. Если больше - сразу 0 и выход. А дальше - как есть
Немцам видимо не приходит в голову что русские будут за каким-то делать SHL более 31 раза для 32-битового регистра. На таком они и погорели. Тогда. Их парламентеры с Петровым И. переговоры ведут. Может сдадуцца. Всех с наступающим.
PS
А в атмеге нету типа SHL AX,CL ?
Валенок да вопрос то не в именно 32 на входе dword shl или 8 на входе byte shl а вообще в любом числе на входе.
когда shl dword происходит расчет бита по циклу на одном операнде и на выходе есть значение, а когда shl byte или word при превышении числа на выходе тупо 0.
функция одна, а работает на разных операндах по разному. вот разность и есть ошибка в логике. ИМХО.
кстати не проверял еще математические функции, но на примере сименса там проверку делает система, если идет перепонение, то можно контроировать по регистру произошло переполнение или нет.
а тут add считает по кругу а вот можно ли проверить или нет, не смотрел еще, может кто знает ?
Да это симулятор такой кривой. На ПЛК с SHL всё ок.
А по поводу retain переменных что скажете ?, если я всю библиотеку туда запихну, она будет сохранять все свои внутренние переменные ?
А по поводу Retain в справке достаточно ясно написано:
"Замечания. Если хотя бы одна переменная функционального блока объявлена как RETAIN, то все данные экземпляров целиком помещаются в энергонезависимый сегмент."
А для функций: "Внимание: объявление в функции RETAIN локальной переменной не приведет к желаемому результату. Не пытайтесь создавать локальные энергонезависимые переменные в функциях"
Вот как-то так...
YuriBel с объявлениями переменных понятно.
Я делаю FB без объявления переменных retain но сам FB объявляю как retain.
При этом симулятор мне пишет, что память retain не задана.
типа
VAR RETAIN
tr1: TRAB;
END_VAR
Внутри FB есть счетчики, арифметические выражения. Вот в таком варианте будут все данные FB попадать в Retain или все-таки необходимо заботиться о выносе переменных отдельно от FB ?
По идее должны все попадать.