Ассемблер (ASM) для AVR в вопросах и ответах
-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
Savelek писал(а):Извините пожалуйста за возможно глупый вопрос, но что случится, если сделать логическую операцию между двумя регистрами (т.е. двумя байтами)? Ну например логическое ИЛИ. Будут поочередно сравниваться одинаковые п осчету биты двух регистров? А результат? Результат сравнения запишется в первый из сравниваемых регистров?
И еще вопрос - у Вас в коде команда "or tmp,tmp1", а в комментариях указано что это логическое И. Но ведь or это или... Да и для установки бита, наверное, нужно использовать лог. ИЛИ. Или я не прав?
Правы во всём
Код: Выделить всё
ldi R17, 1
looplab:
dec R16
brmi loopend
lsl R17
rjmp looplab
loopend:
Инверсия
Здравствуйте!
Подскажите, пожалуйста, как можно инвертировать два (младших) разряда в регистре ввода-вывода? Если можно, на примере.
Спасибо!
Подскажите, пожалуйста, как можно инвертировать два (младших) разряда в регистре ввода-вывода? Если можно, на примере.
Спасибо!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Инверсия
например, так:lag1 писал(а):Здравствуйте!
Подскажите, пожалуйста, как можно инвертировать два (младших) разряда в регистре ввода-вывода? Если можно, на примере.
Спасибо!
Код: Выделить всё
in r0, PORTB ; берем содержимое PORTB
ldi r16, 3 ; берем 2 младших бита - число 3
eor r0, r16 ; инвертируем биты
out PORTB, r0 ; выводим обратно в PORTBесли рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Инверсия
С примером стало понятно. Все работает.
Еще раз спасибо!
Еще раз спасибо!
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Ну и дополнение - для многих кристаллов можно инвертировать выход PORT записью 1-ки в соответствующий бит PIN
Например, для at90s2313 и atmega8 так нельзя, для attiny2313 и atmega48/88/168 - можно.
Смотреть описание на конкретный кристалл - раздел I/O-Ports
Искать там подраздел Toggling the Pin
Если он вообще есть, то возможно его можно не читать
- функция доступна. Там должно быть написано такое
Код: Выделить всё
ldi r16, 3
out PINB, r16 ; инвертируем два младших бита в PORTBНапример, для at90s2313 и atmega8 так нельзя, для attiny2313 и atmega48/88/168 - можно.
Смотреть описание на конкретный кристалл - раздел I/O-Ports
Искать там подраздел Toggling the Pin
Если он вообще есть, то возможно его можно не читать
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.
Note that the SBI instruction can be used to toggle one single bit in a port.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- IfoR
- Поставщик валерьянки для Кота
- Сообщения: 2029
- Зарегистрирован: Сб ноя 15, 2008 10:09:56
- Откуда: г. Тула
- Контактная информация:
У меня тоже вопрос по чтению из памяти. Контроллер ATmega16
Суть: есть запись в FLASH. Нужно её считать и запихнуть в регистр.
Делаю так:
Вот тут и проблема. В R16 пишется 0x00, а R17 - 0x20 при чём независимо от значения BVB.
Что я делаю не так?
Суть: есть запись в FLASH. Нужно её считать и запихнуть в регистр.
Делаю так:
Код: Выделить всё
.CSEG
.org 0x0000 ;Reset вектор
rjmp Reset
.org 0x002A
BVB: .DW 0x2255 ;Данные
Reset:
LDI R30,LOW(BVB) ;Пишем адрес в Z регистр
LDI R31,HIGH(BVB);Всё нормально. Пишется 0x002A
LD R16,Z+ ;Читаем слово из flash
LD R17,Z
Вот тут и проблема. В R16 пишется 0x00, а R17 - 0x20 при чём независимо от значения BVB.
Что я делаю не так?
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
начнем с того что в меге16, как впрочем и в других АВРках, флеш-память словная, т.е. состоит из 2 байтов, и чтобы получить доступ к ячейке BVB нада писать так:
а команда LD читает данные из памяти данных, а там по адреск 0х002А находится служебный регист UCSR0B=0х00 а по адресу 0х002В регистр UCSR0A=0x20 (значения по умолчанию при включении)
Код: Выделить всё
LDI R30,LOW(BVB*2) ;Пишем адрес в Z регистр
LDI R31,HIGH(BVB*2);Всё нормально. Пишется 0x002A*2=0х0054
lpm R16,Z+ читаем данные из flash
Lpm R17,Zа команда LD читает данные из памяти данных, а там по адреск 0х002А находится служебный регист UCSR0B=0х00 а по адресу 0х002В регистр UCSR0A=0x20 (значения по умолчанию при включении)
-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
GP1 писал(а):начнем с того что в меге16, как впрочем и в других АВРках, флеш-память словная, т.е. состоит из 2 байтов, и чтобы получить доступ к ячейке BVB нада писать так:Код: Выделить всё
LDI R30,LOW(BVB*2) ;Пишем адрес в Z регистр
LDI R31,HIGH(BVB*2);Всё нормально. Пишется 0x002A*2=0х0054
lpm R16,Z+ читаем данные из flash
Lpm R17,Z
а команда LD читает данные из памяти данных, а там по адреск 0х002А находится служебный регист UCSR0B=0х00 а по адресу 0х002В регистр UCSR0A=0x20 (значения по умолчанию при включении)
Чуток добавлю: с точки зрения выборки команд флэш-память организована по словам, т.е. адрес команды -- это адрес слова (двух байтов). Однако при доступе к ней за данными (с помощью команды LPM) она адресуется уже побайтно. Именно поэтому в этом примере адрес, с которого начинается считывание данных, умножен на два -- чтобы адрес слова (его использует транслятор ассемблера) превратить в адрес байта (нужный команде LPM).
- IfoR
- Поставщик валерьянки для Кота
- Сообщения: 2029
- Зарегистрирован: Сб ноя 15, 2008 10:09:56
- Откуда: г. Тула
- Контактная информация:
сообсно весь код:
И из BVB, и из CVB возвращает стабильно 0.
Код: Выделить всё
.DEVICE ATmega16
.INCLUDE "m16def.inc"
.CSEG
.org 0x0000 ;Reset вектор
rjmp Reset
.org 0x002A
BVB: .DW 0x1545 ;Данные
CVB: .DW 0x1234
Reset: ;outi SPL,low(RAMEND)
;outi SPH,high(RAMEND)
LDI R30,LOW(BVB*2)
LDI R31,HIGH(BVB*2)
LD R16,Z+
LD R17,Z
Main:
WDR
rjmp Reset
И из BVB, и из CVB возвращает стабильно 0.
- MTF
- Нашел транзистор. Понюхал.
- Сообщения: 179
- Зарегистрирован: Чт янв 07, 2010 11:25:12
- Откуда: Москва
Уважаемые коты помогите решить проблему с таймером !!!!
Попытаюсь обьяснить суть проблемы ,допустим в таймере T0 есть счетчик
работает CK/0 без деления т.к надо отсчитать
0,000064 cек и 0,016384 сек
сейчас таймер работает CK/256 и менять его частоту не могу ,так как там тоже есть счетчик но для счета более 1 сек
как можно использовать один таймер как CK/0 и CK/256 одновременно ???
допустим T0 без деления CK/0 , а все остальное что у меня работало в таймере с делением СK/256 , срабатывало через время как при СK/256
натолкните на мысль как это можно реализовать ???
Попытаюсь обьяснить суть проблемы ,допустим в таймере T0 есть счетчик
Код: Выделить всё
inc timer1 ;64us
inc inttemp
brne TIM0_OVF_exit
inc timer2
TIM0_OVF_exit:
работает CK/0 без деления т.к надо отсчитать
0,000064 cек и 0,016384 сек
сейчас таймер работает CK/256 и менять его частоту не могу ,так как там тоже есть счетчик но для счета более 1 сек
как можно использовать один таймер как CK/0 и CK/256 одновременно ???
допустим T0 без деления CK/0 , а все остальное что у меня работало в таймере с делением СK/256 , срабатывало через время как при СK/256
натолкните на мысль как это можно реализовать ???


