Уважаемые электронщики. Столкнулся со странной проблемой. Я решил написать программу на asm для Tiny88 с использованием АЦП, но почему то в AVRStudio не получается записать хоть какое либо число в регистры ADMUX и ADCSRA(и возможно еще многие регистры). Или же установить там отдельные биты. Все время вылетает ошибка “operand l out of range”
.ORG 0x0000 //rjmp Reset reti .ORG 0x001 ; IRQ0 Handler reti .ORG 0x002 ; IRQ1 Handler reti .ORG 0x003 ; PCINT0 Handler reti .ORG 0x004 ; PCINT1 Handler reti .ORG 0x005 ; PCINT2 Handler reti .ORG 0x006 ; PCINT3 Handler reti .ORG 0x007 ; Watchdog Timer Handler reti .ORG 0x008 ; Timer1 Capture Handler reti .ORG 0x009 ; Timer1 Compare A Handler reti .ORG 0x00A ; Timer1 Compare A Handler reti .ORG 0x00B ; Timer1 Compare B Handler reti .ORG 0x00C ; Timer0 Compare A Handler reti .ORG 0x00D ; Timer0 Compare B Handler reti .ORG 0x00E ; Timer0 Overflow Handler reti .ORG 0x00F ; SPI Transfer Complete Handler reti .ORG 0x010 ; ADC Conversion Complete Handler reti .ORG 0x011 ; EEPROM Ready Handler reti .ORG 0x012 ; Analog Comparator Handler reti .ORG 0x013 ; 2-wire Serial Interface Handler; reti
.def temp=R16 ldi temp,$FF out DDRB,temp ldi temp,$FF out DDRD,temp
ldi temp,$8B out ADCSRA,temp
Она еще не дописана. Просто встрял с этими регистрами. Если кто сталкивался помогите
Последний раз редактировалось blindman 03 июл 2009, 07:37, всего редактировалось 1 раз.
Причина:Используйте тэг CODE!
В архитектуре AVR, доступ к регистрам ввода-вывода возможен через 2 адресных пространства: пространство ввода-вывода и пространство ОЗУ. Через пространство ввода-вывода можно обращаться только к 64 регистрам, потому что в коде операций ввода-вывода под адрес порта отведено 6 битов. Если в контроллере больше 64 регистров ввода-вывода, то к старшим обращение возможно только как к ячейкам памяти, а к младшим - и как к ячейкам памяти, и как к портам ввода-вывода.
Если открыть любой даташит на AVR, в конце есть таблица "Register Summary". Там в колонке "Address" указаны 2 адреса - в пространстве ввода вывода и в скобках - в пространстве ОЗУ (эти адреса всегда различаются на 0x20). Если указан только адрес в скобках - обращение возможно только как к ОЗУ.
Например для ATtiny88 обращаться к PORTB можно так: in R24, PORTB или так: lds R24, PORTB + $20. А к ADCSRA - только как lds R24, ADCSRA. Обратите внимание - здесь нет + $20
Я ето понял. Но скажите пожалуйста как записать нужные мне числа в регистр ADCSRA? Допустим устновить нужный бит этого регистра в 1. Просто при конструкции .............. ldi temp,$8B out ADCSRA,temp ............... вылетает ошибка и вариант
.............. sbi ADCSRA,$8B ............. поже ошибка. Хотя по идее в этот регистр можно записать такое число.
Что понял?! Это что такое: out ADCSRA,temp Я для кого всё это писал? Неужели не ясно что если нельзя применять инструкцию in, то и out тоже нельзя? А sbi/cbi вообще применима только к 32 младшим регистрам ввода-вывода.
Можно конечно. Но только если ты перечитаешь все что я писал, откроешь даташит, и ответишь сам себе на вопрос: почему инструкция sbi ADCSRA, что-угодно не компилируется. Поверь, это будет намного полезнее, чем если тебе дадут прямой ответ.
DK10000 писал(а): Я решил написать программу на asm для Tiny88 с использованием АЦП
Попробуйте писать на Си - компилятор знает обчно как правильно обращаться к регистрам ну и другие "трюки". Посмотрите работу с мастером кода CVAVR ( всего 2 Мб ) - http://avr123.nm.ru/z3.htm - возможно пойдет.
Кроме того код на АСМ можно посмотреть в листинге компилятора CVAVR - файл .lst - это может помочь когда вы в тупике на АСМ.
Ну, в общем докладываю. Как я понял к некоторым регистрам можно обращаться только как к ячейкам памяти данных. Для этого я нашел такую команду как st X, R(n) Она записывает содержимое регистра R в память по адресу X. Адресный регистр X состоит из 2 байт. XL и XH причем (XL=R26, XH=R27). Следовательно, для того чтобы записать что-либо, например, в регистр ADCSRA (адрес которого 0x7A) необходимо.
.def temp=R16 ldi temp,$40 // записываем в темп то что хотели бы записать в ADCSRA
ldi R26,0x7A // поскольку адрес не больше одного байта то он полностью укладывается в младший байт адресного регистра X
ldi R27,0 // в старшем байте адресного регистра Х ничего не должно быть
st X, temp // и собственно вуаля и содержимое temp уже в ADCSRA
Спасибо тем кто помог.
Добавлено спустя 1 минуту 1 секунду: avr123 спасибо за совет.
Меня тут уже упрекали в выдаче чересчур подробных ответов людям, которые не хотят думать сами. И все же наводящий вопрос - чем не приглянулась команда sts?
DK10000 писал(а):Как я понял к некоторым регистрам можно обращаться только как к ячейкам памяти данных
Ну вот и прекрасно. Только советую получше изучить систему команд и способы адресации, раз уж взялся писать на ассемблере. То же самое можно записать короче с использованием уже упомянутой команды sts:
“Меня тут уже упрекали в выдаче чересчур подробных ответов людям, которые не хотят думать сами. И все же наводящий вопрос - чем не приглянулась команда sts?”
Да я же вам говорю, что я новичок Более менее прилично пишу на С. Вот решил освоить и асм. Я просто не знал о такой команде sts. Хотя она гораздо удобней (для данного случая).
Знаете господа электронщики. С одной стороны конечно вы правы. Не стоит разжевывать ответ человеку, который не хочет сам до него дойти. Но с другой стороны, если человек только начинает. Может, стоит ему помочь, ведь бывают еще различные обстоятельства. А на тех, кто действительно хочет получить только все готовенькое может плюнуть. И забыть о них. А ориентироваться на тех, кто действительно хочет разобраться, но в силу неопытности нуждается в хорошем совете и т.д.