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

Обсуждаем контроллеры компании Atmel.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 708
Зарегистрирован: Пт ноя 30, 2007 14:40:44

Сообщение Серый_ »

Ок, спс. Вроде не трётся. (Юзаю AVR Studio & мыльничку ISP mk2).
Реклама
Опытный кот
Аватара пользователя
Сообщения: 708
Зарегистрирован: Пт ноя 30, 2007 14:40:44

Сообщение Серый_ »

Ещё вопрос: существует ли список команд с которыми не работают регистры R0...R15?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6349
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

http://www.atmel.com/images/Atmel-0856- ... Manual.pdf
тут про каждую команду прописано, с какими регистрами она может работать, с какими - нет. А составить для себя суммарную табличку по этому документу можно минуты за 3.
Изображение
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Серый_ В DS на старые AT90Sxxxx, ATmega103 было написано
The only exception is the five constant arithmetic and logic instructions SBCI, SUBI, CPI, ANDI, ORI between a constant and a register and the LDI instruction for load immediate constant data.
Реклама
Эиком - электронные компоненты и радиодетали
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

Сообщение ПТУ-шник »

Как записать в SRAM (ОЗУ) что нибудь? В частности нужен массив.
Хочу выводить цифры на семисигментный индиктор черз каждые 4-5 секунд. Написал код, но не работает. Просто SRAM полностью пусто, хотя я туда данные как массив вбивал. Почему их там нет?
Спойлер

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

;МК attiny2313. 
.equ Numb0 = 0b00111111 // Запоминаем цифры
.equ Numb1 = 0b00000110
.equ Numb2 = 0b01011011
.equ Numb3 = 0b01001111
.equ Numb4 = 0b01100110
.equ Numb5 = 0b01101101
.equ Numb6 = 0b01111101
.equ Numb7 = 0b00000111
.equ Numb8 = 0b01111111
.equ Numb9 = 0b01101111

.include  "C:\Program Files (x86)\Atmel\AVR Tools\AvrAssembler2\Appnotes\tn2313def.inc"
; ***************** Константы/переменные ***********
.def temp = R16
// ОЗУ ===================
.dseg
.org 0x60
ArrayNumb: // Массив в ОЗУ
.db Numb0,Numb1,Numb2,Numb3,Numb4,Numb5,Numb6,Numb7,Numb8,Numb9
//Начало =================
.cseg
.org 0
;****************** Таблицы векторов *******************
rjmp RESET ; Reset Handler
reti ;INT0 ; External Interrupt0 Handler
reti ;INT1 ; External Interrupt1 Handler
reti ;TIM1_CAPT ; Timer1 Capture Handler
reti ;TIM1_COMPA ; Timer1 CompareA Handler
rjmp  TIM1_OVF ; Timer1 Overflow Handler
reti ;TIM0_OVF ; Timer0 Overflow Handler
reti ;USART0_RXC ; USART0 RX Complete Handler
reti ;USART0_DRE ; USART0,UDR Empty Handler
reti ;USART0_TXC ; USART0 TX Complete Handler
reti ;ANA_COMP ; Analog Comparator Handler
reti ;PCINT ; Pin Change Interrupt
reti ;TIMER1_COMPB ; Timer1 Compare B Handler
reti ;TIMER0_COMPA ; Timer0 Compare A Handler
reti ;TIMER0_COMPB ; Timer0 Compare B Handler
reti ;USI_START ; USI Start Handler
reti ;USI_OVERFLOW ; USI Overflow Handler
reti ;EE_READY ; EEPROM Ready Handler
reti ;WDT_OVERFLOW ; Watchdog Overflow Handle
;************ Предварительная настройка**********
Reset:
;************ Инициализация стека **********
ldi r16, low(RAMEND)
out  SPL,r16 
;************ Настройка I/O и переферии**********
ldi temp, 0b11111111
out DDRB, temp
ldi temp, 0b00111100
out DDRD, temp
ldi temp, (1<<CS11) | (1<<CS10); Делитель на 64
out TCCR1B, temp
ldi temp, (1<<TOIE1)
out TIMSK, temp
sbi PORTD,2 // УСТАНОВИМ 2
ldi ZL, LOW(ArrayNumb) // считаем адресс 
ldi ZH, HIGH(ArrayNumb) // в озу
sei
	rjmp Main
;************ Главная программа *************
	Main:
rjmp MAIN
;************ Прерывание таймер *************	
	TIM1_OVF:
ld temp, Z+ //Считываем что находится по адресу ригстровой пары Z и потом прибавляем +1
out PORTB, temp
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15793
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

