Ассемблер (ASM) для AVR в вопросах и ответах
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Чего-то непойму как без директив обойтись,так сказать,саму подноготную арифметики непонимаю.
как к 2-х байтовой переменной прибавляется 1-байтовая константа,
Почему-то не канает если так хочу прибавить 6:
subi REG_L, -6
sbci REG_H, 0
Это мягко говоря не совсем очевидено
как к 2-х байтовой переменной прибавляется 1-байтовая константа,
Почему-то не канает если так хочу прибавить 6:
subi REG_L, -6
sbci REG_H, 0
Это мягко говоря не совсем очевидено
В первый раз меня ударило током - и я подумал что ни черта не соображаю в электричестве. Во второй раз был аккуратнее и меня не ударило - теперь я возомнил из себя крутого микроэлектронщика.
- Реклама
Re: Ассемблер (ASM) для AVR в вопросах и ответах
У меня крокодил не ловиться,не растет кокос. Почему так?
P.S. А вроде понимать начал,это походу из-за того что я себе представляю число "-6" как однобайтное,
При этом пытаюсь его вычесть из двух байт. А надо приводить константу тоже в 2-х байтное значение.Это совсем не похоже на вычитание положительного значения. Нужно из старшей части не 0 вычитать,а -1.
Как-бы действительно не вполне очевидная вещь(и то до конца не понял
).
P.S. А вроде понимать начал,это походу из-за того что я себе представляю число "-6" как однобайтное,
При этом пытаюсь его вычесть из двух байт. А надо приводить константу тоже в 2-х байтное значение.Это совсем не похоже на вычитание положительного значения. Нужно из старшей части не 0 вычитать,а -1.
Как-бы действительно не вполне очевидная вещь(и то до конца не понял
В первый раз меня ударило током - и я подумал что ни черта не соображаю в электричестве. Во второй раз был аккуратнее и меня не ударило - теперь я возомнил из себя крутого микроэлектронщика.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Для двухбайтовых констант в пределах 0-63 лучше подходят команды
ADIW Rd+1:Rd,k (adiw rd,k) / SBIW Rd+1:Rd,k (sbiw rd,k) с регистровыми парами 25:24, 27:26, 29:28, 31:30

ADIW Rd+1:Rd,k (adiw rd,k) / SBIW Rd+1:Rd,k (sbiw rd,k) с регистровыми парами 25:24, 27:26, 29:28, 31:30
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ну это понятно,про такие команды мы знаем
,я немного про другое спрашивал:)) Разобрался вроде
Но все равно спасибо
Но все равно спасибо
В первый раз меня ударило током - и я подумал что ни черта не соображаю в электричестве. Во второй раз был аккуратнее и меня не ударило - теперь я возомнил из себя крутого микроэлектронщика.
- Реклама
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Здравствуйте, у меня есть некоторая проблема с переносом ассемблерной вставки bp CCG в AVR. Код взят по этой ссылке http://www.mikrocontroller.net/topic/292775, к слову этот код управляет диодами ws2812.
asm volatile(
" ldi %0,8 \n\t"
"loop%=:lsl %1 \n\t"
" dec %0 \n\t"
" sbi %2, %3 \n\t"
" brcs .+2 \n\t"
" cbi %2, %3 \n\t"
" brcc .+2 \n\t"
" cbi %2, %3 \n\t"
" brne loop%= \n\t"
: "=&d" (ctr)
: "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
);
До этого момента с ассемблером не сталкивался, по CCG мануалов достаточно, так что я разобрался, что происходит в коде, а по CVAVR куций хэлп и больше не нашел.
Вот что получилось у меня.
#asm
ldi r1,curbyte
ldi r2,ws2812_port
ldi r3,ws2812_pin
ldi r0,8
loop :
lsl r1
dec r0
sbi r2, r3
brcs PC+2
cbi r2, r3
brcc PC+2
cbi r2, r3
brne loop
// : "=&d" (ctr)
// : "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
#endasm
И если честно, даже прочитав Allocation of Variables to Registers в хэлпе я не понял, как правильно осуществляется доступ к глобальным переменным или в какой регистр и как их помещать, компилятор ругается. Где мне найти информацию и как правильно транслировать код в Code Vision?
И еще, тут: http://rurandom.org/justintime/index.ph ... _explained рассматривается какая-то более заковыристая реализация этой задачи, код координально рознится, какому стоит доверять?
asm volatile(
" ldi %0,8 \n\t"
"loop%=:lsl %1 \n\t"
" dec %0 \n\t"
" sbi %2, %3 \n\t"
" brcs .+2 \n\t"
" cbi %2, %3 \n\t"
" brcc .+2 \n\t"
" cbi %2, %3 \n\t"
" brne loop%= \n\t"
: "=&d" (ctr)
: "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
);
До этого момента с ассемблером не сталкивался, по CCG мануалов достаточно, так что я разобрался, что происходит в коде, а по CVAVR куций хэлп и больше не нашел.
Вот что получилось у меня.
#asm
ldi r1,curbyte
ldi r2,ws2812_port
ldi r3,ws2812_pin
ldi r0,8
loop :
lsl r1
dec r0
sbi r2, r3
brcs PC+2
cbi r2, r3
brcc PC+2
cbi r2, r3
brne loop
// : "=&d" (ctr)
// : "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
#endasm
И если честно, даже прочитав Allocation of Variables to Registers в хэлпе я не понял, как правильно осуществляется доступ к глобальным переменным или в какой регистр и как их помещать, компилятор ругается. Где мне найти информацию и как правильно транслировать код в Code Vision?
И еще, тут: http://rurandom.org/justintime/index.ph ... _explained рассматривается какая-то более заковыристая реализация этой задачи, код координально рознится, какому стоит доверять?
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Регистры r0-r15 c константами не работают, наверно по-этому компилятор ругается, с константами работают r16-r31, нужно заменить r0,r1,r2,r3 на какие нибудь из r16-r31, но какие из них использует компилятор в своих целях хз, так что с прогой в целом может произойти чтото непонятное, конфликт используемых регистров. Лучше все используемые регистры сохранить в стеке в начале вставки, а по завершении восстановить.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Я пытался засунуть их во все возможные регистры, все равно компилятор ругается, можно привести пример кода или рассказать, где можно посмотреть разбор похожего кода.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вроде успешно раскидал по регистрам, но выдает ошибку в sbi r22,r23, в r22 записан 0х15, адрес порта С для атмега8, в r23 0x04- 4й порт. Вот еще такой вопрос, если я закрою инлайновую вставку, напишу то же по функционалу выражение, скажем PORTC.4=1, потеряю ли я такты на его исполнение?
Последний раз редактировалось MINSK42 Ср окт 30, 2013 15:59:49, всего редактировалось 1 раз.
- Engineer_Keen
- Друг Кота
- Сообщения: 3871
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вы командой установки бита (от 0 до 7) пытаетесь установить бит с номером 23 (адрес регистра r23). SBI не предусматривает переменную в качестве второго аргумента, только константу. Да и первом аргументе должен быть прямой адрес, а не регистр. Так и пишите SBI PORTC,PC3MINSK42 писал(а):Вроде успешно раскидал по регистрам, но выдает ошибку в sbi r22,r23
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Получается, мне в сишной части нужно задать эти значения как константы и поместить их в соответствующие регистры r16-r31? что-то в стиле
register const char ws2812_pin=0x15 @16;
или же
const char ws2812_pin;
а потом в инлайновой вставке:
ldi r24,ws2812_pin
чтобы потом использовать sbi ?
Прямой адрес а не регистр? В примере " sbi %2, %3 \n\t", насколько я понимаю используется регистр.
register const char ws2812_pin=0x15 @16;
или же
const char ws2812_pin;
а потом в инлайновой вставке:
ldi r24,ws2812_pin
чтобы потом использовать sbi ?
Прямой адрес а не регистр? В примере " sbi %2, %3 \n\t", насколько я понимаю используется регистр.
- Engineer_Keen
- Друг Кота
- Сообщения: 3871
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Если у вас конкретный пин конкретного порта, не надо ничего определять, все уже должно быть определено просто пишите как есть SBI PORTC,PC3, если конечно адрес регистра попадает в дозволенный диапазон (иначе компилятор ругнется).
Если в диапазон не попадает, или нужно устанавливать произвольные биты произвольных портов, тогда придется использовать регистровые пары X,Y,Z и команды LD(S), ST(S).
Если в диапазон не попадает, или нужно устанавливать произвольные биты произвольных портов, тогда придется использовать регистровые пары X,Y,Z и команды LD(S), ST(S).
Re: Ассемблер (ASM) для AVR в вопросах и ответах
получается в CCG для использования значений из основного кода и вывода из инлайновой вставки используется
: "=&d" (ctr)
: "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
а в CVAVR можно напрямую обращаться к переменным?
Мне бы хотелось разобраться, чтобы в будущем подобные вопросы не возникали.
: "=&d" (ctr)
: "r" (curbyte), "I" (ws2812_port), "I" (ws2812_pin)
а в CVAVR можно напрямую обращаться к переменным?
Мне бы хотелось разобраться, чтобы в будущем подобные вопросы не возникали.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
SBI - дословно - "Set Bit I/O",это ИЛИ между значением в адресе и константой
SBI PORTC, 3 - означает Установить 3-й Бит РВВ портС, где вместо "PORTC",на самом деле компилятор подставит константу-адрес порта и вместо 3 на самом деле подставит (1<<3)
В случае если вы хотите переменную загонять в порт,то есть такие команды IN/OUT.
Допустим в R16 храним переменную - желаемое значение,которое должно попасть на ноги контроллера,
Делаем так:
OUT PORTC, R16 ;дословно: скопировать нафиг наружу из РОН r16 в РВВ портС
Если нужно с ножек что-то прочесть в РОН16,то делаем наоборот:
IN R16,PORTC
SBI PORTC, 3 - означает Установить 3-й Бит РВВ портС, где вместо "PORTC",на самом деле компилятор подставит константу-адрес порта и вместо 3 на самом деле подставит (1<<3)
В случае если вы хотите переменную загонять в порт,то есть такие команды IN/OUT.
Допустим в R16 храним переменную - желаемое значение,которое должно попасть на ноги контроллера,
Делаем так:
OUT PORTC, R16 ;дословно: скопировать нафиг наружу из РОН r16 в РВВ портС
Если нужно с ножек что-то прочесть в РОН16,то делаем наоборот:
IN R16,PORTC
В первый раз меня ударило током - и я подумал что ни черта не соображаю в электричестве. Во второй раз был аккуратнее и меня не ударило - теперь я возомнил из себя крутого микроэлектронщика.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Насколько склероз не изменяет "с ножек что-то прочесть" в данном случае будет in r16,PINCvek писал(а): OUT PORTC, R16 ;дословно: скопировать нафиг наружу из РОН r16 в РВВ портС
Если нужно с ножек что-то прочесть в РОН16,то делаем наоборот:
IN R16,PORTC
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ой
Ну,да 
В первый раз меня ударило током - и я подумал что ни черта не соображаю в электричестве. Во второй раз был аккуратнее и меня не ударило - теперь я возомнил из себя крутого микроэлектронщика.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ну вообще-то не совсем так, вместо PORTC компилятор на самом деле подставит адрес, а вот 3 так и запишет, ничего вместо нее не подставляя, вот кусок из assembler help'а:vek писал(а):SBI PORTC, 3 - означает Установить 3-й Бит РВВ портС, где вместо "PORTC",на самом деле компилятор подставит константу-адрес порта и вместо 3 на самом деле подставит (1<<3)
16-bit Opcode:
1001 1010 AAAA Abbb
где
10011010 - уникальный ID команды
ААААА - та самая константа-адрес порта
bbb - номер бита
видим, что под номер бита выделено всего три бита в коде команды (что логично, т.к. 8 было бы избыточно), поэтому туда запишется именно номер бита, а не результат сдвига (1 << 3), который занял бы 8 бит в коде.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добрый вечер.
Не могли бы Вы мне подсказать, где я ошибся.
Необходимо реализовать

