Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Мучитель микросхем
Сообщения: 443
Зарегистрирован: Ср окт 19, 2011 08:48:27
Откуда: Мать городов русских

Сообщение Frogfot »

Народ, кто разбирался с аппнотой AVR204: BCD Arithmetics - преобразование bin 2 bcd - не могу понять, каким образом оно работает - прибавляется к байту 0x03 - смотрится бит 3 и прибавляется к байту 0x30 и смотрится бит 7. Кто может, объясните.
Хорошему коту и в декабре - март :)
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

Доброго времени суток!
В одной из программ (Atmega8) имеется прерывание Таймера0:

Код: Выделить всё

Prertim:                        ' прерывание таймера Timer0
  Stop Timer0                   ' останавливаем Таймер0
    $asm
      <какие-то действия>
    $end asm
  timer0 = Timer0pre            ' начальная точка старта таймера
  Start Timer0                  ' запускаем Таймер0
Return
Эти <какие-то действия> уже на АСМ-е, и работают. Осталось останов и запуск таймера написать - тут уже заблудился. Литература только запутала, а поиск (в теме "Ассемблер для AVR") привел на 82 страницу, где mypkot останавливал таймер загрузкой нулей в регистр управления TCCR0. У TCCR0 используются только три младших разряда, и используются только как выбор источника и предделитель. Хотел бы убедиться, что верно понял...
В моем случае (предделитель 1024) нижеследующая запись будет верна и работоспособна?

Код: Выделить всё

Prertim:                            ' прерывание таймера Timer0
    $asm
      LDI R16 , 0b00000000
      OUT TCCR0 , R16               ' останавливаем Таймер0
      <какие-то действия>
      LDS R16 , {Timer0pre}
      OUT TCNT0 , R16               ' вернем начальную точку старта таймера
      LDI R16 , 0B00000101
      OUT TCCR0 , R16               ' запускаем Таймер0
    $end asm
Return
Разумеется, сохранение и возвращение SREG, PUSH-и и POP-ы имеются (убрал для краткости).

P.S. В железе не проверял - нет пока доступа к нему. Баском жалуется 377-ой ошибкой (Unexpected non numeric characters) на строку с присвоением двоичного числа, но молчит на 16-ричное.

Код: Выделить всё

      LDI R16 , 0b00000101     ' 377-ая ошибка
      LDI R16 , $5             ' молчание