В ОЗУ данные заносит только программа при ее исполнении (в отличии от ПЗУ и/или EEPROM где массивы записывает компилятор с последующим размещением данных в файлах прошивки).
Для ОЗУ можно лишь зарезервировать количество ячеек для заданного имени:
.dseg
.org SRAM_START
Numb: .byte 10 ; резервируем 10 ячеек для массива Numb
затем при начале работы программа должна проинициализировать (провести предварительную запись)
указанные ячейки значениями Numb0-Numb9 и лишь затем использовать массив Numb как источник
данных.
8)
Реклама
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

Сообщение ПТУ-шник »

Мда. Это ж замучится можно ручками это всё инициализировать. А как сделать цикл я не знаю пока. Проще тогда эти константы в FLASH сделать и всё.
Друг Кота
Аватара пользователя
Сообщения: 15793
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Ежли с обычной ОЗУ вопросы... :roll:
То с таблицей в ПЗУ их еще больше будет - хотя бы по размещению данных в ячейках ПЗУ и поведению указателя Z (бит Z.0) при отработке команды LPM.
:wink:
Друг Кота
Аватара пользователя
Сообщения: 6349
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

ПТУ-шник писал(а):А как сделать цикл я не знаю пока. Проще тогда эти константы в FLASH сделать и всё.
Не только проще, а это единственно разумный вариант размещения констант. Но для извлечения их из флеши - все равно без цикла никак. :)
Изображение
Друг Кота
Аватара пользователя
Сообщения: 15793
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Для начала пущай с "ручным распихиванием" и циклами потренируется, а не то "первый облом" интерес к ассемблеру напрочь отобьёт.
8)
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

ПТУ-шник писал(а): Проще тогда эти константы в FLASH сделать и всё.
Конечно, так и нужно. По мне, ничего страшного
Спойлер

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

;МК attiny2313. 
.equ Numb0 = 0b00111111 // Запоминаем цифры
.equ Numb1 = 0b00000110
.equ Numb2 = 0b01011011
.equ Numb3 = 0b01001111
.equ Numb4 = 0b01100110
.equ Numb5 = 0b01101101
.equ Numb6 = 0b01111101
.equ Numb7 = 0b00000111
.equ Numb8 = 0b01111111
.equ Numb9 = 0b01101111

.include  "tn2313def.inc"
; ***************** Константы/переменные ***********
.def temp = R16
;// ОЗУ ===================
;.dseg
;.org 0x60
;ArrayNumb: // Массив в ОЗУ
;.db Numb0,Numb1,Numb2,Numb3,Numb4,Numb5,Numb6,Numb7,Numb8,Numb9
//Начало =================
.cseg
.org 0
;****************** Таблицы векторов *******************
rjmp RESET ; Reset Handler
reti ;INT0 ; External Interrupt0 Handler
reti ;INT1 ; External Interrupt1 Handler
reti ;TIM1_CAPT ; Timer1 Capture Handler
reti ;TIM1_COMPA ; Timer1 CompareA Handler
rjmp  TIM1_OVF ; Timer1 Overflow Handler
reti ;TIM0_OVF ; Timer0 Overflow Handler
reti ;USART0_RXC ; USART0 RX Complete Handler
reti ;USART0_DRE ; USART0,UDR Empty Handler
reti ;USART0_TXC ; USART0 TX Complete Handler
reti ;ANA_COMP ; Analog Comparator Handler
reti ;PCINT ; Pin Change Interrupt
reti ;TIMER1_COMPB ; Timer1 Compare B Handler
reti ;TIMER0_COMPA ; Timer0 Compare A Handler
reti ;TIMER0_COMPB ; Timer0 Compare B Handler
reti ;USI_START ; USI Start Handler
reti ;USI_OVERFLOW ; USI Overflow Handler
reti ;EE_READY ; EEPROM Ready Handler
reti ;WDT_OVERFLOW ; Watchdog Overflow Handle

ArrayNumb: // Массив в FLASH
.db Numb0,Numb1,Numb2,Numb3,Numb4,Numb5,Numb6,Numb7,Numb8,Numb9
ArrayNumb_END:
;************ Предварительная настройка**********
Reset:
;************ Инициализация стека **********
ldi r16, low(RAMEND)
out  SPL,r16 
;************ Настройка I/O и переферии**********
ldi temp, 0b11111111
out DDRB, temp
ldi temp, 0b00111100
out DDRD, temp
	LDI	R16,1<<SE
	OUT	MCUCR,R16
