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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Muzykant
Нашел транзистор. Понюхал.
Сообщения: 192
Зарегистрирован: Вт дек 24, 2013 17:22:18
Откуда: Ярославль

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

Сообщение Muzykant »

А можно, допустим, просто записать элементы массива в регистры R16-R31 и переключаться между ними как-то типа R16+1=R17?
Извините, если глупость сказал....
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20091
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

Вроде можно через ST/LD. Но там нужна пара адресных регистров X, Y или Z.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

можно записать элементы массива в ячейки ОЗУ (регистры, кстати, тоже в области адресов ОЗУ расположены) и работать с ними почти так же, как с flash, но проще :)

во-первых, не надо адрес удваивать, а во-вторых, существуют команды косвенной загрузки из ОЗУ с инкрементом указателя (регистровой пары), т.е. программа упрощается.

но, разумеется, размер кода может увеличиться, т.к. заносить в ОЗУ придется "ручками"...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

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

ARV писал(а):во-первых, не надо адрес удваивать

Для LDM/SPM надо.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Gudd-Head писал(а):
ARV писал(а):во-первых, не надо адрес удваивать

Для LDM/SPM надо.
уважаемый, читайте внимательнее - я говорю про доступ к ОЗУ
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

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

Ах, это было продолжение мысли "почти так же, как с flash, но проще"?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Gudd-Head писал(а):Ах, это было продолжение мысли
угу. тем более, что команды LDM не существует :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Mr.Noiro
Родился
Сообщения: 11
Зарегистрирован: Вт апр 08, 2014 18:20:56

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

Сообщение Mr.Noiro »

ldi r16,0x05
out TCCR1B,r16
ldi r16,0x02
out TCCR1A,r16
ldi r16,high(pause)
ldi r17,low(pause)
out OCR1AH,r16
out OCR1AL,r17

МК Tiny2313. Вопрос по коду. После команды записи в регистр OCR1AH - значение в нем появляется, а сразу после команды записи в OCR1AL - в low регистре значение остается, а в high-регистре (OCR1AH) - сбрасывается в ноль. В чем причина?
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

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

Сообщение Alexeyslav »

Как это было определено?
А если поменять последовательность записи, сначала L потом H. В регистрах этих имеются хитрые защелки(или это касается только самого таймера?), которые предотвращают реакцию на неполное значение 16-битного регистра. Только когда обе половинки загрузишь, защелка срабатывает и таймер подхватывает значение поэтому от последовательности загрузки многое зависит.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Mr.Noiro писал(а):...В чем причина?
Разберитесь с режимом PWM, Phase Correct, 9-bit, объявляемым Вами битами WGM13...WGM10. Вполне возможно, что переменная pause имеет значение >0x01FF.
Спойлер

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

   .equ      PAUSE=   0x035C

   CLR   R0
   OUT TCCR1B,R0
   OUT   TCNT1H,R0
   OUT   TCNT1L,R0

   ldi r16,high(pause)
   ldi r17,low(pause)
   out OCR1AH,r16
   out OCR1AL,r17

   ldi r16,0x02
   out TCCR1A,r16

   ldi r16,0x05
   out TCCR1B,r16

;ldi r16,high(pause)
;ldi r17,low(pause)
;out OCR1AH,r16
;out OCR1AL,r17

По мне, лучше настроить режим работы, привести в начальную точку, сбросить флаги и только потом разрешить работу.
Mr.Noiro
Родился
Сообщения: 11
Зарегистрирован: Вт апр 08, 2014 18:20:56

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

Сообщение Mr.Noiro »

Ошибка в коде найдена! Был вкючен режим ШИМ.
Таймер был сконфигурирован как Phase correct PWM 9 бит, а не как CTC.
Mr.Noiro
Родился
Сообщения: 11
Зарегистрирован: Вт апр 08, 2014 18:20:56

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

Сообщение Mr.Noiro »

akl писал(а):
Mr.Noiro писал(а):...В чем причина?
Разберитесь с режимом PWM, Phase Correct, 9-bit, объявляемым Вами битами WGM13...WGM10. Вполне возможно, что переменная pause имеет значение >0x01FF.
Спойлер

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

   .equ      PAUSE=   0x035C

   CLR   R0
   OUT TCCR1B,R0
   OUT   TCNT1H,R0
   OUT   TCNT1L,R0

   ldi r16,high(pause)
   ldi r17,low(pause)
   out OCR1AH,r16
   out OCR1AL,r17

   ldi r16,0x02
   out TCCR1A,r16

   ldi r16,0x05
   out TCCR1B,r16

