Ассемблер (ASM) для AVR в вопросах и ответах
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Здравствуйте ребята! Прогу пишу на Ассемблере для МК Atmega8. Подскажите как из регистровой пары (например Х - регистр) сделать двухбайтный счетчик с инкрементом и декрементом?
- Реклама
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Т.е. при достижении числа 256 xl обнулится, а в младшем бите xh запишется 1?
В случае с adiw/sbiw обрабатывается сразу вся регистровая пара
Xh:Xl, а не раздельно младший и старший байты.

Xh:Xl, а не раздельно младший и старший байты.
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
- Реклама
Иногда бывает полезно псевдочтение в регистр с целью изменить содержимое регистровой пары.
Код: Выделить всё
LD R0,X+; инкремент XH:XL
LD R0,-X; декремент XH:XLХм, приколюха. Не знал. Спасибо.
Docendo discimus
А чем оно лучше ADIW, SBIW ? Тем, что флаги не трогает ?
именно тем и лучше.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Ёще раз благодарю за ответы! Помогите пожалуйста решить еще одну проблему в этом же проекте. Я использую АЦП МК Atmega8, он десятибитный.
Необходимо напряжение от 0 до (примерно) 5 Вольт разбить на 511 шагов. Для этого мне надо использовать всего девять бит регистров преобразования ADCL, ADCH. Если использовать все десять бит, то в младшем бите регистра ADCL появляется сигнал ошибки, видимо вызванный шумом МК и внешними наводками. Поэтому я пытаюсь сделать так: сначала копирую содержимое регистра ADCL в регистр XL, ADCH в XH. Далее мне надо сделать логический сдвиг вправо всей регистровой пары X c переносом младшего бита регистра ХH в старший бит XL. При этом, младший "вытесненный" бит регистра XL мне не нужен, а в старший бит регистра ХH надо записать ноль. Далее уже работать с этим числом. Таким образом я хочу с эмитировать девяти разрядный АЦП. Подскажите как сделать логический сдвиг вправо всей регистровой пары X?
Картинку прилагаю
Необходимо напряжение от 0 до (примерно) 5 Вольт разбить на 511 шагов. Для этого мне надо использовать всего девять бит регистров преобразования ADCL, ADCH. Если использовать все десять бит, то в младшем бите регистра ADCL появляется сигнал ошибки, видимо вызванный шумом МК и внешними наводками. Поэтому я пытаюсь сделать так: сначала копирую содержимое регистра ADCL в регистр XL, ADCH в XH. Далее мне надо сделать логический сдвиг вправо всей регистровой пары X c переносом младшего бита регистра ХH в старший бит XL. При этом, младший "вытесненный" бит регистра XL мне не нужен, а в старший бит регистра ХH надо записать ноль. Далее уже работать с этим числом. Таким образом я хочу с эмитировать девяти разрядный АЦП. Подскажите как сделать логический сдвиг вправо всей регистровой пары X?
Картинку прилагаю
- Вложения
-
- Логический сдвиг.jpg
- (88.01 КБ) 416 скачиваний
Снижать разрешение АЦП как то не очень.
Получили усечение. Хотя, правильнее сделать округление
Код: Выделить всё
LSR XH
ROR XLКод: Выделить всё
LSR XH
ROR XL
CLR R0
ADC XL,R0
ADC XH,R0
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Если младший бит смущает шумом, значение можно всегда пропустить через фильтр подвижного окна. И использовать все 10 бит.
[uquote="Kavka",url="/forum/viewtopic.php?p=3542170#p3542170"][uquote="Starichok51",url="/forum/viewtopic.php?p=3542126#p3542126"]4 байта сдвинуть 4 раза и без swap займет 16 циклов (а не тактов).[/uquote]
Именно поэтому я и спрашивал про быстрее 16 циклов/тактов.
[/uquote]
Starichok51, pyzhman, BOB51 спасибо!
4epemyxa спасибо за вариант кода с умножением!
Именно поэтому я и спрашивал про быстрее 16 циклов/тактов.
Starichok51, pyzhman, BOB51 спасибо!
4epemyxa спасибо за вариант кода с умножением!
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Здравствуйте! Помогите решить проблему с АЦП в МК ATmega8!
Если настраиваю тактовую частоту МК 2 МГц от встроенного генератора без кварца, использую восьмибитный результат преобразования по входам ADC0 и ADC1, тактовая частота АЦП при измерениии на ADC0 и ADC1 = 1 Мгц, 5 бит регистра ADMUX (ADLAR = 1) не меняется при переключении с ADC0 на ADC1. То при такой конфигурации программа далее идеально работает:
main:
ldi R16, 0b00100001
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m1: in R16, ADCSRA
sbrc R16, 6
rjmp m1
in R17, ADCH
out OCR2, R17
ldi R16, 0b00100000
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m2: in R16, ADCSRA
sbrc R16, 6
rjmp m2
in R18, ADCH
\
\ ;дальнейшие вычисления
\
rjmp main
Если настраиваю тактовую частоту МК 2 МГц от встроенного генератора без кварца, использую восьмибитный результат преобразования по входу ADC1 и десятибитный результат по входу ADC1, тактовая частота АЦП ADC1 = 1 Мгц, а ADC0 = 125 Кгц. 5 бит регистра ADMUX ADLAR = 1- при опросе входа ADC1 и ADLAR = 0 - при опросе входа ADC1, то программа с редкими ошибками, но работает:
main:
ldi R16, 0b00100001
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m1: in R16, ADCSRA
sbrc R16, 6
rjmp m1
in R17, ADCH
out OCR2, R17
ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11000100
out ADCSRA, R16
m2: in R16, ADCSRA
sbrc R16, 6
rjmp m2
in XH, ADCH
in XL, ADCL
\
\ ;дальнейшие вычисления
\
rjmp main
А если в этой программе убрать опрос входа ADC1 из цикла, то опрос ADC0 в цикле срабатывает однократно, а затем перестает работать с двухбайтным числом регистра XL, XH. Хотя эти два преобразования с ADC0 и ADC1 нужны для разных, не связанных друг с другом, участков программы
ldi R16, 0b00100001
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m1: in R16, ADCSRA
sbrc R16, 6
rjmp m1
in R17, ADCH
out OCR2, R17
main:
ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11000100
out ADCSRA, R16
m2: in R16, ADCSRA
sbrc R16, 6
rjmp m2
in XH, ADCH
in XL, ADCL
\
\ ;дальнейшие вычисления
\
rjmp main
Такое ощущение, что надо все время все время полностью перезагружать АЦП - выключить, потом опять включить и настроить. Подскажите где проблема? Есть ли нюансы при переключения АЦП с одной частоты на другую, при переключении входов, при переключении 5 бита – ADLAR?
Если настраиваю тактовую частоту МК 2 МГц от встроенного генератора без кварца, использую восьмибитный результат преобразования по входам ADC0 и ADC1, тактовая частота АЦП при измерениии на ADC0 и ADC1 = 1 Мгц, 5 бит регистра ADMUX (ADLAR = 1) не меняется при переключении с ADC0 на ADC1. То при такой конфигурации программа далее идеально работает:
main:
ldi R16, 0b00100001
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m1: in R16, ADCSRA
sbrc R16, 6
rjmp m1
in R17, ADCH
out OCR2, R17
ldi R16, 0b00100000
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m2: in R16, ADCSRA
sbrc R16, 6
rjmp m2
in R18, ADCH
\
\ ;дальнейшие вычисления
\
rjmp main
Если настраиваю тактовую частоту МК 2 МГц от встроенного генератора без кварца, использую восьмибитный результат преобразования по входу ADC1 и десятибитный результат по входу ADC1, тактовая частота АЦП ADC1 = 1 Мгц, а ADC0 = 125 Кгц. 5 бит регистра ADMUX ADLAR = 1- при опросе входа ADC1 и ADLAR = 0 - при опросе входа ADC1, то программа с редкими ошибками, но работает:
main:
ldi R16, 0b00100001
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m1: in R16, ADCSRA
sbrc R16, 6
rjmp m1
in R17, ADCH
out OCR2, R17
ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11000100
out ADCSRA, R16
m2: in R16, ADCSRA
sbrc R16, 6
rjmp m2
in XH, ADCH
in XL, ADCL
\
\ ;дальнейшие вычисления
\
rjmp main
А если в этой программе убрать опрос входа ADC1 из цикла, то опрос ADC0 в цикле срабатывает однократно, а затем перестает работать с двухбайтным числом регистра XL, XH. Хотя эти два преобразования с ADC0 и ADC1 нужны для разных, не связанных друг с другом, участков программы
ldi R16, 0b00100001
out ADMUX, R16
ldi R16, 0b11000001
out ADCSRA, R16
m1: in R16, ADCSRA
sbrc R16, 6
rjmp m1
in R17, ADCH
out OCR2, R17
main:
ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11000100
out ADCSRA, R16
m2: in R16, ADCSRA
sbrc R16, 6
rjmp m2
in XH, ADCH
in XL, ADCL
\
\ ;дальнейшие вычисления
\
rjmp main
Такое ощущение, что надо все время все время полностью перезагружать АЦП - выключить, потом опять включить и настроить. Подскажите где проблема? Есть ли нюансы при переключения АЦП с одной частоты на другую, при переключении входов, при переключении 5 бита – ADLAR?
Скорей ньюансы со считыванием регистров. Там имеется защёлка, когда один регистр читаешь то пока второй не прочитаешь защёлка не уберётся и новое значение в регистр не попадёт. Если у вас такая каша в программе происходит что работаете то в 8-битном режиме то в 10-битном просто тогда для 8 бит читайте оба регистра как и в 10-битном режиме. Видимо при переключениях и последующем чтении происходит срабатывание защелки.
Порядок чтения тоже важен.
Спойлер
Код: Выделить всё
ldi R16, 0b00100001
out ADMUX, R16
LDI R16,0b11000001
out ADCSRA, R16
m1:
SBIC ADCSRA,6
RJMP M1
IN R0,ADCL
in R17, ADCH
out OCR2, R17
main:
ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11010100
;ldi R16, 0b11000100
out ADCSRA, R16
m2:
SBIC ADCSRA,6
RJMP M2
in XL,ADCL
in XH,ADCH
; in XH, ADCH
; in XL, ADCL
RJMP GO- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Благодарю akl и Alexeyslav за ответы! Сейчас попробую исправить.



