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

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

pyzhman, не угадали....., я просто готовлю каверзные вопросы :))
кстати, команда lmp работает только с регистрами Z и R0 ?
по другому никак ?
Tell Me The Truth
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

FreshMan писал(а):lmp работает только с регистрами Z и R0 ?
LMP? :shock: Может, LPM? :)))
Есть ещё LPM Rd, Z(+).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

Gudd-Head писал(а):LMP? Может, LPM?
о....., да сори :)) ......, подумаешь ..., мальца ошибся :))
в данной статье http://radiokot.ru/start/mcu_fpga/avr/12/

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

;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************

Timer1_comp1:


         ldi Temp,0            ;обнуление таймера
         out TCNT1H,Temp
         out TCNT1L,Temp


         cpi Temp1,30          ;сравнить с крайним знач.
         breq Init             ;если равно - загрузка нач. знач.


ReadArray:
         ldi ZH,High(Array*2)  ;загрузка начального адреса массива
         ldi ZL,Low(Array*2)

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

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

         mov Temp,R0           ;копирование в РОН
         inc Temp1             ;увеличение внутр. адреса

         rjmp Output           ;перейти на вывод в порт

Init:    ldi Temp1,0          ;загрузить нач. значение
         rjmp ReadArray

Output:  out PortB,Temp       ;вывод в порт

         reti                  ;выход из обработчика


Array:

.db   0b10000001,0b01000010
.db   0b00100100,0b00011000
.db   0b00011000,0b00111100
.db   0b01111110,0b11111111
.db   0b11100111,0b11000011
.db   0b10000001,0b11000001
.db   0b11100001,0b11110001
.db   0b11111001,0b11111101
.db   0b11111111,0b01111111
.db   0b00111111,0b00011111
.db   0b00001111,0b00000111
.db   0b00000011,0b00000001
.db   0b00000011,0b00000101
.db   0b00001001,0b00010001
.db   0b00100001,0b01000001
для меня непонятны следующие строки

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

ldi Temp,0            ;прибавление внутр. адреса
 add ZL,Temp1
 adc ZH,Temp
почему делается именно так , а не скажем вот так ?

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

ldi Temp,0            ;прибавление внутр. адреса
 adс ZL,Temp1
 add ZH,Temp
Tell Me The Truth
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

FreshMan писал(а): для меня непонятны следующие строки

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

ldi Temp,0            ;прибавление внутр. адреса
 add ZL,Temp1
 adc ZH,Temp
почему делается именно так , а не скажем вот так ?

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

ldi Temp,0            ;прибавление внутр. адреса
 adс ZL,Temp1
 add ZH,Temp
команда ADC прибавляет флаг переноса, т.е. "1", если с младшими случается переполнение, поэтому к старшему нужно прибавить "0" именно командой ADC, а если прибавим командой ADD, то в случае переполнения младших старшему ничего не перепадет.

p.s. Если применять ADC к младшему байту, то к нему может прибавиться результат предыдущей любой операции влияющей на флаг переноса.... Во загнул как :hunger:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

FreshMan писал(а):мальца ошибся
После такого мальца спутники мимо Венеры пролетают. :))
FreshMan, когда паять и программировать вживую начнем? А то такое ощущение, что голой теорией занимаетесь.
Docendo discimus
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

zero648 писал(а):команда ADC прибавляет флаг переноса, т.е. "1", если с младшими случается переполнение
а что будет когда со старшим случится переполнение ?
pyzhman писал(а): А то такое ощущение, что голой теорией занимаетесь.
неа....., счас я занимаюсь голым ремонтом :)) ,а в передишках штудирую асм для разминки мозгов :))
похожие мигалки я уже паял и програмировал на Си, а тут стало интерестно как же вся эта кухня работает на асме :tea:
Tell Me The Truth
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

FreshMan писал(а):команда ADC прибавляет флаг переноса, т.е. "1", если с предыдущим случается переполнение
Так правильнее.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

а что будет когда со старшим случится переполнение ?
Ничего, просто флаг С опять установится.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

Alexeyslav писал(а): Причем, <метка>*2 адресует один байт, а <метка>*2+1 адресует следующий байт. Поэтому у вас в примере ошибка - старшая и младшая часть слова у вас будут равны одному и тому же байту из памяти.
Это в скобках, а что будет после применения модификатора или как его там LOW() и HIGH()?
Контактная информация:
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Они от результата возьмут старший/младший байт слова и всего-то.
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Ср апр 24, 2013 19:33:05

Сообщение Valek174 »