;ldi r16,high(pause)
;ldi r17,low(pause)
;out OCR1AH,r16
;out OCR1AL,r17

По мне, лучше настроить режим работы, привести в начальную точку, сбросить флаги и только потом разрешить работу.


Действительно, переменная pause была >0x01FF.

А если подробнее, что происходит с регистрами OCR1AH, OCR1AL и регистром TEMP при режиме PWM, Phase Correct, 9-bit при попытке записать число >0x01FF.
Я предполагаю - происходит запись в OCR1AL, а в OCR1AH - происходит переполнение (содержит один разряд исходя из режима PMW-9bit) и он (OCR1AH) сбрасывается в нуль. Так ли это? Какие есть мнения.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Скорее всего, в режиме PWM, Phase Correct, 9-bit не хватает разрядной сетки для занесения числа. Думаю, занесение чисел 0x03FF 0x04FF будет приводить к занесению 0x01FF и 0x00FF соответственно.
Может перейти в одну тему по таймерам. Сейчас вопрос обсуждается уже в трех темах. Неудобно. :oops:
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Сообщение Мikа »

Добрый день. Решил написать программу для ATmega48 с UART на ассемблере.

При компиляции лезет куча ошибок. Вот маленький пример:

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

ldi Temp, 51      
out UBRR0L, Temp
ldi Temp, 0
out UBRR0H, Temp


Ошибка Operand 1 out of range: 0xc4(адрес UBRR0L)". Все слова понятный, но общий смысл едва ли. Попробовал в разном виде писать число. Попробовал разные регистры для загрузки числа в UBRR0L. Результата никакого. Подскажите, пожалуйста, что это за ошибка?
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20091
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

Мikа писал(а):Подскажите, пожалуйста, что это за ошибка?

Не достреливает OUT до регистров UART.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Сообщение Мikа »

Спасибо, но тогда закономерен следующий вопрос, как до него "дострелить"? Я помню, что-то похожее было с jmp или rjmp, там можно ставить второй джамп туда, куда прыгает первый. А тут как? :)
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20091
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

Пользоваться командами ST/STD/STS.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Сообщение Мikа »

И правда :) Благодарю.

Появился ещё один вопрос.

Вот настройка векторов прерываний для ATmega48. Их я взял из апноута.
Спойлер

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

 .cseg

.org 0
   jmp RESET
.org   INT0addr   ; External Interrupt Request 0
   jmp INT0_IRQ
.org   INT1addr   ; External Interrupt Request 1
   jmp INT1_IRQ
.org   PCI0addr   ; Pin Change Interrupt Request 0
   jmp PCI0_IRQ
.org   PCI1addr   ; Pin Change Interrupt Request 0
   jmp PCI1_IRQ
.org   PCI2addr   ; Pin Change Interrupt Request 1
   jmp PCI2_IRQ
.org   WDTaddr      ; Watchdog Time-out Interrupt
   jmp WDT_IRQ
.org   OC2Aaddr   ; Timer/Counter2 Compare Match A
   jmp OC2A_IRQ
.org   OC2Baddr   ; Timer/Counter2 Compare Match A
   jmp OC2B_IRQ
.org   OVF2addr   ; Timer/Counter2 Overflow
   jmp OVF2_IRQ
.org   ICP1addr   ; Timer/Counter1 Capture Event
   jmp ICP1_IRQ
.org   OC1Aaddr   ; Timer/Counter1 Compare Match A
   jmp OC1A_IRQ
.org   OC1Baddr   ; Timer/Counter1 Compare Match B
   jmp OC1B_IRQ
.org   OVF1addr   ; Timer/Counter1 Overflow
   jmp OVF1_IRQ
.org   OC0Aaddr   ; TimerCounter0 Compare Match A
   jmp OC0A_IRQ
.org   OC0Baddr   ; TimerCounter0 Compare Match B
   jmp OC0B_IRQ
.org   OVF0addr   ; Timer/Couner0 Overflow
   jmp OVF0_IRQ
.org   SPIaddr      ; SPI Serial Transfer Complete
   jmp SPI_IRQ
.org   URXCaddr   ; USART Rx Complete
   jmp URXC_IRQ
.org   UDREaddr   ; USART, Data Register Empty
   jmp UDRE_IRQ
.org   UTXCaddr   ; USART Tx Complete
   jmp UTXC_IRQ
.org   ADCCaddr   ; ADC Conversion Complete
   jmp ADCC_IRQ