Что упускаю?
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Все верно, чтобы запустить таймер, надо указать источник тактирования.
Lavad писал(а):Литература только запутала
На ДШ старайтесь налегать.
На счет синтаксиса записи двоичного числа в Баскоме, то лучше сюда обратитесь.
----
Товарищ "Гугл" сказал мне, что синтаксис двоичных чисел имеет вот такой формат &b01010101, врет поди собака ;).
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=3139176#p3139176"]На ДШ старайтесь налегать.[/uquote]Вот это и называю литературой (вкупе с книгами, журналами). А международный собачий я не знаю, от него меня коробит, да и поздновато для изучения.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3139176#p3139176"]Товарищ "Гугл" сказал мне, что синтаксис двоичных чисел имеет вот такой формат &b01010101, врет поди собака ;).[/uquote]Только что проверил... Нет, не врет, данный вариант записи Баском проглотил молча.
Спасибо за ответ, но, увы, не заработало :-( Закоментировал свои 3 строки, вместо них вставил эти 6...

Код: Выделить всё

Prertim:                            ' прерывание таймера Timer0
    $asm
      LDI R16 , $00
      OUT TCCR0 , R16               ' останавливаем Таймер0
      <какие-то действия>
      LDI R16 , $3d
      OUT TCNT0 , R16               ' вернем начальную точку старта таймера
      LDI R16 , $5
      OUT TCCR0 , R16               ' запускаем Таймер0
    $end asm
Return
Где ловить таракана?

P.S. Методом исключений добрался до 2-х последних АСМ строк (на запуск таймера). Если вместо них вернуть прежнее

Код: Выделить всё

Start Timer0
, то все работает. Почему?
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

"Все работает" или "не работает" слишком абстрактно. Что именно у Вас не работает?
Я Баском не знаю. Но могу предложить сравнить во что компилируется Start Timer0 и не забывать про главный инструмент отладки - пошаговое выполнение.

Добавлено after 20 minutes 44 seconds:
Тот же гугл говорит, что синтаксис шестнадцатеричных чисел имеет префикс &h. Вы смотрели что у Вас по факту пишется в регистры с префиксом $ ?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1368
Зарегистрирован: Вс мар 28, 2010 12:52:22
Откуда: Беларусь

Сообщение dr.doc »

преобразование bin 2 bcd
Когда-то изголялся...
Вложения
Пример BCD преобразования.rar
(8.3 КБ) 249 скачиваний
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=3139566#p3139566"]...Что именно у Вас не работает?[/uquote] :shock: Прерывание не работает. В прерывании, помимо прочего, проводится подсчет временнЫх интервалов (секунда, 2 сек., 5,...). Во внешних подпрограммах эти интервалы (переменные), помимо прочих операций, зажигают/тушат св/диоды. Вот по ним и сужу. Не мигают? Значит в прерывании не отмеряются временнЫе промежутки! Плюс, в самом начале программы проводится проверка состояния устройства. И если оно отличается от необходимой, то устройство останавливается и ждет вмешательства пользователя. Эта проверка также повязана с прерыванием. И, следовательно, устройство (программа) останавливается, даже не начав работу.
Другими словами (так понимаю) - АСМ-код внутри этих 3-х злополучных строк вылизан, и работает, как часы.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3139566#p3139566"]...главный инструмент отладки - пошаговое выполнение.[/uquote]Вы абсолютно правы! Из-за слабого знания Бейсика (и тем более Ассемблера) так и делаю. Пока переписывал прерывание на АСМ, чуть ли не после каждой новой команды прогонял в симуляторе. Но тут еще незнание всех возможностей симулятора, нехватка времени, да и подзабываю быстро :(
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3139566#p3139566"]...могу предложить сравнить во что компилируется Start Timer0...[/uquote]Поделитесь, пожалуйста. Может, что-то новое узнаю.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3139566#p3139566"]...что у Вас по факту пишется в регистры с префиксом $ ?[/uquote]Это уже многократно пройденный этап. Работаю только в Баском. В его симуляторе содержимое регистров можно смотреть в 3-х видах: 10-тичное, 16-ричное и двоичное значения. В любом виде отображаются и обрабатываются корректные значения (если ввожу через $). Вопрос по поводу нерабочей команды "LDI R16 , 0b00000101" был лишь для познания. Вы сами же и дали верный ответ - "LDI R16 , $b00000101" :)
16-ричные данные ввожу через $, без h. Если число меньше 16, то и без $.
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Прерывание не работает.
Не входит в обработчик прерывания или обработчик как-то неверно работает?
Lavad писал(а):Поделитесь, пожалуйста. Может, что-то новое узнаю.
Вы меня не поняли. В симуляции, выполняя работу по шагам, можно открыть окно дизассемблера и поглядеть во что скомпиллировлся оператор start timer. Коли у Вас тут только отличие в запуске таймера. А я уже сказал, баском я не знаю и тема тут не про него.
Lavad писал(а):каждой новой команды прогонял в симуляторе.
Вот и поставте точку останова перед выходом из прерывания и поглядите значения регистров отвечающих за таймер.

Правильно ли я понял, что цель ассемблерных вставок - это изучение ассемблера? Если это так, то Ваш подход неверен. Лучше напишите новый проект на ассеблере. Как правило - это мигание светодиодом для начала.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140007#p3140007"]Не входит в обработчик прерывания или обработчик как-то неверно работает?[/uquote]В железе еще не проверял, но, кажется нашел свою оплошность. Вход в обработчик прерывания имеется, а выход некорректен. Команды возврата точки старта таймера и его запуска я расположил не в самом конце обработчика (перед $end asm), а немного до него, перед пустышкой _exit. И совсем вылетело из головы, что полный или частичный проход обработчика происходит не всегда, в зависимости от ситуации. В моем случае происходил прыжок на _exit, без обработки добавленных команд. Следовательно, выходил из прерывания без запуска таймера, и второго прерывания уже не произойдет.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140007#p3140007"]...и поглядите значения регистров отвечающих за таймер.[/uquote]Если уж перед обработкой прерывания обнуляем регистр управления TCCR0, то может быть также следует поступать и со счетным регистром TCNT0? Т.е. обнулять и его. Ведь все равно в конце прерывания ему возвращается прежнее значение. Либо не возвращать значение потому, что все время обработки прерывания в нем так и лежит прежнее значение. Что посоветуете?
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140007#p3140007"]...что цель ассемблерных вставок - это изучение ассемблера?...[/uquote]Нет. Началось с того, что решил хоть как-то уменьшить занимаемый объем кода, заменив особо тяжелые или долгие процедуры АСМ-вставками. А изучение... это уже само собой происходит. Не вижу смысла использовать в своей разработке чужие примеры, не понимая их! Стараюсь писать сам. С разумной (удобоваримой) помощью только туговато.
И мигание св/диодами так же... само собой получилось :-)
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Я не предлагал Вам использовать чужие примеры, хотя в них бывают оригинальные алгоритмы и могут быть очень полезными.
Lavad писал(а):Что посоветуете?
Если Вам нужно попасть в прерывание наиболее точным интервалом времени, то вообще его не останавливать (но это все в зависимости от задачи).
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140143#p3140143"]Я не предлагал Вам использовать чужие примеры,...[/uquote]Чего это уже в штыки. :-) Я и не показывал на Вас пальцем :-). Это были мысли вслух о том, что стараюсь учиться.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140143#p3140143"]...хотя в них бывают оригинальные алгоритмы и могут быть очень полезными.[/uquote]Абсолютно согласен! Стараюсь, по мере извилин, их изучать.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140143#p3140143"]Если Вам нужно попасть в прерывание наиболее точным интервалом времени, то вообще его не останавливать (но это все в зависимости от задачи).[/uquote]Как раз наоборот. В прерывании отмеряются "точные" интервалы, а уж от них пляшет вся программа. Или я Вас не так понял?

