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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

во первых вложенные циклы так не делаются:

;Задержка

Delay: out PortB,Temp

ldi Temp1,0
ldi Temp2,5
ldi Temp3,4

Loop: dec Temp1; На этом месте отладка в Студии зависает, зацикливается
brne Loop; тут тоже виснет

dec Temp2
brne Loop

dec Temp3
brne Loop

ret

Во вторых - декремент нуля приведет к результату 0xff и вместо останова отмотать 255 циклов :cry:

сделай хотя-бы как-то так:

;Задержка

Delay:
out PortB,Temp

ldi Temp1,1
Loop2:
ldi Temp2,5
Loop1:
ldi Temp3,4

Loop:
dec Temp3
brne Loop

dec Temp2
brne Loop1

dec Temp1
brne Loop2

ret
:tea:
чего касательно указателя стека, то в некоторых аврках он по умолчанию уже установлен на конец ОЗУ при аппаратном сбросе - читать даташит конкретно на 8-ю мегу влом :sleep:
зазря народ асм ругает (ибо не всегда в полном объеме его знает 8) )
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

BOB51 писал(а):во первых вложенные циклы так не делаются:
Делаются. Просто надо "в полном объёме знать" ;)
BOB51 писал(а):Loop: dec Temp1; На этом месте отладка в Студии зависает, зацикливается
brne Loop; тут тоже виснет
Если так — то это её личные проблемы. В железе работает.
BOB51 писал(а):Во вторых - декремент нуля приведет к результату 0xff и вместо останова отмотать 255 циклов
Отлично, это и нужно. Тот первый цикл плюс оставшиеся 255 — это 256.
Скажем, нужно отмотать 512 циклов. Это как раз два раза по 256, в старший счётчик "троесчётчика" грузится 1, в средний 2, в младший 0.
А если 513, то в старший грузится 1 (два внутренних пройти 1 раз), в средний 3 (самый внутренний пройти три раза, один раз с начальным значением и еще два раза с 0, т.е. с 256), в младший грузится 1.

BOB51 писал(а):сделай хотя-бы как-то так:

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

;Задержка
   ldi Temp1,1
Loop2:
   ldi Temp2,5
Loop1:
   ldi Temp3,4
Loop:
     ; допустим, тут делаем импульс на ножке
   dec   Temp3
   brne Loop
   dec   Temp2
   brne Loop1
   dec   Temp1
   brne Loop2
   ret
Так тоже можно, конечно. Но через место, отмеченное комментарием «допустим, тут делаем импульс на ножке», этот «троецикл» пройдёт 4*5*1 = 20 раз. Зачем для этого три регистра?
Из-за того, что полное число проходов внутреннего цикла равно произведению загружаемых значений, таким способом можно получить только числа, раскладывающиеся на три множителя.

Такой цикл:

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

   ldi   r16, XXX
   ldi   r17, YYY
   ldi   r18, ZZZ
loop:
   dec   r16
   brne loop
   dec   r17
   brne loop
   dec   r18
   brne loop
отлично работает, даёт любые значения, а не только произведения трёх сомножителей.
Просто нужно правильно инициализировать. Я в бытность на 51-ом настолько часто такой цикл использовал, что у меня и для асма, и для С были макроса для загрузки начальных значений.
Для асма на AVR будет выглядеть как-то так (нотация avr-as из avr-binutils, идёт в комплекте с avr-gcc/WinAVR):

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

.macro ldcnt3 rg0, rg1, rg2, value
        ldi     \rg0, lo8( \value )
        ldi     \rg1, lo8( (\value+0xFF) >> 8 )
        ldi     \rg2, lo8( (\value+0xFFFF) >> 16 )
.endm

foo:
        ldcnt3 r16, r17, r18, 123456
loop:
        dec     r16
        brne loop
        dec     r17
        brne loop
        dec     r18
        brne loop
        ret

BOB51 писал(а):не всегда в полном объеме его знает
Да-да… Чтобы что-то ругать или хвалить — это надо знать.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

О, даже не так. Можно сделать универсальный макрос, загружающий заданные регистры. Хоть 2 счётчика последовательно, хоть четыре.

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

.macro ldcntm value, regs:vararg
        .set val_rest, \value
        .irp r, \regs
                ldi     \r, lo8( val_rest )
                .set val_rest, (val_rest + 0xFF) >> 8
        .endr
.endm