.org   ERDYaddr   ; EEPROM Ready
   jmp ERDY_IRQ
.org   ACIaddr      ; Analog Comparator
   jmp ACI_IRQ
.org   TWIaddr      ; Two-wire Serial Interface
   jmp TWI_IRQ
.org   SPMRaddr   ; Store Program Memory Read
   jmp SPMR_IRQ

   ;Векторы прерываний


   INT0_IRQ:
   INT1_IRQ:
   PCI0_IRQ:
   PCI1_IRQ:
   PCI2_IRQ:
   WDT_IRQ:
   OC2A_IRQ:
   OC2B_IRQ:
   OVF2_IRQ:
   ICP1_IRQ:
   OC1A_IRQ:
   OC1B_IRQ:
   OVF1_IRQ:
   OC0A_IRQ:
   OC0B_IRQ:
   OVF0_IRQ:
   SPI_IRQ:
   URXC_IRQ:
   UDRE_IRQ:
   UTXC_IRQ:
   ADCC_IRQ:
   ERDY_IRQ:
   ACI_IRQ:
   TWI_IRQ:
   SPMR_IRQ:

   reti
.
Дело в том, что если этот кусок кода присутствует в программе, то контроллер не делает вообще ничего, если эту часть кода убрать, то всё ок. Я снова что-то пропустил? =((
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

А где метка RESET ?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
ANALOG
Мучитель микросхем
Сообщения: 444
Зарегистрирован: Вс ноя 28, 2010 15:18:52
Откуда: Минск

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

Сообщение ANALOG »

Mika, дело в том, что команда jmp занимает 4 байта в памяти, а вектора прерываний у 48-й меги расположены через каждые 2 байта (но не у всех МК так, бывает и по 4 байта, это надо смотреть в даташите). Поэтому команды jmp у вас наслаиваются друг на друга, тут нужно использовать rjmp (да и вообще, лучше везде где можно использовать его, а не jmp)

А вообще, вот вам на заметку, я вот так всегда прерывания оформляю:
Спойлер

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

.cseg
rjmp RESET      ; Reset Handler
reti ;rjmp EXT_INT0    ; IRQ0 Handler
reti ;rjmp EXT_INT1    ; IRQ1 Handler
reti ;rjmp PCINT0       ; PCINT0 Handler
reti ;rjmp PCINT1       ; PCINT1 Handler
reti ;rjmp PCINT2       ; PCINT2 Handler
reti ;rjmp WDT          ; Watchdog Timer Handler
reti ;rjmp TIM2_COMPA    ; Timer2 Compare A Handler
reti ;rjmp TIM2_COMPB    ; Timer2 Compare B Handler
reti ;rjmp TIM2_OVF    ; Timer2 Overflow Handler
reti ;rjmp TIM1_CAPT    ; Timer1 Capture Handler
reti ;rjmp TIM1_COMPA    ; Timer1 Compare A Handler
reti ;rjmp TIM1_COMPB    ; Timer1 Compare B Handler
reti ;rjmp TIM1_OVF    ; Timer1 Overflow Handler
rjmp TIM0_COMPA    ; Timer0 Compare A Handler
reti ;rjmp TIM0_COMPB    ; Timer0 Compare B Handler
reti ;rjmp 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    ; USART, UDR Empty Handler
reti ;rjmp USART_TXC    ; USART, TX Complete Handler
reti ;rjmp ADC_RDY       ; ADC Conversion Complete Handler
reti ;rjmp EE_RDY       ; EEPROM Ready Handler
reti ;rjmp ANA_COMP    ; Analog Comparator Handler
reti ;rjmp TWI          ; 2-wire Serial Interface Handler
reti ;rjmp SPM_RDY       ; Store Program Memory Ready Handler

TIM0_COMPA:
nop
nop
nop
reti

RESET:
nop
nop
...


В строчках с нужными прерываниями я просто убираю reti, раскомменчиваю rjmp и выношу отдельно метку с обработчиком (тут для примера взял прерывание таймера 0)
Мне так больше нравится, потому, что кроме самой таблицы в коде тогда ничего нет, не нужно создавать блок пустых заглушек на те прерывания, которые не нужны (неиспользуемые прерывания сразу гасятся командами reti прямо на самих адресах прерываний)
Но если писать под контроллер, в котором прерывания идут через 4 байта, то тогда надо повставлять nop-ы между заглушечными reti, или вставить по 2 reti, ну или еще чего :)
Ответить

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