Ассемблер (ASM) для AVR в вопросах и ответах
- edm2007
- Поставщик валерьянки для Кота
- Сообщения: 2255
- Зарегистрирован: Вт апр 21, 2009 22:24:10
- Откуда: Иркутск
- Контактная информация:
Ну да, если нужен регистр данных порта - то PORTB, а если регистр выводов - то PINB. Я же написал ...если необходимо считать состояние вывода порта... Там только через PINB.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
-
Andrey3377
- Родился
- Сообщения: 9
- Зарегистрирован: Чт май 28, 2009 14:19:38
- Откуда: Санкт-Петербург
Код: Выделить всё
ldi r16,low(ramend)
out spl, r16
ldi r16, high(ramend)
out sph, r16Инициализация стека.... Объясните пожалуйста конструкции low(ramend) и high(ramend). ramend прописан в соответсвующем .inc, это понятно. А вот где прописаны low и high и как из low(ramend) и high(ramend) получаются константы? В хелпе я чего-то не нашел.
-
Andrey3377
- Родился
- Сообщения: 9
- Зарегистрирован: Чт май 28, 2009 14:19:38
- Откуда: Санкт-Петербург
- Виталик
- Первый раз сказал Мяу!
- Сообщения: 29
- Зарегистрирован: Вс ноя 18, 2007 12:29:40
- Откуда: Одесса
- Контактная информация:
Подскажите, что означают команды:
Код: Выделить всё
.DB 255,255,31,25,19,13,7,1
.org flashend-79
.dw VCR | (5 << 8)
- Виталик
- Первый раз сказал Мяу!
- Сообщения: 29
- Зарегистрирован: Вс ноя 18, 2007 12:29:40
- Откуда: Одесса
- Контактная информация:
Как на ассемблере осуществить деление 351 на 1579?
Сдесь есть деление, правда, только 8-разрядных чисел.
http://atmel.ru/Articles/Atmel21.htm
RUNA писал(а):...Как на ассемблере осуществить деление 351 на 1579?
Умножьте 351 на 10'000'000 и, пользуясь подпрограммой "DIV" по ссылке ниже, разделите на 1579. Получите результат умноженный на 10'000'000.
Умножать не обязательно на 10'000'000, а на число, которое позволит получить результат с достаточной точностью.
http://radiokot.ru/forum/viewtopic.php?p=193610#193610
-
Andrey3377
- Родился
- Сообщения: 9
- Зарегистрирован: Чт май 28, 2009 14:19:38
- Откуда: Санкт-Петербург
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Фраза "Сразу после таблицы прерываний" ничего не дает. главное какая метка стоит после нее.
Я обычно после РЕСЕТА произвожу инициализацию стека, портов, ну и всякую дребедень которая пригодиться, после этого завожу основной цикл программы и в нем уже пишу остальной код, т.к. в цикле нет смысла инициализировать несколько раз (исключения составляют те модули, которые отключаются/включаются в цикле, тогда их инициализацию ставлю не после РЕСЕТа а в цикл)
Я обычно после РЕСЕТА произвожу инициализацию стека, портов, ну и всякую дребедень которая пригодиться, после этого завожу основной цикл программы и в нем уже пишу остальной код, т.к. в цикле нет смысла инициализировать несколько раз (исключения составляют те модули, которые отключаются/включаются в цикле, тогда их инициализацию ставлю не после РЕСЕТа а в цикл)
Ставим плюсы: )
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
по-моему, вы являетесь очередной жертвой неудачного тезиса из обучалкиAndrey3377 писал(а):Двигаюсь потихоньку... Прерывания.
Как по вашему опыту лучше все эти дела организовывать, стек инициализировать, разрешение, конфигурация внешних и других прерываний? Сразу после таблицы прерываний или внутри обработчика RESET?
в подавляющем большинстве AVR RESET - это НЕ ВЕКТОР ПРЕРЫВАНИЯ, а сброс - НЕ ПРЕРЫВАНИЕ!!! это адрес начала исполнения программы, стартовый адрес. непосредственно со следующей ячейки памяти начинается таблица векторов прерываний.
так вот, обработчика RESET не существует - это есть основная программа. если вы используете прерывания, то таблица векторов будет использоваться по прямому назначению, следовательно, по адресу RESET должна быть команда безусловного перехода к телу основной программы - и ничего более!!! где это тело начнется - сразу после таблицы прерываний или глубже по памяти - абсолютно все равно. но иного места, кроме как в начале основной программы (реальном начале, а не по адресу RESET), для установки указателя стека и настройки периферии просто быть не может!!!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
-
Andrey3377
- Родился
- Сообщения: 9
- Зарегистрирован: Чт май 28, 2009 14:19:38
- Откуда: Санкт-Петербург
ARV писал(а):по-моему, вы являетесь очередной жертвой неудачного тезиса из обучалкиAndrey3377 писал(а):Двигаюсь потихоньку... Прерывания.
Как по вашему опыту лучше все эти дела организовывать, стек инициализировать, разрешение, конфигурация внешних и других прерываний? Сразу после таблицы прерываний или внутри обработчика RESET?
в подавляющем большинстве AVR RESET - это НЕ ВЕКТОР ПРЕРЫВАНИЯ, а сброс - НЕ ПРЕРЫВАНИЕ!!! это адрес начала исполнения программы, стартовый адрес. непосредственно со следующей ячейки памяти начинается таблица векторов прерываний.
Угу, вкурил. Тут виной не столько обучалка, сколько даташиты контроллеров с рыбой таблицы векторов прерываний. Где по нулевому адресу прописан Reset Handler.
В принципе по нулевому адресу может быть написано даже не rjmp НАЧАЛО_ПРОГРАММЫ, а какие-то команды на месте неиспользуемых векторов и rjmp можно поставить прямо перед используемым в конкретной программе вектором. Я правильно понял?
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
теоретически вы правильно поняли, вы в праве использовать память контроллера по своему усмотрению, только нужно точно знать, что никакое прерывание не произойдет. иначе PC присвоится адрес по которому должен быть вектор прерывания, а там на самом деле будет другая команда.
ИМХО лучший вариант вместо неиспользуемых векторов прерываний написать reti. (всегда если что можно заменить на rjmp метка)
ИМХО лучший вариант вместо неиспользуемых векторов прерываний написать reti. (всегда если что можно заменить на rjmp метка)
Ставим плюсы: )
Добрый день. Подскажите пожалуйста как решить мою проблему. Бьюсь головой в стену уже 2 дня
Нужно использовать USART1 в atmega64
Инициализация из даташита
Так как мне нужен USART1 то будет UBRR1H и UBRR1L
Но AVR sudio категорически не признает строки
out UBRR1H, r17 и out UBRR1L, r16 говоря
error: Operand 1 out of range: 0x9b
Что делать? заранее спасибо.
Нужно использовать USART1 в atmega64
Инициализация из даташита
- USART_Init:
; Set baud rate
out UBRRH, r17
out UBRRL, r16
итд...
ret
Так как мне нужен USART1 то будет UBRR1H и UBRR1L
Но AVR sudio категорически не признает строки
out UBRR1H, r17 и out UBRR1L, r16 говоря
error: Operand 1 out of range: 0x9b
Что делать? заранее спасибо.
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Alspro писал(а):Добрый день. Подскажите пожалуйста как решить мою проблему. Бьюсь головой в стену уже 2 дня
Нужно использовать USART1 в atmega64
Инициализация из даташитаUSART_Init:
; Set baud rate
out UBRRH, r17
out UBRRL, r16
итд...
ret
Так как мне нужен USART1 то будет UBRR1H и UBRR1L
Но AVR sudio категорически не признает строки
out UBRR1H, r17 и out UBRR1L, r16 говоря
error: Operand 1 out of range: 0x9b
Что делать? заранее спасибо.
Для загрузки регистров в старших адресах необходимо использовать команду ST, а для чтения LD
GP1 писал(а):Для загрузки регистров в старших адресах необходимо использовать команду ST, а для чтения LD
Чуть чуть подправлю, в случае с регистрами общего назначения нужно загружать их значения командой STS, т.е.
Код: Выделить всё
sts UBRR1H, r17а читать командой LDS, т.е. если мы хотим прочитать в r17 значение UBRR1H, то нужно сделать так.
Код: Выделить всё
lds r17, UBRR1H