Всем привет!!!
У меня начальные знания програмирования AVR.
Как я понял из книг, чтобы заработали прерывания нужно:
организовать безусловный переход на те прерывания которые нам необходимы, например - rjmp RESET
настроить определенные регистры, а именно MCUCR и GIMSK, таким образзом как нам надо (читаем описание к контроллеру).
Потом разрешаем прывания sei.
И дальше у меня стоп!
Например я хочу получить генаратор прямоугольных импульсов.
Управление генератором осуществляется одной кнопкой (подключена к EXT_INT0)
При нажатии на кнопку запускается генератор, а при повторном нажатии выключается и микроконтроллер уходит в режим Power-down, при следующем нажатии запускается, и т. д.
Так вот, вопрос: если срабатывает прерывание, то с какого места начинает выполняться программа? Например контроллер в режиме sleep, при срабатывании прерывания,выполняет следующую команду за sleep или программа начинает выполнятся с какой-то определенной метки?
И еще вопрос. Когда мы организовываем безусловный переход на прерывания, компилятор ругается, типа что такая метка уже задействована. Выход, как я прочитал, обозвать прерывания другим именем, но тогда как контроллер поймет что задействовано именно то прерывание которое мне нужно?
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

я тут читал что сброс программы может быть вызван тремя причинами
1)кнопкой ресет
2)сторожевым таймером
3)подачей питания

а как в системе отследить чем именно в данный момент был вызван сброс ?
Tell Me The Truth
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

2FreshMan: MCUCSR
2Valek174:
с какого места
с того самого, откуда ушла в обработчик прерывания. Например:
а
б
в
г
плямс, сработало прерывание. В стеке сохраняется адрес следующей команды(в данном случае адрес команды "д").Ушли на его обработку......Обработка завершена, вертаемся сюда же(адрес возврата хранится в стеке).
д
е
ё
ж
обозвать прерывания
называть можно как угодно, главное - соблюдать адреса.
Docendo discimus
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 560
Зарегистрирован: Пт июл 02, 2010 19:30:22
Откуда: Новосибирск / Магнитогорск

Сообщение ranger93 »

Помогите разобраться со power-down.
Пишу следующее:
Спойлер...
ldi r16, 0b10100010
out MCUCR, r16 ; хотим работать со спадающим фронтом с прерыванием int0 и выключаться по команде sleep
sleepmode:
ldi r16,0b00000000
out timsk,r16; запрещаем прерывания по таймеру
ldi r16, 0
out tcnt2, r16; сбросим таймер нахрен!
ldi r16, 0b01000000
out GICR, r16 ; разрешаем прерывание int0
sei
sleep
nop
В avr-studio все работает нормально: контроллер засыпает и при нажатии кнопке на 4-й ноге уходит в прерывание, а вот в реальной жизни как-то не работает... В чем может быть причина?
Главное, чтоб был источник ЭДС, а с остальным разберемся :).
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

В чем может быть причина?
Даже и смотреть не станем, пока не научитесь называть константы осмысленно.
Что у вас в MCUCR?
Вымогатель припоя
Аватара пользователя
Сообщения: 560
Зарегистрирован: Пт июл 02, 2010 19:30:22
Откуда: Новосибирск / Магнитогорск

Сообщение ranger93 »

Извините, не понял, какие константы :) ?
Главное, чтоб был источник ЭДС, а с остальным разберемся :).
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Те, которые вот тут например показаны:

Изображение

Обратите внимание, у каждого бита есть имя. И его знает ваш компилятор.
Вымогатель припоя
Аватара пользователя
Сообщения: 560
Зарегистрирован: Пт июл 02, 2010 19:30:22
Откуда: Новосибирск / Магнитогорск

Сообщение ranger93 »

у меня вот так:
Изображение
И ассемблер принимает биты в таком же порядке. А выходной файл беру из папки с проектом, стало быть он правильно собран...
Главное, чтоб был источник ЭДС, а с остальным разберемся :).
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Что правильно? У меня скриншот с даташита другого контроллера :)
Я про сам принцип. Вот эти строки будут равнозначны:

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

ldi r16, 0b10100010
ldi r16, (1<<ISC01)|(1<<SM1)|(1<<SE)
Разница только в том, что последняя легко читается, т.к. это сокращения, например SM - Sleep Mode Select Bits

И теперь хорошо видно, что у вас включено прерывание по спаду на INT0 (ISC01), режим power-down (SM1), и, собственно, разрешение сна (SE). Вроде всё нормально.
А вот 0b10100010 - совершенно ни о чём не говорит :)
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Как по мне, так ни первый ни второй вариант некрасивы и непонятны. было бы куда проще если записать как ISC01+SM1+SE Но это требует дополнительных определений.
Контактная информация:
Ответить

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