Страница 174 из 400
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб янв 26, 2013 15:23:25
akl
Уже ответили, а удалить нельзя. Странно.
В принципе, правильно, но если учесть, что
BREQ - строго равно
BRLO - строго меньше
операцию BRSH можно не проводить.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб янв 26, 2013 15:46:57
МКС
Да, спасибо за помощь! Я поправил в своей программке. У меня рядом программатор и отладочное устройство. Сегодня хочу проверить работу программы на железе. Если что-то не будет получаться, еще задам вопросы. Только не ругайте

, я не давно занялся программированием МК.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб янв 26, 2013 17:28:48
МКС
Еще вопрос по этой же программе. При сравнении двух чисел из Х и 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.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб янв 26, 2013 17:56:42
BOB51
Похоже народ городит селектор задач по длительности события...

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб янв 26, 2013 19:29:15
Alexeyslav
А что мешает сначала вычесть значения, а потом решать на основе разницы с учетом знака? Определить события для "больше" и "меньше" если через эти два не пройдет - значит "в интервале".
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб янв 26, 2013 20:18:19
BOB51
И чего всех в математику тянет? При определении длительности события счетчиком с последующей селекцией можно ведь и другим способом результата добиться.

(таблица переходов по "условным единицам")

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб янв 26, 2013 20:40:50
МКС
Alexeyslav писал(а):А что мешает сначала вычесть значения, а потом решать на основе разницы с учетом знака? Определить события для "больше" и "меньше" если через эти два не пройдет - значит "в интервале".
Надо попробовать. Если не трудно покажите пример.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс янв 27, 2013 04:14:05
akl
Если правильно понял, то думаю, как то так
Спойлер
Код: Выделить всё
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 в вопросах и ответах
Добавлено: Вс янв 27, 2013 08:07:22
МКС
Спасибо akl !!! В этом примере я увидел все, что хотел

.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс янв 27, 2013 15:56:30
Vlad399
Господа! Имеется Mega8 + Assembler2 в AVRStudio4.
Надо на прерываниях по таймеру1 сделать генератор меандра со скважностью 2 и периодом ~100...200 msec на выводе PortC.1. Написал вот это, выходной сигнал образуется в обработчике прерываний инверсией вывода PortC.1, результат контролирую осциллографом и светодиодом - все работает, но есть вопрос: Почему-то период колебаний не зависит от значения компаратора, а зависит только от начального значения счетчика, ну и предделителя, конечно. Ведь прерывание возникает при совпадении компаратора и счетчика и частота прерываний должна зависеть от их обоих?
И вторая проблема - в том же обработчике прерываний сделал двойную инверсию вывода PortC.2, надеясь получить на этой ножке вместо меандра узкие импульсы с удвоенной частотой. Ан нет, вместо этого изредка проскакивают короткие импульсы и все. Если вторую инверсию убрать, то PortC.2 ведет себя точно так же, как и порт PortC.1 т.е выдаёт меандр. Почему не работает 2-я инверсия?
Буду очень благодарен если разрешите мои непонятки. Спасибо.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс янв 27, 2013 16:14:26
BOB51
А зачем таймер перезагружать, тем более без остановки счета?
Достаточно режима прерывания по совпадению с аппаратным сбросом таймера (CTC) - а значения менять в OCR1A.

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс янв 27, 2013 16:18:21
Alexeyslav
Вместо того чтобы читать с порта, отведи регистр в котором производи все изменения и выводи в порт только из него.
Таймер. Надо настроить его на режим в котором происходит его СБРОС по совпадению, тогда будет зависеть. А так ведь понятно, сравнение произошло вызвало прерывание а счетчик считает дальше до переполнения...
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн янв 28, 2013 00:12:51
Vlad399
Спасибо! Насчет Т/С1 вы правы! Что-то я ступил. Видимо, когда я пробовал СТС, был другой косяк... Сейчас включил СТС (1<<WGM12) и со счетчиком стало все ОК! А вот с двойной инверсией остаются непонятки.
Alexeyslav писал(а):
Вместо того, чтобы читать с порта, отведи регистр в котором производи все изменения и выводи в порт только из него
Alexeyslav
Как же инвертировать порт не получив его состояния? Параллельно держать регистр, синхронизировать его с портом... Как-то муторно. А в остальном я так и делаю. Кстати, провел эксперимент: запретил все прерывания, а инверсии перенес в главный цикл - так в таком виде все работает! Правда, тайминги совсем не те, что нужны. Но двойная инверсия проходит!
Копаю дальше.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт янв 29, 2013 08:52:54
GP1
BOB51 писал(а):А зачем таймер перезагружать, тем более без остановки счета?
Достаточно режима прерывания по совпадению с аппаратным сбросом таймера (CTC) - а значения менять в OCR1A.

При всем моё уважении...
значение OCR1A при CTC кошернее использовать для получения требуемого периода повторения, а коэф. заполнения рулить через OCR1B
как-то так.

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт янв 29, 2013 10:31:33
Gudd-Head
Как насчёт размяться математикой?
Есть 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 в вопросах и ответах
Добавлено: Вт янв 29, 2013 12:44:09
Kavka
Повезло тебе Gudd-Head!

У меня в загашниках как раз есть деление на 9.
Не помню где взял. Работает до 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
Поправил. Ошибся пока копи-пастил.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт янв 29, 2013 13:13:31
akl
Удалил.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт янв 29, 2013 13:21:44
Gudd-Head
akl писал(а):По мне, искусственное введение погрешности при вычислении - зло.
Ещё раз, вы видели какая там погрешность? Специально посчитал: 0,013%.
akl писал(а):Установить для исполнения 3,3V опорное напряжение 3.072V, для 5V - 4.096V
Ещё не хватало сидеть крутить что-то (для достижения "моей точности" надо будет установить с точностью до 0,5 мВ), ставить многооборотный потенциометр и, по-хорошему, шунтирующую ёмкость. В данном случае не подходит потому что опора — напряжение питания.
akl писал(а):Да, будут 32-разрядные числа, но Вы же пишете на великом и могучем.
Пффф... проще взять из аппнота "16 / 16 = 16 + 16 bit unsigned (Code Optimized)". Или вкурить что
Kavka предложил.
akl писал(а):Удалил.
А зря. Местами было конструктивно.
UPD: Деление на константу (до 63) позволяет сократить код из аппнота с 19 до 17 слов

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт янв 29, 2013 21:52:29
Alexeyslav
А не лучше ли масштабировать входное напряжение аналоговым способом? Это откинет все проблемы с математикой.
Подгонять точность все равно придется. Не уверен что внутренний ИОН обеспечит хорошую точность при измерении напряжений с погрешностью до 0.5мв - стабильности не хватит. Тут наверно придется думать о внешнем термостатированном ИОН? И к тому же тщательно продумать топологию платы и материалы из которых она изготовлена, не ровен час с такими требованиями можно и на паразитных термоэлектрических эффектах споткнуться.
Да, и как ты собрался достичь 0.5мв, тогда как квант при 12битах и опоре 3.3В составляет примерно 0.8мв?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вт янв 29, 2013 22:45:44
Kavka
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