У меня почему-то "0" на выходе только в одном случае: PA3 - "1", PA4 - "1", PA5 - "0". Во всех остальных случаях PC0 - "1"
Если в коде есть "тупейшие" ошибки, не судите меня строго, это моя первая программа.
Не могли бы Вы мне подсказать, где я ошибся.
Необходимо реализовать
Код: Выделить всё
;Мой код
.include "m8535def.inc" ;Подключение библиотеки контроллера AVR ATMega8535
.cseg ;Начало сегмента кода
.org 0 ;Начальный адрес программы
;Инициализация портов
ldi r16,$00
ldi r17,$FF
out DDRA,r16 ;Порт A на ввод
out DDRC,r17 ;Порт C на вывод
out PORTA,r17 ;Устанавливаем подтягивающий резистор на порт А
;Основная программа
main:
in r16,PINA
mov r17,r16
mov r18,r16
andi r16,$08 ;Выделение РА3 в r16
andi r17,$10 ;Выделение РА4 в r17
andi r18,$20 ;Выделение РА5 в r18
;Сдвигаем все переменные на 3-ий бит
lsr r18
lsr r18
lsr r17
mov r19,r16 ;Копирование значения из регистра r16, в регистр r19
and r19,r17 ;Выполняется логическое умножение (and - и) r19=r19*r17
andi r19,$08
com r19 ;Выполняется инверсия значения записанного в регистре r19
andi r19,$08
or r19,r18 ;Выполняется логическое сложение r19=r19+r18
andi r19,$08
;Сдвигаем значение регистра r19 на 3 бита вправо
lsr r19 ;
lsr r19 ;
lsr r19 ;
out PORTC,r19 ;Вывод результата из регистра r19 на порт C
rjmp main ;Возвращение на метку main
Если в коде есть "тупейшие" ошибки, не судите меня строго, это моя первая программа.
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Все правильно, так и должно быть.У меня почему-то "0" на выходе только в одном случае: PA3 - "1", PA4 - "1", PA5 - "0". Во всех остальных случаях PC0 - "1"
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Не "почему-то", а так и должно быть. Вы таблицу истинности-то составьте. 
Docendo discimus


