я бы приблизительный таймер на 3 часа делал вообще без прерываний и задержек - на WDT. тупо по сбросу ячейку памяти инкрементировал бы и все - строго линейный алгоритм, без прерываний а между сбросами наглухо усыплял бы МК.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Вы забыли, что после первого обнуления r19 в нем будет 0 и его маленький цикл уже не 142 раза прокрутится, а 256.
т.е. количество прогонов всего кода у вас будет равно 142 + 256, а не 142 + 142. а количество тактов надо считать соответственно - тут я не подскажу, ибо точно не помню, сколько тактов каждая команда занимает.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Даже если этот код загнать в студию, то можно пронаблюдать за количеством тактов на каждую команду. Декремент выполняется за один такт, также, как и присваивание. А вот команды ветвления (переходов) выполняются за один такт, если НЕ ВЫПОЛНЯЕТСЯ условие, и за два такта если ВЫПОЛНЯЕТСЯ условие, т.к. надо адрес (метку) перехода еще грузануть.
Итого. (расчет примерный). 2 такта на то, чтобы присвоить два значения переменным (регистрам Р18 и Р19). 1 такт на декремент 142 2 такта НА КАЖДЫЙ РАЗ на переход, т.к. условие у вас ВЫПОЛНЯЕТСЯ (флаг нулевого результата Z не равен нулю) И все это по кругу 142 раза. Т.е. 2+(3*142) = 428 Потом, как вам и сказал Роман, счет начинается уже не с 142, а с 256, т.к. новое значение никто не грузил в Р19. 1 такт на декремент Р18 (он стал равен 1) 2 такта на переход на метку Л1. И по новой 1 такт на декремент 256 2 такта на переход Итого 1+2+(3*256) = 771 428+771 = 1199.
Ах, да, там же еще декремент Р18 до нуля и выход из цикла. Вот и еще пара тактов.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Доброго времени суток! Пишу на Бейсике, но в Ассемблер "метнулся" из-за того, что программа уже на 96-98% забита (Atmega8). Причесываю, перечесываю и ужимаю ее не один день. Думал, часто повторяющуюся арифметику выполнить в ASM-блоке. Нашел в книге Ревича перемножение многобайтных чисел, чуть изменил под себя, прогнал в симуляторе Баскома... работает! НО! Как и большинство учебников и сайтов, ВЕЗДЕ практикуется ввод в регистры РОН готовых значений. А если в программе это/и значение/я меняются? У меня уже извилины выпрямились в одну линию от гор информации, литературы и попыток "направить" в регистр переменную . Подскажите, пожалуйста, кто понимает, по паре моментов: 1) Баском (2.0.7.5) упорно ругается 222-ой ошибкой на строку: !LDI R16 , Y Заносить готовые HEX-данные в регистр, с последующей обработкой и результатом - без проблем! А переменную (даже с объявлением через .def) не дает. Что не так? КАК отправлять переменную в регистр? 2) Конечный результат разнесен в 3-х регистрах. С директивой STS могу вынести за ASM-блок все три байта, объединить, "превратить" в число... Но, может быть, в Ассемблере имеется что-то короче для получения конечного (числового) результата из нескольких регистров? А иначе теряется смысл в этих танцах - результирующий код намного превышает код заменяемый.
P.S. Баском позволяет поместить переменную в фигурные скобки (правда, так и не нашел описания этим скобкам): !LDI R16 , {Y} Но все равно, в конечном итоге, в целевом регистре будет 0 и, следовательно, результат будет искажен.
_________________ О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
1) Баском (2.0.7.5) упорно ругается 222-ой ошибкой на строку: !LDI R16 , Y Заносить готовые HEX-данные в регистр, с последующей обработкой и результатом - без проблем! А переменную (даже с объявлением через .def) не дает. Что не так? КАК отправлять переменную в регистр?
X,Y,Z - существующие регистровые пары (R26-R31 или XH,XL,YH,YL,ZH,ZL), поэтому в качестве второго аргумента LDI их использовать некорректно. Попробуйте использовать другое, более осмысленное имя для переменной (ну или константы, раз LDI используется).
2) Конечный результат разнесен в 3-х регистрах. С директивой STS могу вынести за ASM-блок все три байта, объединить, "превратить" в число... Но, может быть, в Ассемблере имеется что-то короче для получения конечного (числового) результата из нескольких регистров? А иначе теряется смысл в этих танцах - результирующий код намного превышает код заменяемый.
Тут не понятно что конкретно нужно получить и как данные расположены. Например, имея 3 байта подряд можно выгадать 1 слово в программной памяти, используя ST X+,rn с предварительной загрузкой регистровой пары XH:XL начальным адресом (STS занимает 2 слова, а ST одно, но нужно потратить еще пару на LDI). Для оптимизации такого места нужно видеть весь код.
_________________ Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
X,Y,Z - существующие регистровые пары (R26-R31 или XH,XL,YH,YL,ZH,ZL),... ...более осмысленное имя для переменной (ну или константы...
А где Вы видите в моем примере использование старших регистров R26-R31? Осмысленные имена... Так и поступаю. Здесь "Y" вписал лишь для краткости. А константы... В процессе работы программы значение переменной, которую пытаюсь отправить в регистры, постоянно меняется.
Тут не понятно что конкретно нужно получить и как данные расположены. Например, имея 3 байта подряд можно выгадать 1 слово в программной памяти, используя ST X+,rn с предварительной загрузкой регистровой пары XH:XL начальным адресом (STS занимает 2 слова, а ST одно, но нужно потратить еще пару на LDI). Для оптимизации такого места нужно видеть весь код.
В Ассемблере у меня не то что первые шаги, а поползновения Так что с понятием "память" и использованием директив мне еще потеть и пыхтеть. Вот рабочий код, с ручной подстановкой данных (а-ля константа): СпойлерDim tmp1 As Byte Dim tmp2 As Byte 'data = 16 [$0010] 1-ый множитель 'koef = 2489 [$09B9] 2-ой множитель 'temp = 39824 [$9B90] -> ожидаемый результат !.def dataL = R4 ; $10 - младший разряд !.def dataH = R5 ; $00 - старший разряд !.def koefL = R2 ; $B9 - младший разряд !.def koefH = R3 ; $09 - старший разряд !.def tmp1 = R16 ; $90 - младший разряд !.def tmp2 = R17 ; $9B - старший разряд !ldi R24 , $10 !mov R4 , R24 !ldi R24 , $00 !mov R5 , R24 !ldi R24 , $b9 !mov R2 , R24 !ldi R24 , $09 !mov R3 , R24 !clr tmp2 ; очищаем старший разряд R18 !mul dataL , koefL ; умножаем младшие разряды => R4 * R2 => $09 * $13 = $AB => копируем в R0,R1 !mov tmp1 , R0 ; копируем R0 в мл. разр. результата R16 => $AB => R16 !mov tmp2 , R1 ; копируем R1 в ср. разр. результата R17 => $00 => R17 !mul dataH , koefL ; умножаем старший на младший => R5 * R2 => $01 * $13 = $13 => копируем в R0,R1 !add tmp2 , R0 ; складываем R17 и R0 => $00 + $13 = $13 => R17 !mul dataL , koefH ; умножаем младший на старший => R4 * R3 => $09 * $01 = $09 => копируем в R0,R1 !add tmp2 , R0 ; складываем R17 и R0 => $13 + $09 = 1C => R17 !mul dataH , koefH ; умножаем старший на старший => R5 * R3 => $01 * $01 = $01 => копируем в R0,R1 !sts {tmp1} , tmp1 !sts {tmp2} , tmp2
Dim tmp4 As String * 6 Dim tmp5 As Word tmp4 = Hex(tmp2) tmp4 = tmp4 + Hex(tmp1) ' $9B90 tmp5 = HexVal(tmp4) ' 39824 Результат разнесен по регистрам R16,R17. Их то я и вытаскиваю директивой STS и форматирую последними тремя строками. Это извлечение можно выполнить менее емким кодом?
По поводу переменной... Перед ASM-блоком разбил число поразрядно и пытался впихнуть в регистры (оба разряда тут присвоены одной переменной - это лишь для попытки "пропихивания")
Код:
Dim Y As String * 2 X = 2489 Y = Hex(High(X)) ' -> 09 Y = Hex(Low(X)) ' -> b9
Проблемка в том, что куда-то не туда увели меня танцы - 16-ричные результаты смог получить лишь для переменной String . В чем ошибка? Но полный тупик даже не в этом. В регистры пытался отправлять переменную ВСЕХ типов - и Ворд, и Лонг, и Байт,... Один ответ у Баскома - 222-ая ошибка.
_________________ О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Проблема больше в том, что все "высокоуровневые" компиляторы сами решают чего куда поместить... А вставка на ассемблере предусматривает прямое вмешательство в логику распределения ресурсов... Обязательно надо учитывать правила предварительного освобождения/резервирования тех ресурсов в "высокоуровневом", которые будут использованы вставкой на ассемблере. А там... у каждого компилятора свои правила... не всегда в явном виде указаны...
Не работал с баском, но гугль говорит что 222 это некорректный символ в команде, значит у вас что-то не то с "грамматикой". Код вы сначала не привели, откуда мне знать что "Y" был как пример? Привычный asm-компилятор АВР-студии за "LDI R16,Y" вполне закономерно послал бы вас с формулировкой "неправильное число". Привели бы конкретный пример на какую строчку ругается, может знатоки баскома наставят на путь истинный. Насколько я понял надо ассемблером умножить data (word) на koef (word) и результат получить в temp (должен быть dword, двух байт тут маловато). Может тут че поможет...
_________________ Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Не работал с баском, но гугль говорит что 222 это некорректный символ в команде...
Спасибо, конечно! Об ошибке я и сказал в первом сообщении. Подобная страница имеется и в скупой справке Баскома. Она изначально ничем не помогла. Там в регистр загружают или адрес переменной, или уже готовые значения. Но нет ничего (либо "не врубился") о загрузке самой переменной.
Привели бы конкретный пример на какую строчку ругается,...
Вообще-то , в самом начале и привел: LDI R16 , Y На нее и ругается. Полное ругательство: Illegal character [expected (, got '' [Y]] , in File.... Если верно понимаю, он ожидал открывающую скобку, а получил... ничего.
Насколько я понял надо ассемблером умножить data (word) на koef (word) и результат получить в temp (должен быть dword, двух байт тут маловато).
Поняли верно, но обратив внимание на разрядность множителей, согласитесь, что и Ворда хватает. Те, размерности, что использовал в коде - это почти потолок их значений, которые могут быть в программе. А конечный результат в 65535 (дес) или FFFF (hex) - в программе невозможен. И код (в моей проблеме) тот же самый. За исключением, что вместо готовых 16-ричных значений прописываю переменную. Какого бы типа ни была переменная (Word, Byte. String,...) - ругань одна и та же. Вот и возвращаюсь к вопросу: как в регистр загрузить переменную?
_________________ О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Так на LDI R16 , Y и ассемблер матюкнётся - LDI R16,k где k 0-255 (константа), но никак не зарезервированное имя регистровой пары Yh:Yl (R29:R28) (LD R16,Y к примеру - загрузка R16 из ячейки памяти по адресу указанному в Yh:Yl (R29:R28)). В принципе всегда рекомендуется избегать применения "зарезервированных имен" не по назначению!
Вообще-то , в самом начале и привел: LDI R16 , Y На нее и ругается. Полное ругательство: Illegal character [expected (, got '' [Y]] , in File.... Если верно понимаю, он ожидал открывающую скобку, а получил... ничего.
Ну так мы с ВОВ51 уже сказали что Y в LDI нельзя вторым аргументом писать, это имя регистра, а должна быть константа. Одной командой LDI в регистр переменную из RAM загрузить нельзя. Либо напрямую через LDS, либо через LD с индексными регистрами (X,Y,Z), по ссылке что я привел выше как раз пример. И за один раз одной ассемблерной командой больше чем байт не загрузить, для word надо два регистра и две команды загрузки, типа:
Код:
Dim A As word LOADADR a, X !Ld R16, X+ !Ld R17, X+
_________________ Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс июн 25, 2017 16:38:50
Мучитель микросхем
Карма: 2
Рейтинг сообщений: 10
Зарегистрирован: Ср окт 19, 2011 08:48:27 Сообщений: 443 Откуда: Мать городов русских
Рейтинг сообщения:0
Народ, кто разбирался с аппнотой AVR204: BCD Arithmetics - преобразование bin 2 bcd - не могу понять, каким образом оно работает - прибавляется к байту 0x03 - смотрится бит 3 и прибавляется к байту 0x30 и смотрится бит 7. Кто может, объясните.
_________________ Хорошему коту и в декабре - март
Эти <какие-то действия> уже на АСМ-е, и работают. Осталось останов и запуск таймера написать - тут уже заблудился. Литература только запутала, а поиск (в теме "Ассемблер для AVR") привел на 82 страницу, где mypkot останавливал таймер загрузкой нулей в регистр управления TCCR0. У TCCR0 используются только три младших разряда, и используются только как выбор источника и предделитель. Хотел бы убедиться, что верно понял... В моем случае (предделитель 1024) нижеследующая запись будет верна и работоспособна?
Разумеется, сохранение и возвращение SREG, PUSH-и и POP-ы имеются (убрал для краткости).
P.S. В железе не проверял - нет пока доступа к нему. Баском жалуется 377-ой ошибкой (Unexpected non numeric characters) на строку с присвоением двоичного числа, но молчит на 16-ричное.
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср июл 05, 2017 17:54:52
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Все верно, чтобы запустить таймер, надо указать источник тактирования.
Lavad писал(а):
Литература только запутала
На ДШ старайтесь налегать. На счет синтаксиса записи двоичного числа в Баскоме, то лучше сюда обратитесь. ---- Товарищ "Гугл" сказал мне, что синтаксис двоичных чисел имеет вот такой формат &b01010101, врет поди собака .
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Товарищ "Гугл" сказал мне, что синтаксис двоичных чисел имеет вот такой формат &b01010101, врет поди собака .
Только что проверил... Нет, не врет, данный вариант записи Баском проглотил молча. Спасибо за ответ, но, увы, не заработало Закоментировал свои 3 строки, вместо них вставил эти 6...
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт июл 06, 2017 07:33:24
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
"Все работает" или "не работает" слишком абстрактно. Что именно у Вас не работает? Я Баском не знаю. Но могу предложить сравнить во что компилируется Start Timer0 и не забывать про главный инструмент отладки - пошаговое выполнение.
Добавлено after 20 minutes 44 seconds: Тот же гугл говорит, что синтаксис шестнадцатеричных чисел имеет префикс &h. Вы смотрели что у Вас по факту пишется в регистры с префиксом $ ?
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Прерывание не работает. В прерывании, помимо прочего, проводится подсчет временнЫх интервалов (секунда, 2 сек., 5,...). Во внешних подпрограммах эти интервалы (переменные), помимо прочих операций, зажигают/тушат св/диоды. Вот по ним и сужу. Не мигают? Значит в прерывании не отмеряются временнЫе промежутки! Плюс, в самом начале программы проводится проверка состояния устройства. И если оно отличается от необходимой, то устройство останавливается и ждет вмешательства пользователя. Эта проверка также повязана с прерыванием. И, следовательно, устройство (программа) останавливается, даже не начав работу. Другими словами (так понимаю) - АСМ-код внутри этих 3-х злополучных строк вылизан, и работает, как часы.
Вы абсолютно правы! Из-за слабого знания Бейсика (и тем более Ассемблера) так и делаю. Пока переписывал прерывание на АСМ, чуть ли не после каждой новой команды прогонял в симуляторе. Но тут еще незнание всех возможностей симулятора, нехватка времени, да и подзабываю быстро
...что у Вас по факту пишется в регистры с префиксом $ ?
Это уже многократно пройденный этап. Работаю только в Баском. В его симуляторе содержимое регистров можно смотреть в 3-х видах: 10-тичное, 16-ричное и двоичное значения. В любом виде отображаются и обрабатываются корректные значения (если ввожу через $). Вопрос по поводу нерабочей команды "LDI R16 , 0b00000101" был лишь для познания. Вы сами же и дали верный ответ - "LDI R16 , $b00000101" 16-ричные данные ввожу через $, без h. Если число меньше 16, то и без $.
_________________ О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения