Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

Уже ответили, а удалить нельзя. Странно.

В принципе, правильно, но если учесть, что
BREQ - строго равно
BRLO - строго меньше
операцию BRSH можно не проводить.
Реклама
МКС
Встал на лапы
Сообщения: 147
Зарегистрирован: Чт янв 10, 2013 21:03:18

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение МКС »

Да, спасибо за помощь! Я поправил в своей программке. У меня рядом программатор и отладочное устройство. Сегодня хочу проверить работу программы на железе. Если что-то не будет получаться, еще задам вопросы. Только не ругайте :) , я не давно занялся программированием МК.
Реклама
МКС
Встал на лапы
Сообщения: 147
Зарегистрирован: Чт янв 10, 2013 21:03:18

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.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15558
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

Похоже народ городит селектор задач по длительности события... 8)
Реклама
Эиком - электронные компоненты и радиодетали
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Alexeyslav »

А что мешает сначала вычесть значения, а потом решать на основе разницы с учетом знака? Определить события для "больше" и "меньше" если через эти два не пройдет - значит "в интервале".
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15558
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

И чего всех в математику тянет? При определении длительности события счетчиком с последующей селекцией можно ведь и другим способом результата добиться. :)
(таблица переходов по "условным единицам") 8)
Реклама
МКС
Встал на лапы
Сообщения: 147
Зарегистрирован: Чт янв 10, 2013 21:03:18

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение МКС »

Alexeyslav писал(а):А что мешает сначала вычесть значения, а потом решать на основе разницы с учетом знака? Определить события для "больше" и "меньше" если через эти два не пройдет - значит "в интервале".
Надо попробовать. Если не трудно покажите пример.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение 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
МКС
Встал на лапы
Сообщения: 147
Зарегистрирован: Чт янв 10, 2013 21:03:18

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение МКС »

Спасибо akl !!! В этом примере я увидел все, что хотел :shock: :) .
Аватара пользователя
Vlad399
Открыл глаза
Сообщения: 57
Зарегистрирован: Сб фев 28, 2009 19:25:24
Откуда: MSK

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Vlad399 »

Господа! Имеется Mega8 + Assembler2 в AVRStudio4.
Надо на прерываниях по таймеру1 сделать генератор меандра со скважностью 2 и периодом ~100...200 msec на выводе PortC.1. Написал вот это, выходной сигнал образуется в обработчике прерываний инверсией вывода PortC.1, результат контролирую осциллографом и светодиодом - все работает, но есть вопрос: Почему-то период колебаний не зависит от значения компаратора, а зависит только от начального значения счетчика, ну и предделителя, конечно. Ведь прерывание возникает при совпадении компаратора и счетчика и частота прерываний должна зависеть от их обоих?
И вторая проблема - в том же обработчике прерываний сделал двойную инверсию вывода PortC.2, надеясь получить на этой ножке вместо меандра узкие импульсы с удвоенной частотой. Ан нет, вместо этого изредка проскакивают короткие импульсы и все. Если вторую инверсию убрать, то PortC.2 ведет себя точно так же, как и порт PortC.1 т.е выдаёт меандр. Почему не работает 2-я инверсия?
Буду очень благодарен если разрешите мои непонятки. Спасибо.
Вложения
MY_TEST_7.asm
(2.73 КБ) 514 скачиваний
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15558
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение BOB51 »

А зачем таймер перезагружать, тем более без остановки счета? :shock:
Достаточно режима прерывания по совпадению с аппаратным сбросом таймера (CTC) - а значения менять в OCR1A. :tea:
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Alexeyslav »

Вместо того чтобы читать с порта, отведи регистр в котором производи все изменения и выводи в порт только из него.
Таймер. Надо настроить его на режим в котором происходит его СБРОС по совпадению, тогда будет зависеть. А так ведь понятно, сравнение произошло вызвало прерывание а счетчик считает дальше до переполнения...
Аватара пользователя
Vlad399
Открыл глаза
Сообщения: 57
Зарегистрирован: Сб фев 28, 2009 19:25:24
Откуда: MSK

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Vlad399 »

Спасибо! Насчет Т/С1 вы правы! Что-то я ступил. Видимо, когда я пробовал СТС, был другой косяк... Сейчас включил СТС (1<<WGM12) и со счетчиком стало все ОК! А вот с двойной инверсией остаются непонятки.
Alexeyslav писал(а): Вместо того, чтобы читать с порта, отведи регистр в котором производи все изменения и выводи в порт только из него
Alexeyslav
Как же инвертировать порт не получив его состояния? Параллельно держать регистр, синхронизировать его с портом... Как-то муторно. А в остальном я так и делаю. Кстати, провел эксперимент: запретил все прерывания, а инверсии перенес в главный цикл - так в таком виде все работает! Правда, тайминги совсем не те, что нужны. Но двойная инверсия проходит!
Копаю дальше.
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение GP1 »

BOB51 писал(а):А зачем таймер перезагружать, тем более без остановки счета? :shock:
Достаточно режима прерывания по совпадению с аппаратным сбросом таймера (CTC) - а значения менять в OCR1A. :tea:
При всем моё уважении...
значение OCR1A при CTC кошернее использовать для получения требуемого периода повторения, а коэф. заполнения рулить через OCR1B
как-то так. :tea:
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение 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 такта. Наверняка можно упростить, не используя один старший байт. Или вообще заменить вычитанием :facepalm:
Как вам изврат? :))

UPD: результат в BCD приветствуется, но не обязателен.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение 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
Поправил. Ошибся пока копи-пастил.
Последний раз редактировалось Kavka Вт янв 29, 2013 20:59:03, всего редактировалось 1 раз.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

Удалил.
Последний раз редактировалось akl Вт янв 29, 2013 13:53:01, всего редактировалось 1 раз.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение 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 слов :(
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Alexeyslav »

А не лучше ли масштабировать входное напряжение аналоговым способом? Это откинет все проблемы с математикой.
Подгонять точность все равно придется. Не уверен что внутренний ИОН обеспечит хорошую точность при измерении напряжений с погрешностью до 0.5мв - стабильности не хватит. Тут наверно придется думать о внешнем термостатированном ИОН? И к тому же тщательно продумать топологию платы и материалы из которых она изготовлена, не ровен час с такими требованиями можно и на паразитных термоэлектрических эффектах споткнуться.

Да, и как ты собрался достичь 0.5мв, тогда как квант при 12битах и опоре 3.3В составляет примерно 0.8мв?
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение 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
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Ответить

Вернуться в «AVR»