Ассемблер (ASM) для AVR в вопросах и ответах
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Уже ответили, а удалить нельзя. Странно.
В принципе, правильно, но если учесть, что
BREQ - строго равно
BRLO - строго меньше
операцию BRSH можно не проводить.
В принципе, правильно, но если учесть, что
BREQ - строго равно
BRLO - строго меньше
операцию BRSH можно не проводить.
- Реклама
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Да, спасибо за помощь! Я поправил в своей программке. У меня рядом программатор и отладочное устройство. Сегодня хочу проверить работу программы на железе. Если что-то не будет получаться, еще задам вопросы. Только не ругайте
, я не давно занялся программированием МК.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Еще вопрос по этой же программе. При сравнении двух чисел из Х и Y регистров необходимо сделать вычитание между этими регистровыми парами. Если разность чисел меньше числа 3, то эта разность должна приравниваться к 0 ( т. е как бы числа все равно совпадают).
Я сделал пока так: если числа из XL - YL, XH- YH точно совпадают, то конфигурация порта С такая:
sbi PORTC, 0
cbi PORTC, 1
cbi PORTC, 2
а если не совпадают, тогда я провожу вычитание между младшими байтами регистровых пар XL и YL.
cp XL, YL
cpc XH, YH
breq j1
brlo j2
rjmp j3
j1: sbi PORTC, 0
cbi PORTC, 1
cbi PORTC, 2
rjmp main
j2: sub YL, XL
cpi YL, 3
brlo j1
cbi PORTC, 0
sbi PORTC, 1
cbi PORTC, 2
rjmp main
j3: sub XL, YL
cpi XL, 3
brlo j1
cbi PORTC, 0
cbi PORTC, 1
sbi PORTC, 2
rjmp main
А как сделать вычитание между шестнадцатиразрядными числами находящимися в старших и младших байтах т.е YH - XH, YL - XL.
Я сделал пока так: если числа из XL - YL, XH- YH точно совпадают, то конфигурация порта С такая:
sbi PORTC, 0
cbi PORTC, 1
cbi PORTC, 2
а если не совпадают, тогда я провожу вычитание между младшими байтами регистровых пар XL и YL.
cp XL, YL
cpc XH, YH
breq j1
brlo j2
rjmp j3
j1: sbi PORTC, 0
cbi PORTC, 1
cbi PORTC, 2
rjmp main
j2: sub YL, XL
cpi YL, 3
brlo j1
cbi PORTC, 0
sbi PORTC, 1
cbi PORTC, 2
rjmp main
j3: sub XL, YL
cpi XL, 3
brlo j1
cbi PORTC, 0
cbi PORTC, 1
sbi PORTC, 2
rjmp main
А как сделать вычитание между шестнадцатиразрядными числами находящимися в старших и младших байтах т.е YH - XH, YL - XL.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Похоже народ городит селектор задач по длительности события... 
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А что мешает сначала вычесть значения, а потом решать на основе разницы с учетом знака? Определить события для "больше" и "меньше" если через эти два не пройдет - значит "в интервале".
- Реклама
Re: Ассемблер (ASM) для AVR в вопросах и ответах
И чего всех в математику тянет? При определении длительности события счетчиком с последующей селекцией можно ведь и другим способом результата добиться. 
(таблица переходов по "условным единицам")
(таблица переходов по "условным единицам")
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Надо попробовать. Если не трудно покажите пример.Alexeyslav писал(а):А что мешает сначала вычесть значения, а потом решать на основе разницы с учетом знака? Определить события для "больше" и "меньше" если через эти два не пройдет - значит "в интервале".
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Если правильно понял, то думаю, как то так
Спойлер
Код: Выделить всё
MAIN:
LDS XH,$70
LDS XL,$71
LDS YH,$80
LDS YL,$81
IN R22,PORTC
ANDI R22,$F8
;Еще вопрос по этой же программе. При сравнении двух чисел из Х и Y регистров необходимо
; сделать вычитание между этими регистровыми парами.
; Если разность чисел меньше числа 3, то эта разность должна приравниваться к 0
; ( т. е как бы числа все равно совпадают).
;Я сделал пока так: если числа из XL - YL, XH- YH точно совпадают, то конфигурация порта С такая:
; sbi PORTC, 0
; cbi PORTC, 1
; cbi PORTC, 2
;а если не совпадают, тогда я провожу вычитание между младшими байтами регистровых пар XL и YL.
;*****************************************************
; ANDI XL,$FC
; ANDI YL,$FC ; в данном конкретном случае можно убрать незначащие разряды, но
; это не будет общим случаем. Для чисел не кратных степени 2 так делать уже нельзя
LDI R18,HIGH(11) ;
LDI R19,LOW(11) ; для примера
LDI R20,HIGH(-11) ;
LDI R21,LOW(-11) ; для примера
SUB XL,YL
SBC XH,YH
CP XL,R19
CPC XH,R18
BRGE J2
CP XL,R21
CPC XH,R20
BRLT J3
J1:
SBR R22,$01
OUT PORTC,R22
; sbi PORTC, 0
; cbi PORTC, 1
; cbi PORTC, 2
rjmp main
J2:
SBR R22,$02
OUT PORTC,R22
; cbi PORTC, 0
; sbi PORTC, 1
; cbi PORTC, 2
rjmp main
J3:
SBR R22,$04
OUT PORTC,R22
; cbi PORTC, 0
; cbi PORTC, 1
; sbi PORTC, 2
rjmp main
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Спасибо akl !!! В этом примере я увидел все, что хотел
.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Господа! Имеется Mega8 + Assembler2 в AVRStudio4.
Надо на прерываниях по таймеру1 сделать генератор меандра со скважностью 2 и периодом ~100...200 msec на выводе PortC.1. Написал вот это, выходной сигнал образуется в обработчике прерываний инверсией вывода PortC.1, результат контролирую осциллографом и светодиодом - все работает, но есть вопрос: Почему-то период колебаний не зависит от значения компаратора, а зависит только от начального значения счетчика, ну и предделителя, конечно. Ведь прерывание возникает при совпадении компаратора и счетчика и частота прерываний должна зависеть от их обоих?
И вторая проблема - в том же обработчике прерываний сделал двойную инверсию вывода PortC.2, надеясь получить на этой ножке вместо меандра узкие импульсы с удвоенной частотой. Ан нет, вместо этого изредка проскакивают короткие импульсы и все. Если вторую инверсию убрать, то PortC.2 ведет себя точно так же, как и порт PortC.1 т.е выдаёт меандр. Почему не работает 2-я инверсия?
Буду очень благодарен если разрешите мои непонятки. Спасибо.
Надо на прерываниях по таймеру1 сделать генератор меандра со скважностью 2 и периодом ~100...200 msec на выводе PortC.1. Написал вот это, выходной сигнал образуется в обработчике прерываний инверсией вывода PortC.1, результат контролирую осциллографом и светодиодом - все работает, но есть вопрос: Почему-то период колебаний не зависит от значения компаратора, а зависит только от начального значения счетчика, ну и предделителя, конечно. Ведь прерывание возникает при совпадении компаратора и счетчика и частота прерываний должна зависеть от их обоих?
И вторая проблема - в том же обработчике прерываний сделал двойную инверсию вывода PortC.2, надеясь получить на этой ножке вместо меандра узкие импульсы с удвоенной частотой. Ан нет, вместо этого изредка проскакивают короткие импульсы и все. Если вторую инверсию убрать, то PortC.2 ведет себя точно так же, как и порт PortC.1 т.е выдаёт меандр. Почему не работает 2-я инверсия?
Буду очень благодарен если разрешите мои непонятки. Спасибо.
- Вложения
-
- MY_TEST_7.asm
- (2.73 КБ) 514 скачиваний
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А зачем таймер перезагружать, тем более без остановки счета?
Достаточно режима прерывания по совпадению с аппаратным сбросом таймера (CTC) - а значения менять в OCR1A.
Достаточно режима прерывания по совпадению с аппаратным сбросом таймера (CTC) - а значения менять в OCR1A.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вместо того чтобы читать с порта, отведи регистр в котором производи все изменения и выводи в порт только из него.
Таймер. Надо настроить его на режим в котором происходит его СБРОС по совпадению, тогда будет зависеть. А так ведь понятно, сравнение произошло вызвало прерывание а счетчик считает дальше до переполнения...
Таймер. Надо настроить его на режим в котором происходит его СБРОС по совпадению, тогда будет зависеть. А так ведь понятно, сравнение произошло вызвало прерывание а счетчик считает дальше до переполнения...
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Спасибо! Насчет Т/С1 вы правы! Что-то я ступил. Видимо, когда я пробовал СТС, был другой косяк... Сейчас включил СТС (1<<WGM12) и со счетчиком стало все ОК! А вот с двойной инверсией остаются непонятки.
Как же инвертировать порт не получив его состояния? Параллельно держать регистр, синхронизировать его с портом... Как-то муторно. А в остальном я так и делаю. Кстати, провел эксперимент: запретил все прерывания, а инверсии перенес в главный цикл - так в таком виде все работает! Правда, тайминги совсем не те, что нужны. Но двойная инверсия проходит!
Копаю дальше.
AlexeyslavAlexeyslav писал(а): Вместо того, чтобы читать с порта, отведи регистр в котором производи все изменения и выводи в порт только из него
Как же инвертировать порт не получив его состояния? Параллельно держать регистр, синхронизировать его с портом... Как-то муторно. А в остальном я так и делаю. Кстати, провел эксперимент: запретил все прерывания, а инверсии перенес в главный цикл - так в таком виде все работает! Правда, тайминги совсем не те, что нужны. Но двойная инверсия проходит!
Копаю дальше.
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
При всем моё уважении...BOB51 писал(а):А зачем таймер перезагружать, тем более без остановки счета?![]()
Достаточно режима прерывания по совпадению с аппаратным сбросом таймера (CTC) - а значения менять в OCR1A.
значение OCR1A при CTC кошернее использовать для получения требуемого периода повторения, а коэф. заполнения рулить через OCR1B
как-то так.
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Как насчёт размяться математикой?
Есть 10-бит значение АЦП с опорным напряжением 3.3 В, необходимо перевести в мВ. Требования: компактность и быстрота. Камень: Мега (аппаратный умножитель).
Какие решения видятся мне:
1. "В лоб": умножить на 3300/1024=3,22265625 или подобное.
2. Почти "в лоб": умножить на 825 и потом просто отбросить младший байт (поделить на 256).
3. Который больше всего нравится мне:
Хитрый: число 3.22265625 имеет три идущие подряд двойки! А если кто помнит алгебру, дробь 1/9 равна 0.(1), т.е. имеет единицу в периоде. Таким образом, умножая на 9 можно представить это чисто в виде простой дроби: 3.22265625 ≈ 29/9, т.е. для преобразования достаточно просто умножить на 29 и поделить на 9. При этом погрешность будет меньше 1 МЗР на краю диапазона (3296,7 против 3296,3 мВ)!!!
Двухбайтное число (а умножив 1023 на 29 мы гарантировано не выйдем за пределы 32767) умножить на однобайтное элементарно, а вот поделить на однобайтное... В аппноте только деление двухбайтного на двухбайтное, занимает 19 слов и 243 такта. Наверняка можно упростить, не используя один старший байт. Или вообще заменить вычитанием
Как вам изврат?
UPD: результат в BCD приветствуется, но не обязателен.
Есть 10-бит значение АЦП с опорным напряжением 3.3 В, необходимо перевести в мВ. Требования: компактность и быстрота. Камень: Мега (аппаратный умножитель).
Какие решения видятся мне:
1. "В лоб": умножить на 3300/1024=3,22265625 или подобное.
2. Почти "в лоб": умножить на 825 и потом просто отбросить младший байт (поделить на 256).
3. Который больше всего нравится мне:
Хитрый: число 3.22265625 имеет три идущие подряд двойки! А если кто помнит алгебру, дробь 1/9 равна 0.(1), т.е. имеет единицу в периоде. Таким образом, умножая на 9 можно представить это чисто в виде простой дроби: 3.22265625 ≈ 29/9, т.е. для преобразования достаточно просто умножить на 29 и поделить на 9. При этом погрешность будет меньше 1 МЗР на краю диапазона (3296,7 против 3296,3 мВ)!!!
Двухбайтное число (а умножив 1023 на 29 мы гарантировано не выйдем за пределы 32767) умножить на однобайтное элементарно, а вот поделить на однобайтное... В аппноте только деление двухбайтного на двухбайтное, занимает 19 слов и 243 такта. Наверняка можно упростить, не используя один старший байт. Или вообще заменить вычитанием
Как вам изврат?
UPD: результат в BCD приветствуется, но не обязателен.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Повезло тебе Gudd-Head!
У меня в загашниках как раз есть деление на 9.
Не помню где взял. Работает до 93635 (десятичное) включительно.
Если разрядность наращивать по ходу вычисления, то тактов в 70-80 влезет.Поправил. Ошибся пока копи-пастил.
Не помню где взял. Работает до 93635 (десятичное) включительно.
Если разрядность наращивать по ходу вычисления, то тактов в 70-80 влезет.
Спойлер
Код: Выделить всё
R1 = делимое
Rw = R1
Rw <<= 3
Rw -= R1
Rw <<= 3
Rw += R1
Rw <<= 3
Rw -= R1
Rw <<= 4
Rw += R1
Rw += 7287
Rw >>= 16
Если R1>= 9378 то Rw++
Результат деления в Rw
Последний раз редактировалось Kavka Вт янв 29, 2013 20:59:03, всего редактировалось 1 раз.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Удалил.
Последний раз редактировалось akl Вт янв 29, 2013 13:53:01, всего редактировалось 1 раз.
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ещё раз, вы видели какая там погрешность? Специально посчитал: 0,013%.akl писал(а):По мне, искусственное введение погрешности при вычислении - зло.
Ещё не хватало сидеть крутить что-то (для достижения "моей точности" надо будет установить с точностью до 0,5 мВ), ставить многооборотный потенциометр и, по-хорошему, шунтирующую ёмкость. В данном случае не подходит потому что опора — напряжение питания.akl писал(а):Установить для исполнения 3,3V опорное напряжение 3.072V, для 5V - 4.096V
Пффф... проще взять из аппнота "16 / 16 = 16 + 16 bit unsigned (Code Optimized)". Или вкурить что Kavka предложил.akl писал(а):Да, будут 32-разрядные числа, но Вы же пишете на великом и могучем.
А зря. Местами было конструктивно.akl писал(а):Удалил.
UPD: Деление на константу (до 63) позволяет сократить код из аппнота с 19 до 17 слов
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А не лучше ли масштабировать входное напряжение аналоговым способом? Это откинет все проблемы с математикой.
Подгонять точность все равно придется. Не уверен что внутренний ИОН обеспечит хорошую точность при измерении напряжений с погрешностью до 0.5мв - стабильности не хватит. Тут наверно придется думать о внешнем термостатированном ИОН? И к тому же тщательно продумать топологию платы и материалы из которых она изготовлена, не ровен час с такими требованиями можно и на паразитных термоэлектрических эффектах споткнуться.
Да, и как ты собрался достичь 0.5мв, тогда как квант при 12битах и опоре 3.3В составляет примерно 0.8мв?
Подгонять точность все равно придется. Не уверен что внутренний ИОН обеспечит хорошую точность при измерении напряжений с погрешностью до 0.5мв - стабильности не хватит. Тут наверно придется думать о внешнем термостатированном ИОН? И к тому же тщательно продумать топологию платы и материалы из которых она изготовлена, не ровен час с такими требованиями можно и на паразитных термоэлектрических эффектах споткнуться.
Да, и как ты собрался достичь 0.5мв, тогда как квант при 12битах и опоре 3.3В составляет примерно 0.8мв?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Gudd-Head, вкуривать особо нечего - 68-71 тактов работает разложенная не регистрах процедурка. Занимает порядка 140 байт. Можно сдвиги в циклы завернуть или подпрограммами сделать - размер уменьшиться, чуть время вырастет.
Но прикол не в этом!
И я тоже.
А, как говориться, слона то и не заметили.
Но прикол не в этом!
Ну, ёлки-палки. И куча народу повелось.Gudd-Head писал(а):Как насчёт размяться математикой?![]()
Камень: Мега (аппаратный умножитель).
2. Почти "в лоб": умножить на 825 и потом просто отбросить младший байт (поделить на 256).
Как вам изврат?![]()
А, как говориться, слона то и не заметили.
Спойлер
Код: Выделить всё
;******************************************************************************
;* Unsigned multiply of two 16bits numbers with 24bits result.
;* r18:r17:r16 = r23:r22 * r21:r20
;* STATISTICS
;* Cycles : 14 + ret
;* Words : 10 + ret
;* Register usage: r0 to r1, r16 to r18 and r20 to r23 (9 registers)
;******************************************************************************
mul16x16_24:
mul r23, r21 ; ah * bh
mov r18, r0
mul r22, r20 ; al * bl
movw r17:r16, r1:r0
mul r23, r20 ; ah * bl
add r17, r0
adc r18, r1
mul r21, r22 ; bh * al
add r17, r0
adc r18, r1
retКогда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)



