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

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

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

Сообщение Muzykant »

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

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

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

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

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

Сообщение ARV »

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

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

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

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

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

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

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

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

Сообщение ARV »

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

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

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

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

Ах, это было продолжение мысли "почти так же, как с flash, но проще"?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18629
Зарегистрирован: Чт дек 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
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 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
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 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
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 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
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 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»