У меня еще один вопрос возник. Если не трудно, помогите. В конце прерывания необходима команда RETI. Нет проблем! Return комментирую, RETI дописываю (это было несколько дней назад)... Первый же запуск программы привел ее в "неработоспособное" состояние. На дисплее замерло что-то половинчатое (от того, что могло быть там), сам дисплей сильно мерцал, НИ ОДНА кнопка не реагировала на нажатия. RESET-ы не помогали. Пришлось вернуть Return обратно. Что не так?
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Если бы штыки, то вставил бы какой-нибудь злой смайлик. Просто я дотошный зануда :)
Z_h_e писал(а):Как раз наоборот. В прерывании отмеряются "точные" интервалы, а уж от них пляшет вся программа. Или я Вас не так понял?
Вы вошли в прерывание. Выключили таймер. В прерывании торчали некоторое неизвестное время и опять запустили таймер. Зачем его останавливать если таймер только для генерации события для прерывания? Кстати ознакомтесь с режимом СТС таймера, скорее всего то что Вам надо. Правда в меге8 у таймер0 такого режима нет.
Lavad писал(а):Пришлось вернуть Return обратно. Что не так?
Это вопрос к Бейсику. Могу предположить. Комплиятор автоматически скомпиллил код в том числе для обработчика прерываний. Наверняка в начале обработчика идет сохранение некоторых данных на стек. Вы вставили команду reti, которая взяла адрес возврата со стека какой-то левый, так как SP указывает не на него.

Еще раз категорически советую, прежде чем писать вставки, напишите полностью несколько проектов на асме.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

Справочник по программированию «Bascom-AVR»:
Чтобы обеспечить возврат из программы обработки с разрешением прерываний следует применить команду микроконтроллера RETI. Компилятор делает это автоматически - первая команда RETURN, встретившаяся после метки с именем вектора прерывания скомпилируется как команда микроконтроллера RETI. Чтобы такая автозамена произошла в нужном месте, даже применяя ассемблер, необходимо завершить его текст оператором Bascom RETURN.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3140186#p3140186"]Справочник по программированию «Bascom-AVR»:...[/uquote]Спасибо! Это читал ни раз! Именно поэтому решил проверить RETI! Но дальше:
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3140186#p3140186"]..., встретившаяся после метки с именем вектора прерывания...[/uquote]выбивает мне все мозги :-(. Ноль понятия.
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

