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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
gauss
Держит паяльник хвостом
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

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

Сообщение gauss »

Добрый вечер.
Небольшой вопрос по обучалке:

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

ReadArray:
          ldi ZH,High(MyArray*2) ;загрузка адреса 0-го
          ldi ZL,Low(MyArray*2)  ;элемента в рег. пару Z

          ldi Temp1,0
          add ZL,Temp          ;прибавление
          adc ZH,Temp1         ;внутр. адреса

          lpm                  ;загрузка из ПЗУ

          mov Temp1,R0         ;копирование
          out PortB,Temp1      ;вывод в порт
          inc Temp             ;увелич. внутр. адреса
          rjmp ReadArray       ;в начало цикла

MyArray:
.db 12,16,3,4,10,17,255,37,158,14,13,98
.db 14,85,30,9,145,52,64,49,119,72,209,46


Помещаем в регистровую пару Z адрес нашего массива, затем к регистру ZL прибавляем смещение,
складываем с учетом переполнения с регистром ZH и с помощью команды lpm загружаем то что нужно из массива.

Вопрос состоит в том, можно ли инициализировать пару один раз, а затем после каждого считывания инкрементить ZL и в следующей
итерации считывать уже другое значение. Будет ли работать или нет?

П. С: представляю себе примерно так:

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

          ldi ZH,High(MyArray*2) ;загрузка адреса 0-го
          ldi ZL,Low(MyArray*2)  ;элемента в рег. пару Z, инициализировано где-то выше
ReadArray:
          lpm                  ;загрузка из ПЗУ

          mov Temp1,R0         ;копирование
          out PortB,Temp1      ;вывод в порт
          inc ZL                    ;увеличили смещение
          breq INCZH             ;если переполнилось ZL то переходим и инкрементим ZH
          rjmp ReadArray       ;в начало цикла
          INCZH:
          inc ZH
          rjmp ReadArray

MyArray:
.db 12,16,3,4,10,17,255,37,158,14,13,98
.db 14,85,30,9,145,52,64,49,119,72,209,46
:idea:
Аватара пользователя
Seriyvolk
Друг Кота
Сообщения: 4961
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

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

Сообщение Seriyvolk »

Всё делается проще:

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

 ReadArray:
LPM Temp1,Z+
 out PortB,Temp1
rjmp ReadArray
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

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

Сообщение Engineer_Keen »

Помимо того, что сказал Seriyvolk...


gauss писал(а):П. С: представляю себе примерно так:

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

          inc ZL                    ;увеличили смещение
          breq INCZH             ;если переполнилось ZL то переходим и инкрементим ZH
          rjmp ReadArray       ;в начало цикла
          INCZH:
          inc ZH
          rjmp ReadArray

Для регистровых пар удобнее все-таки пользоваться командами ADIW/SBIW (если изменять нужно не на 1)

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

 ReadArray:
LPM Temp1,Z
 out PortB,Temp1
ADIW ZH,ZL,4
rjmp ReadArray
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Аватара пользователя
gauss
Держит паяльник хвостом
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

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

Сообщение gauss »

Понятно, спасибо.

Пока писал код, возник вопрос про выбор нужного массива.
Скажем, имеется набор массивов:

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

Array1:
.db 59,59,12,14,64,69,49,23
Array1:
.db 59,59,12,14,64,69,49,23
;....
ArrayN:
.db 59,59,12,14,64,69,49,23  ;;цифры просто для примера, попросту говоря будут массивы из некоторого количества однобайтовых элементов


Все массивы описаны в некой таблице:

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

Table:
.dw Array1, Array2, /*.....*/, ArrayN


Просто в голове рисуется какой-то сложный алгоритм их обработки:

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