ldi temp, (1<<CS11) | (1<<CS10); Делитель на 64
out TCCR1B, temp
ldi temp, (1<<TOIE1)
out TIMSK, temp
sbi PORTD,2 // УСТАНОВИМ 2
	ldi ZL, LOW(ArrayNumb*2) // считаем адрес FLASH
	ldi ZH, HIGH(ArrayNumb*2) // в озу
;ldi ZL, LOW(ArrayNumb) // считаем адресс 
;ldi ZH, HIGH(ArrayNumb) // в озу
sei
;   rjmp Main
;************ Главная программа *************
Main:
	SLEEP
	rjmp MAIN
;************ Прерывание таймер *************   
TIM1_OVF:
	LPM	R16,Z+
	OUT	PORTB,R16
	CPI	ZL,ArrayNumb_END*2
	BRLO	TIM1_OUT
	ldi ZL, LOW(ArrayNumb*2) // считаем адрес FLASH
TIM1_OUT:
	RETI
;ld temp, Z+ //Считываем что находится по адресу ригстровой пары Z и потом прибавляем +1
;out PORTB, temp

Родился
Аватара пользователя
Сообщения: 6
Зарегистрирован: Вт сен 06, 2016 10:36:15

Сообщение kolpakchi »

Приветствую.
В даташитах на тини контроллеры, в разделе "Self-Programming the Flash" присутствуют строчки:
"The CPU is halted during the Page Erase operation."
"The CPU is halted during the Page Write operation."
Означает ли это, что периферия (в частности USART) тоже остановится на время прожига?

Задача разряда "for fun". Хочу реализовать бутлоадер для ATtiny2313, который бы сам принимал по UART файл прошивки .hex, декодировал его и прошивался. Таким образом планирую избавиться от зависимости от ОС-зависимого софта. Проблема в том, что контроллеру нужно 4.5 мс на прошивку страницы, во время которых он не сможет принимать данные. Следовательно, нужно организовать управление потоком. Хотелось бы обойтись без RTS/CTS, попробую заюзать XOn/XOff. Прощупываю, насколько это реально. Конечно, есть еще вариант заставить комп отсылать файл с паузами.
Мудрый кот
Аватара пользователя
Сообщения: 1814
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

kolpakchi, написано, что CPU останавливается. Больше ничего. Читаем как написано, для начала. :)
Можно ещё передавать на скорости 2400 бод с чётностью - время передачи одного байта будет 4,58мс (если ничего не напутал). А с учетом буферизации в USART можно и на 4800.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Друг Кота
Аватара пользователя
Сообщения: 15793
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Тогда уж лучше "загрузочную ЕЕПРОМку" из 24-й серии...
8)
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Проблема в том, что контроллеру нужно 4.5 мс на прошивку страницы, во время которых он не сможет принимать данные. Следовательно, нужно организовать управление потоком. Хотелось бы обойтись без RTS/CTS, попробую заюзать XOn/XOff. Прощупываю, насколько это реально. Конечно, есть еще вариант заставить комп отсылать файл с паузами.
Я делал так: при старте ПК запрашивает размер страницы и потом пересылает по одной странице с LRC-кодом контроля (LRC - метод, используемый для контроля HEX-файлов, просто сумма переданных байтов), потом контроллер посылает отчет об успехе.
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб сен 17, 2016 18:56:30

Сообщение dimmer »

Внесу свои 5 копеек. В Атмелевском файле AVR202.asm представлена идиома "Negate a 16-bit Register Variable":

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

	com	ng1l
	com	ng1h
	subi	ng1l,low(-1)
	sbci	ng1h,high(-1)
на самом деле можно сделать короче:

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

	neg	ng1h
	neg	ng1l
	sbci	ng1h,0
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Привет всем. )
Вопрос. Как всегда тупой.

Не нашел у себя в списке команд. Видимо программист из меня хреновый.

Как поменять (инвертировать) один бит в регистре. Причем довольно быстро.

Т.е. пришел в прерывание, а до этого в порту уже стояло какое-то значение, и в прерывании просто перевернул его на обратное и вышел. А при очередном входе в прерывание тоже самое, т.е. просто постоянно меняет значение бита на обратное.
Станислав
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Сообщение dgrett »

Мож eor?
Я всё-всё узнAю и стану профессором.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Вот. Я ищу XOR, как инете написали, а у меня его в списке нет, но есть EOR. )))
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

СКАЗОЧНИК писал(а):а до этого в порту уже стояло какое-то значение, и в прерывании просто перевернул его на обратное и вышел.
При записи 1 в PINX, инвертируется PORTX. Наверное это самое быстрое. Не у всех МК есть такая фича.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Ответить

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