тут как раз всё понятно: если вошел по прерыванию - потом ищет ретурн, чтобы обратить его в рети, эту работу ты за него сделал, а у него счетчик не сбросился и ему "под руку" попадется другой ретурн...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140168#p3140168"]...Вы вошли в прерывание. Выключили таймер. В прерывании торчали некоторое неизвестное время...[/uquote]Дочитав до этого момента, дошло очевидное :-) Спасибо!
Тогда проверю другой вариант: не буду отключать/включать таймер в прерывании. Все равно прерывания каждые 200мс, а максимальный проход всего прерывания менее 8мс.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140168#p3140168"]...Кстати ознакомтесь с режимом СТС таймера...[/uquote]Вот придут заказанные 328-ые, тогда и углубимся.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140168#p3140168"]...Наверняка в начале обработчика идет сохранение некоторых данных на стек. Вы вставили команду reti, которая взяла адрес возврата со стека какой-то левый, так как SP указывает не на него.[/uquote]Если честно, то не понял, о чем речь. В начале обработчика идет сохранение регистра SREG и используемых РОН:
Спойлерpush r31
in r31 , sreg
push r31
push r0
push r16
и т.д..
И в конце возврат:
Спойлер...
pop r16
pop r0
pop r31
out sreg , r31
pop r31
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140168#p3140168"]Еще раз категорически советую, прежде чем писать вставки, напишите полностью несколько проектов на асме.[/uquote]Не спорю! Возможно, Вы правы. Начал заниматься асм-вставками на рабочей конструкции потому, что своими "потом и нервами" программу создал, знаю, на что она способна и что от нее ждать. Т.е., рассуждаю так: заменяя какую-то бейсиковскую строку на асм, я уже знаю предназначение и результат этой строки. Следовательно, экспериментируя на ассемблере, уже знаю точно, ЧТО должен в результате получить. Может, сумбурно, но как-то так :-)

Добавлено after 24 minutes 39 seconds:
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3140168#p3140168"]...прежде чем писать вставки, напишите полностью несколько проектов на асме.[/uquote]Если уж начинать с белого листа... Например, на 297-ой странице код программы... Все эти DSEG-и, CSEG-и, вектора прерываний, инициализация контроллера... (в начале программы). Можете посоветовать какую-то конкретную литературу или ссылку, где ДОСТУПНЫМ пониманию чайника об этом рассказывается?
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Курс DiHalt'а, цикл на Схем.нет. Я лично осваивал по Ревичу, но народ считает его не лучшим.
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 33
Зарегистрирован: Сб апр 20, 2013 22:56:52

Сообщение Lavad »

[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=3140263#p3140263"]Курс DiHalt'а, цикл на Схем.нет. Я лично осваивал по Ревичу,...[/uquote]Спасибо! К DiHalt-у время от времени наведываюсь. В данный момент пережевываю одну из его статей по работе с ЕЕПРОМ. Не сразу воспринимаю инфу, но, да, согласен с вами - лучше это, чем ничего.
Книга Котова - что-то знакомое... Видимо, последний визит был при царе Горохе. Ознакомлюсь.
Ревич... Имеются две "Практическое программирование МК Atmel AVR на Ассемблере", 2008 и 2011 годов. Вроде, читабельно. Только недавно начал.
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=3140263#p3140263"]...но народ считает его не лучшим.[/uquote]Спорный вопрос. То же самое мнение я много раз встречал о Белове. Как знать? Каждому по понятиям, что ли...
О человеке говорят не потоки изрыгаемых слов, а его дела и поступки.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Lavad писал(а):Если честно, то не понял, о чем речь. В начале обработчика идет сохранение регистра SREG и используемых РОН:

Что такое стек Вы уже знаете?
SP - это указатель стека.
PC - программый счетчик (счетчик команд)

Если МК выполняет вход в подпрограмму по команде call или уходит в обрабтчик прерывания, то он аппаратно сохраняет PC на стек (т.е. чтобы знать куда вернуться). SP уменьшается на размер занятых байт.

1) возникло событие от таймера. МК скинул адрес возврата на стек и ушел в обработчик прерывания.
2) Ваш язык верхнего уровня скомпиллил некий код. В начале входа в обработчик прерывания он скинул на стек некие регистры. При плохой степени оптимизации он скинул все регистры, даже неиспользуемые в обработчике. SP eще уменьшился
3) Потом Вы еще скинули на стек регистры, SP еще уменьшился
4) какой-то код
5) Вы восстановили регистры что скидывали на стек. SP увеличился до п.2
6') команда RETI. Берет адрес возврата из стека по адресу SP, SP увеличивается и загружает его в PC. Но SP не указывает на адрес возврата, МК прыгнул в неизвестное место программы.
6'') Оператор RETURN. Восстановил из стека данные из.п2. SP- теперь указывает на адрес возврата. Выполнил RETI.
...первая команда RETURN, встретившаяся после метки с именем вектора прерывания скомпилируется как команда микроконтроллера RETI. ...
Так что эта фраза из справочника некорректная или просто неполная.

Как я уже в третий раз говорю Баском не знаю, могут быть какие-то еще нюансы.

З.Ы. Я Вам не зря говорю, поглядите во что компиллятся операторы, сделайте это.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

это объяснение глюков мне больше нравится и понятно. — всё дело в нарушении очередноси извлечения данных из стека в случае прямого ассемблерного вмешательства.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Ответить

Вернуться в «AVR»