foo:
        ldcntm 123456, r16, r17, r18
1:
        dec     r16
        brne 1b
        dec     r17
        brne 1b
        dec     r18
        brne 1b

        ret

moo:
        ldcntm 1234, r16, r17
1:
        dec     r16
        brne 1b
        dec     r17
        brne 1b
        ret

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

0000002c <foo>:
  2c:   00 e4           ldi     r16, 0x40       ; 64
  2e:   13 ee           ldi     r17, 0xE3       ; 227
  30:   22 e0           ldi     r18, 0x02       ; 2
  32:   0a 95           dec     r16
  34:   f1 f7           brne    .-4             ; 0x32 <foo+0x6>
  36:   1a 95           dec     r17
  38:   e1 f7           brne    .-8             ; 0x32 <foo+0x6>
  3a:   2a 95           dec     r18
  3c:   d1 f7           brne    .-12            ; 0x32 <foo+0x6>
  3e:   08 95           ret

00000040 <moo>:
  40:   02 ed           ldi     r16, 0xD2       ; 210
  42:   15 e0           ldi     r17, 0x05       ; 5
  44:   0a 95           dec     r16
  46:   f1 f7           brne    .-4             ; 0x44 <moo+0x4>
  48:   1a 95           dec     r17
  4a:   e1 f7           brne    .-8             ; 0x44 <moo+0x4>
  4c:   08 95           ret

Первый цикл -- (2−1)×65536 + (227−1)×256 + 64 = 123456
Второй цикл -- (5−1)×256+210 = 1234
Всё на месте.

«И почему я почти не пишу на ассемблере?»™
Неужто только потому, что «не всегда его в полном объеме»? ;)
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Окончательный вариант макроса.
Ругается, если заданное число циклов не лезет в заданное число регистров:

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

.macro ldcntm value, regs:vararg
        .set val_rest, \value
        .irp r, \regs
                ldi     \r, lo8( val_rest )
                .set val_rest, (val_rest + 0xFF) >> 8
        .endr
        .if val_rest > 1
        .error "ldcntm: \value does not fit into \regs"
        .endif
.endm

foo:
        ldcntm 65536, r16, r17 ; Строка 13,  65536 проходов как раз максимум для двух байт
        ldcntm 65537, r16, r17 ; Строка 14, "не лізе"
        .end

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

real@realnb:~/temp$ avr-as cy.s
cy.s: Assembler messages:
cy.s:14: Error: ldcntm: 65537 does not fit into r16,r17
real@realnb:~/temp$
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

... кххымм... ответ то не мне адресоваться должен, а КотЭ Мужчина... :tea:
боюсь с его начальным уровнем это перебор... :cry:
нужно чтоб человек сам понял, как и что делается - всего лишь подправить и подтолкнуть в нужном направлении, а не глушить сразу высшими вариантами оптимизации... да еще макросом по башке... :shock:
кстати о счетчиках - я-то вообще стараюсь на МК с конвеером выборки команд от таких конструкций задержек на кольцевых счетных регистрах уходить... :tea:
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

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

Сообщение Alexeyslav »

Можно ведь было просто посмотреть значение temp1 во время симуляции, тогда было бы понятно почему зацикливается.
И вообще надо быть внимательным, когда пишешь надо думать почти как сам контроллер.
Аватара пользователя
КотЭ Мужчина
Открыл глаза
Сообщения: 64
Зарегистрирован: Ср июн 20, 2012 10:49:46
Откуда: Україна, Черкаська область
Контактная информация:

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

Сообщение КотЭ Мужчина »

Все, комраден, заработало. Начало моргать, сволочь. После того как вписал
ldi r16,low(RamEnd);
out SPL,r16;
ldi r16,high(RamEnd);
out SPH,r16;
То есть когда проинициализировал оба стека. Спасибо, проблема решена. Тока больше не стоиг из меня беса гнать, комраден.
Betelgeuse
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

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

Сообщение BOB51 »

а мы бесов не гоним :)
стек -то один, и имеет имеет одно или двухбайтовый указатель (зависит от типа МК) 8)
Челюскин
Прорезались зубы
Сообщения: 209
Зарегистрирован: Ср ноя 03, 2010 14:46:17

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

Сообщение Челюскин »

Дорогие Коты, помогите, пожалуйста разобраться вот с чем. запись такого плана:

sbic PIND, @0;