Function:  ;некоторая функция, загружающая нужное значение из нужного массива
clr r16
ldi ZL,low(Table*2)
ldi ZH,high(Table*2)
lsl selector ;;selector - некоторый регистр, в котором находится номер нужной таблицы, умножаем на 2,
;;чтобы получить реальный адрес нужного массива
add ZL,selector
adc ZH,r16
lpm r16,Z+
lpm r17,Z
movw ZH:ZL, r17:r16
;по идее, загрузили адрес нашего массива, теперь этот адрес находится в ZH:ZL
clr r16
add ZL,counter ;;counter отвечает за выбор нужного элемента массива
adc ZH,r16
lpm
mov r16,r0 ;теперь в r16 находится нужный элемент
ret


Сегдня так попробовал и не получилось :( В чем может быть косяк?
:idea:
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Вы получили в ZH:ZL адрес начала текущего массива и перед чтением командой LPM должны его умножить на 2.

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

   movw ZH:ZL, r17:r16

   LSL   ZL
   ROL   ZH

По мне, можно обойтись без адресов Table, а selector сразу умножать на длину массива. При этом принять, что длина всех массивов одинакова.
Спойлер

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

.def   SELECTOR=R22
.def   counter=R23

Table:
;   .dw Array0, Array1, Array2, ArrayN

Array0:
.db 1,2,3,4,5,6,7,8
Array1:
.db 11,12,13,14,15,16,17,18
Array2:
.db 21,22,23,24,25,26,27,28
;....
ArrayN:
.db 31,32,33,34,35,36,37,38  ;;цифры просто для примера,
; попросту говоря будут массивы из некоторого количества однобайтовых элементов


TEST_MASSIV:
Function:  ;некоторая функция, загружающая нужное значение из нужного массива
   clr r16
   ldi ZL,low(Table*2)
   ldi ZH,high(Table*2)

   lsl selector
   lsl selector
   lsl selector
   
   add ZL,selector
   adc ZH,r16

   add ZL,COUNTER
   adc ZH,r16

   lpm   r16,z ;теперь в r16 находится нужный элемент
;   RJMP   Function
   ret
Аватара пользователя
gauss
Держит паяльник хвостом
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

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

Сообщение gauss »

akl, позвольте уточнить: вы используете тот факт, что количество массивов
известно и что таблица идет до массивов?
:idea:
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Вы их прописали, значит их число известно. Обратите внимание, что строка адресов массивов закомментирована, т.е. адрес Table и Array0 совпадают.

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

Table:
;   .dw Array0, Array1, Array2, ArrayN
Array0:
Аватара пользователя
gauss
Держит паяльник хвостом
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

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

Сообщение gauss »

akl, теперь я понял, почему так, спасибо. Вот только
можно ли применить такой подход, если массивов много(около 15), и в каждом около двух-
сот элементов?
:idea:
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Почему бы и нет. Увеличить разрядность selector до регистровой пары и всё. Можно ещё до кучи при формировании его значения увеличивать сразу на величину размера Array. Тогда не нужно будет умножать. Т.е. selector=0*Array, selector=1*Array, selector=2*Array, и т.д.
Аватара пользователя
gauss
Держит паяльник хвостом
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

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

Сообщение gauss »

Теперь окончательно разобрался, спасибо :beer:
:idea:
Аватара пользователя
xkp
Опытный кот
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров
Контактная информация:

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

Сообщение xkp »

подскажите как? или вообще можно ли? установить приоритет прерывания EXT_INT0 над tim0_ovf, то есть если мы находимся в данный момент в прерывание по переполнению Т0 (tim0_ovf) и пришло прерывание по внешнему импульсу (EXT_INT0), то надо прыгнуть в прерывание по внешнему импульсу а после его выполнения, естественно, вернуться обратно в tim0_ovf. Микроконтроллер atmega8.
кусок кода инициализации прерываний
Спойлер

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

   ldi tmp,(1<<isc11)|(1<<isc10)|(1<<isc01)|(1<<isc00)
   out mcucr,tmp
   ldi tmp,(0<<int1)|(1<<int0)
   out gicr,tmp
   ldi tmp,(1<<toie0)
   out timsk,tmp
   ldi tmp,(0<<CS02)|(1<<CS01)|(0<<CS00)   ;преддилитель 8
   out tccr0,tmp

таблица прерываний
Спойлер

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

;INTERRUPT VECTORS
   rjmp reset            ; Reset Handler
   rjmp EXT_INT0          ; IRQ0 Handler
   reti               ;   rjmp EXT_INT1 ; IRQ1 Handler
   reti               ;rjmp TIM2_COMP ; Timer2 Compare Handler
   reti               ;rjmp TIM2_OVF ; Timer2 Overflow Handler
   reti               ;rjmp TIM1_CAPT            ;Timer1 Capture Handler
   reti               ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
   reti               ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
   reti               ;rjmp TIMPINC 4 191_OVF   ;Timer1 Overflow Handler
   rjmp look            ;tim0_ovf ; Timer0 Overflow Handler
   reti               ;rjmp SPI_STC ; SPI Transfer Complete Handler
   reti               ;rjmp USART_RXC ; USART RX Complete Handler
   reti               ;rjmp USART_UDRE ; UDR Empty Handler
   reti               ;rjmp USART_TXC ; USART TX Complete Handler
   reti               ;rjmp ADC_inc ; ADC Conversion Complete Handler
   reti               ;rjmp EE_RDY ; EEPROM Ready Handler
   reti               ;rjmp ANA_COMP ; Analog Comparator Handler
   reti               ;rjmp TWSI ; Two-wire Serial Interface Handler
   reti               ;rjmp SPM_RDY ; Store Program Memory Ready Handler
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

в самом начале "высокоприоритетного" обработчика прерываний разрешите прерывания командой sei
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
xkp
Опытный кот
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров
Контактная информация:

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

Сообщение xkp »

они разрешены. там дальше в программе стоит sei. но дело в том что когда мк находится в прерывании tim0_ovf то в прерывание по внешнему сигналу мк идет только после отработки tim0_ovf и выхода из него. а мне надо что бы прерывание по внешнему сигналу всегда отрабатывалось непосредственно в тот момент когда приходит внешний сигнал. а сейчас получается если внешний сигнал приходит во время обработки прерывания по переполнению Т0, то получается задержка в количестве тактов, необходимых для обработки Т0.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

второй раз вам говорю: в обработчике прерываний Т0 сразу, как только можно, поставьте sei
я первый раз непонятно высказался?

если вы это сделаете, то прерывание от INT0 (или какое там у вас внешнее) сможет обработаться еще до завершения процедуры обработки прерывания T0
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
xkp
Опытный кот
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров
Контактная информация:

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

Сообщение xkp »

Извиняюсь. Не правильно понял. Спасибо. Заработало.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
harrd
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Ср апр 01, 2009 17:52:51

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

Сообщение harrd »

Здравствуйте, уважаемые. Очень надеюсь на вашу помощь. Делаю преобразователь 12/220, 50 Гц с синусом на выходе. Подобие синуса хочу формировать микроконтроллером. Дело такое, есть attiny2313, требуется выводить последовательно на разные выводы последовательность байт ( ШИМ, чтобы создать грубое подобие синусоиды вида "0010110111011111101110110100", это верхний полупериод (пойдёт на один ключ полумоста), аналогично на другой пин будет выведено тоже самое для нижнего полупериода. Похожих решений нигде не нашёл, поэтому прошу помощи, как примерно реализовать программу (на Cи или ассемблере). Чтобы не связываться с таймерами, чем проще, тем лучше. AVR будет только формировать ШИМ.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

Установили вывод "1"
Подождали
Установили вывод "0"
Подождали
...
Всё сначала.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

harrd А почему Вы решили что без таймеров будет проще? С таймерами тоже просто.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

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

Сообщение Pink-Pank »

Самым простым будет сформировать меандр и пропустить его через пару звеньев RC-фильтра
Fucking static initialization order fiasco
harrd
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Ср апр 01, 2009 17:52:51

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

Сообщение harrd »

Как раз пропускать через фильтр смысла нет, мне нужен чистый ШИМ, для подачи на силовые ключи
Ответить

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