Страница 156 из 400
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср сен 19, 2012 15:08:40
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 циклов
сделай хотя-бы как-то так:
;Задержка
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
чего касательно указателя стека, то в некоторых аврках он по умолчанию уже установлен на конец ОЗУ при аппаратном сбросе - читать даташит конкретно на 8-ю мегу влом

зазря народ асм ругает (ибо не всегда в полном объеме его знает

)
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср сен 19, 2012 16:21:39
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 писал(а):не всегда в полном объеме его знает
Да-да… Чтобы что-то ругать или
хвалить — это надо знать.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср сен 19, 2012 16:45:56
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
Всё на месте.
«И почему я почти не пишу на ассемблере?»™
Неужто только потому, что «не всегда его в полном объеме»?

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср сен 19, 2012 17:16:33
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$
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср сен 19, 2012 18:52:52
BOB51
... кххымм... ответ то не мне адресоваться должен, а КотЭ Мужчина...
боюсь с его начальным уровнем это перебор...
нужно чтоб человек сам понял, как и что делается - всего лишь подправить и подтолкнуть в нужном направлении, а не глушить сразу высшими вариантами оптимизации... да еще макросом по башке...
кстати о счетчиках - я-то вообще стараюсь на МК с конвеером выборки команд от таких конструкций задержек на кольцевых счетных регистрах уходить...

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср сен 19, 2012 19:20:11
Alexeyslav
Можно ведь было просто посмотреть значение temp1 во время симуляции, тогда было бы понятно почему зацикливается.
И вообще надо быть внимательным, когда пишешь надо думать почти как сам контроллер.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пт сен 21, 2012 08:42:35
КотЭ Мужчина
Все, комраден, заработало. Начало моргать, сволочь. После того как вписал
ldi r16,low(RamEnd);
out SPL,r16;
ldi r16,high(RamEnd);
out SPH,r16;
То есть когда проинициализировал оба стека. Спасибо, проблема решена. Тока больше не стоиг из меня беса гнать, комраден.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пт сен 21, 2012 17:49:22
BOB51
а мы бесов не гоним
стек -то один, и имеет имеет одно или двухбайтовый указатель (зависит от типа МК)

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 14:59:04
Челюскин
Дорогие Коты, помогите, пожалуйста разобраться вот с чем. запись такого плана:
sbic PIND, @0;
1. значок @ это всем знакомая "собака" или нет? в книге не очень на собаку похожа...
2. если нет, то где его найти?
3. зачем он вообще нужен и как это должно работать?(что, проверка пина порта Д???)
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 15:03:45
Gudd-Head
Челюскин писал(а):sbic PIND, @0;
Откуда эта запись? Вообще, на месте "@0" должна быть цифра от 0 до 7.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 15:16:16
Челюскин
ткуда эта запись?
книга "Микроконтроллеры АВР практикум для начинающих 2-е издание" В.Я. Хартов.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 15:18:01
Gudd-Head
Челюскин писал(а):книга "Микроконтроллеры АВР практикум для начинающих 2-е издание" В.Я. Хартов.

Это один из аргументов макроса.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 15:19:40
Челюскин
А как это вообще понимать-то? с какой стороны хотя-бы?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 15:23:40
Gudd-Head
Это одна из директив ассемблера. Почитайте, в книжке наверняка есть.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 16:24:46
Челюскин
Я кажись понял - автор пишет про МК семейства АТ90 у них вроде как система команд отличается. в смысле написания. если на прав, господа, жду уточнений.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 18:14:23
Engineer_Keen
Челюскин писал(а):Я кажись понял
Не-а
Как уже писали выше это кусок макроса.
Часто повторяемые части кода, в которых изменяется один или несколько аргументов объединяют в макросы. Макросы вызываются в соответствующем месте кода с параметром, а в самом макросе через "@" и число за ней, показывают в какое место макроса подставить этот параметр.
Как пример - простая версия распространенного макроса OUTI:
сам макрос
а если там где он вызывается написать:
то компилятор подставит туда:
И да, в той самой книжке это должно быть описано.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 21:16:30
ILYAUL
Вообще-то хорошо писать макросы B/B вот в такой форме
Код: Выделить всё
.macro outi
ldi temp,@1
.if ( @0 < 0x60 )
out @0,temp
.else
sts @0,temp
.endif
.endm
В данном примере прерпроцессор сам высчитывает адрес обращения и подставляет сам или
out или
sts/ В этом случае нет необходимости плодить для разных контроллеров свои макросы , а всегда применять один для всех
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн сен 24, 2012 22:09:06
Engineer_Keen
Да, именно этот вариант я всегда и использую. А тот что я привел - упрощенный, для примера.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт окт 04, 2012 08:46:47
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
Не пойму как сделать И-НЕ
И хотелось конкрено понять что писать конкретно в подобных случаях. Способы, варианты итд.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт окт 04, 2012 08:51:18
ploop
Считать один бит порта лучше командами SBRS port, bit или SBRC port, bit
Это команды перехода, если бит установлен или сброшен соответственно, т.е. не надо делать IN и накладывать маску.