1. значок @ это всем знакомая "собака" или нет? в книге не очень на собаку похожа...
2. если нет, то где его найти?
3. зачем он вообще нужен и как это должно работать?(что, проверка пина порта Д???)
Лень - двигатель прогресса!
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

Челюскин писал(а):sbic PIND, @0;

Откуда эта запись? Вообще, на месте "@0" должна быть цифра от 0 до 7.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Челюскин
Прорезались зубы
Сообщения: 209
Зарегистрирован: Ср ноя 03, 2010 14:46:17

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

Сообщение Челюскин »

ткуда эта запись?

книга "Микроконтроллеры АВР практикум для начинающих 2-е издание" В.Я. Хартов.
Вложения
Picture 21.jpg
(21.81 КБ) 484 скачивания
Лень - двигатель прогресса!
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

Челюскин писал(а):книга "Микроконтроллеры АВР практикум для начинающих 2-е издание" В.Я. Хартов.

:facepalm: Это один из аргументов макроса.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Челюскин
Прорезались зубы
Сообщения: 209
Зарегистрирован: Ср ноя 03, 2010 14:46:17

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

Сообщение Челюскин »

А как это вообще понимать-то? с какой стороны хотя-бы?
Лень - двигатель прогресса!
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

Это одна из директив ассемблера. Почитайте, в книжке наверняка есть.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Челюскин
Прорезались зубы
Сообщения: 209
Зарегистрирован: Ср ноя 03, 2010 14:46:17

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

Сообщение Челюскин »

Я кажись понял - автор пишет про МК семейства АТ90 у них вроде как система команд отличается. в смысле написания. если на прав, господа, жду уточнений.
Лень - двигатель прогресса!
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

Челюскин писал(а):Я кажись понял

Не-а :))
Как уже писали выше это кусок макроса.
Часто повторяемые части кода, в которых изменяется один или несколько аргументов объединяют в макросы. Макросы вызываются в соответствующем месте кода с параметром, а в самом макросе через "@" и число за ней, показывают в какое место макроса подставить этот параметр.
Как пример - простая версия распространенного макроса OUTI:
сам макрос

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

.macro OUTI
LDI R16,@1
OUT @0,R16
.endm

а если там где он вызывается написать:

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

OUTI PORTA,0xFF

то компилятор подставит туда:

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

LDI R16,0xFF
OUT PORTA,R16

И да, в той самой книжке это должно быть описано.
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

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

Сообщение ILYAUL »

Вообще-то хорошо писать макросы B/B вот в такой форме

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

.macro   outi
   ldi   temp,@1
   .if ( @0 < 0x60 )
   out   @0,temp
   .else
   sts   @0,temp
   .endif
.endm

В данном примере прерпроцессор сам высчитывает адрес обращения и подставляет сам или out или sts/ В этом случае нет необходимости плодить для разных контроллеров свои макросы , а всегда применять один для всех
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

Да, именно этот вариант я всегда и использую. А тот что я привел - упрощенный, для примера.
Аватара пользователя
Coldheart
Прорезались зубы
Сообщения: 244
Зарегистрирован: Пт сен 10, 2010 20:39:32
Откуда: Украина Луганская обл.

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

Сообщение Coldheart »

Доброго времени суток УВ форумчане!
Подскажите как красиво записать вот такое условие в АСМЕ:
Есть к примеру порт D контроллера тини2313
Биты 0,1,2,3 сидят на общих катодах семисегментного индикатора.
Надо считать состояние Бит 4 порта D
Алгоритм думаю примерно такой:
1)Настраиваем 0123 на вывод остальные на вход.(ldi R16,0b00001111,
out DDRD,R16)
В некий момент обработки динамической индикации:
2)Счтываем весь порт D (in r16,pinD)
3)Делаем логическое И-НЕ между R16 и 0b00010000
4)Сравниваем r16 c 0b00010000
5)Если да, то уходим и выполняем некое условие
6)Делаем чтобы контроллер несколько раз не поподал в цикл опроса порта D(во избежание дребезга контактов)
7)Спустя некоторое время разрешем опрос порта D
Не пойму как сделать И-НЕ
И хотелось конкрено понять что писать конкретно в подобных случаях. Способы, варианты итд.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

Считать один бит порта лучше командами SBRS port, bit или SBRC port, bit
Это команды перехода, если бит установлен или сброшен соответственно, т.е. не надо делать IN и накладывать маску.
Ответить

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