Ассемблер (ASM) для AVR в вопросах и ответах
- Muzykant
- Нашел транзистор. Понюхал.
- Сообщения: 192
- Зарегистрирован: Вт дек 24, 2013 17:22:18
- Откуда: Ярославль
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А можно, допустим, просто записать элементы массива в регистры R16-R31 и переключаться между ними как-то типа R16+1=R17?
Извините, если глупость сказал....
Извините, если глупость сказал....
- Gudd-Head
- Друг Кота
- Сообщения: 20091
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вроде можно через ST/LD. Но там нужна пара адресных регистров X, Y или Z.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
можно записать элементы массива в ячейки ОЗУ (регистры, кстати, тоже в области адресов ОЗУ расположены) и работать с ними почти так же, как с flash, но проще 
во-первых, не надо адрес удваивать, а во-вторых, существуют команды косвенной загрузки из ОЗУ с инкрементом указателя (регистровой пары), т.е. программа упрощается.
но, разумеется, размер кода может увеличиться, т.к. заносить в ОЗУ придется "ручками"...
во-первых, не надо адрес удваивать, а во-вторых, существуют команды косвенной загрузки из ОЗУ с инкрементом указателя (регистровой пары), т.е. программа упрощается.
но, разумеется, размер кода может увеличиться, т.к. заносить в ОЗУ придется "ручками"...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Gudd-Head
- Друг Кота
- Сообщения: 20091
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
ARV писал(а):во-первых, не надо адрес удваивать
Для LDM/SPM надо.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
уважаемый, читайте внимательнее - я говорю про доступ к ОЗУGudd-Head писал(а):ARV писал(а):во-первых, не надо адрес удваивать
Для LDM/SPM надо.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Gudd-Head
- Друг Кота
- Сообщения: 20091
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ах, это было продолжение мысли "почти так же, как с flash, но проще"?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
угу. тем более, что команды LDM не существуетGudd-Head писал(а):Ах, это было продолжение мысли
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Ассемблер (ASM) для AVR в вопросах и ответах
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) - сбрасывается в ноль. В чем причина?
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 в вопросах и ответах
Как это было определено?
А если поменять последовательность записи, сначала L потом H. В регистрах этих имеются хитрые защелки(или это касается только самого таймера?), которые предотвращают реакцию на неполное значение 16-битного регистра. Только когда обе половинки загрузишь, защелка срабатывает и таймер подхватывает значение поэтому от последовательности загрузки многое зависит.
А если поменять последовательность записи, сначала L потом H. В регистрах этих имеются хитрые защелки(или это касается только самого таймера?), которые предотвращают реакцию на неполное значение 16-битного регистра. Только когда обе половинки загрузишь, защелка срабатывает и таймер подхватывает значение поэтому от последовательности загрузки многое зависит.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Разберитесь с режимом PWM, Phase Correct, 9-bit, объявляемым Вами битами WGM13...WGM10. Вполне возможно, что переменная pause имеет значение >0x01FF.Mr.Noiro писал(а):...В чем причина?
Спойлер
Код: Выделить всё
.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
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ошибка в коде найдена! Был вкючен режим ШИМ.
Таймер был сконфигурирован как Phase correct PWM 9 бит, а не как CTC.
Таймер был сконфигурирован как Phase correct PWM 9 бит, а не как CTC.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
akl писал(а):Разберитесь с режимом PWM, Phase Correct, 9-bit, объявляемым Вами битами WGM13...WGM10. Вполне возможно, что переменная pause имеет значение >0x01FF.Mr.Noiro писал(а):...В чем причина?По мне, лучше настроить режим работы, привести в начальную точку, сбросить флаги и только потом разрешить работу.Спойлер
Код: Выделить всё
.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) сбрасывается в нуль. Так ли это? Какие есть мнения.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Скорее всего, в режиме PWM, Phase Correct, 9-bit не хватает разрядной сетки для занесения числа. Думаю, занесение чисел 0x03FF 0x04FF будет приводить к занесению 0x01FF и 0x00FF соответственно.
Может перейти в одну тему по таймерам. Сейчас вопрос обсуждается уже в трех темах. Неудобно.
Может перейти в одну тему по таймерам. Сейчас вопрос обсуждается уже в трех темах. Неудобно.
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добрый день. Решил написать программу для ATmega48 с UART на ассемблере.
При компиляции лезет куча ошибок. Вот маленький пример:
Ошибка Operand 1 out of range: 0xc4(адрес UBRR0L)". Все слова понятный, но общий смысл едва ли. Попробовал в разном виде писать число. Попробовал разные регистры для загрузки числа в UBRR0L. Результата никакого. Подскажите, пожалуйста, что это за ошибка?
При компиляции лезет куча ошибок. Вот маленький пример:
Код: Выделить всё
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 в вопросах и ответах
Мikа писал(а):Подскажите, пожалуйста, что это за ошибка?
Не достреливает OUT до регистров UART.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Спасибо, но тогда закономерен следующий вопрос, как до него "дострелить"? Я помню, что-то похожее было с jmp или rjmp, там можно ставить второй джамп туда, куда прыгает первый. А тут как? 
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
- Gudd-Head
- Друг Кота
- Сообщения: 20091
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Пользоваться командами ST/STD/STS.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Мikа
- Потрогал лапой паяльник
- Сообщения: 343
- Зарегистрирован: Пн апр 01, 2013 15:13:40
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
И правда
Благодарю.
Появился ещё один вопрос.
Вот настройка векторов прерываний для ATmega48. Их я взял из апноута.
.
Дело в том, что если этот кусок кода присутствует в программе, то контроллер не делает вообще ничего, если эту часть кода убрать, то всё ок. Я снова что-то пропустил? =((
Появился ещё один вопрос.
Вот настройка векторов прерываний для 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
Дело в том, что если этот кусок кода присутствует в программе, то контроллер не делает вообще ничего, если эту часть кода убрать, то всё ок. Я снова что-то пропустил? =((
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А где метка RESET ?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Mika, дело в том, что команда jmp занимает 4 байта в памяти, а вектора прерываний у 48-й меги расположены через каждые 2 байта (но не у всех МК так, бывает и по 4 байта, это надо смотреть в даташите). Поэтому команды jmp у вас наслаиваются друг на друга, тут нужно использовать rjmp (да и вообще, лучше везде где можно использовать его, а не jmp)
А вообще, вот вам на заметку, я вот так всегда прерывания оформляю:
В строчках с нужными прерываниями я просто убираю reti, раскомменчиваю rjmp и выношу отдельно метку с обработчиком (тут для примера взял прерывание таймера 0)
Мне так больше нравится, потому, что кроме самой таблицы в коде тогда ничего нет, не нужно создавать блок пустых заглушек на те прерывания, которые не нужны (неиспользуемые прерывания сразу гасятся командами reti прямо на самих адресах прерываний)
Но если писать под контроллер, в котором прерывания идут через 4 байта, то тогда надо повставлять nop-ы между заглушечными reti, или вставить по 2 reti, ну или еще чего
А вообще, вот вам на заметку, я вот так всегда прерывания оформляю:
Спойлер
Код: Выделить всё
.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, ну или еще чего