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

Обсуждаем контроллеры компании Atmel.
User avatar
a1000
Первый раз сказал Мяу!
Posts: 31
Joined: Sun Oct 18, 2020 19:01:52
Location: Харьковская область

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

Post by a1000 »

BOB51 wrote:Тем более, что у АВРок косвенное чтение памяти имеется.
Знаю, я его и использовал. Спасибо за советы, разобрался сам. Ошибка была не в коде, он рабочий. Допустил детскую ошибку при прошивке.
Это Спарта! В смысле, ассемблер. Все ручками.
Реклама
User avatar
BOB51
Друг Кота
Posts: 15589
Joined: Tue Mar 16, 2010 22:02:27
Location: ДОНЕЦК

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

Post by BOB51 »

Прекрасно!
А теперь попробуйте используя только один байт буферного регистра вывести на индикацию вот такую трассу (или картинку при достаточной скорости смены информации):
Image
стрелочки показывают последовательность обхода светящейся точкой поля матрицы.
(направление обхода может быть и обратным).
8)
Подсказка - смотреть специфику адресации MAX7219.
:wink:
Реклама
User avatar
a1000
Первый раз сказал Мяу!
Posts: 31
Joined: Sun Oct 18, 2020 19:01:52
Location: Харьковская область

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

Post by a1000 »

Не совсем понятно
BOB51 wrote:один байт буферного регистра
Что имеется ввиду?
А вообще, для комфортной работы понядобится два РОН. Если совсем изаратиться и одного может хватить. Больше ведь никаких требований к алгоритму не вадвинуто. Самое тупое решение - через LDI кидаем в РОН нужное значение и засылаем его в SPDR.
Это Спарта! В смысле, ассемблер. Все ручками.
User avatar
BOB51
Друг Кота
Posts: 15589
Joined: Tue Mar 16, 2010 22:02:27
Location: ДОНЕЦК

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

Post by BOB51 »

В данном случае имеется ввиду чисто программный синтез картинки - без "заготовки в ПЗУ".
Продвижка точки только алгоритмом программы при использовании одного байта временного хранения данных, а не матрицы 8*8.
ессно и счетчики и подпрограмма вывода будут присутствовать - но то и для обычного алгоритма применяется.
8)
Реклама
Эиком - электронные компоненты и радиодетали
User avatar
a1000
Первый раз сказал Мяу!
Posts: 31
Joined: Sun Oct 18, 2020 19:01:52
Location: Харьковская область

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

Post by a1000 »

И чего там военного? Начинаем с правого верхнего угла. Кидаем в РОН, пусть будет R16, 0b00000001. В счётчик тоже ложим единицу.
Прогоняем отправку 0b00000001 восемь раз. Счётчик одновременно служит номером строки.
Когда достигли 8 - цикл со сдвигом R16 влево, декриментом счётчика и отправкой данных.
Когда достигли 1 - цикл аналогичный первому, без изменения R16.
Когда достигли 8 - цикл со сдвигом R16 вправо, декриментом счётчика и отправкой данных.
Мы вернулись в правый верхний угол.
Перед отправкой данных вызываем подпрограмму очистки дисплея.
Это Спарта! В смысле, ассемблер. Все ручками.
Реклама
User avatar
BOB51
Друг Кота
Posts: 15589
Joined: Tue Mar 16, 2010 22:02:27
Location: ДОНЕЦК

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

Post by BOB51 »

Вот и возврат к вопросу правильно выбранных координат.
Поскольку возможно получить две трактовки привязки строк и колонок - надо перед публикацией оговаривать что принимаем за строку, а что за колонку.
8)
Колонка - вертикальный ряд (аналогия позиции знакоместа и соответственно адресу ОЗУ MAX7219), а строка - горизонталь (аналогия позициям сегментов в знакоместе).
Почему так удобнее - смотрим вариант "беглой строчки" - перемещение вертикальной колонки, привязанной к адресу ячейки ОЗУ MAX7219 гораздо удобнее выполняется в буфере видеопамяти.
При том, что можно как угодно привязку делать. Это уже подбор более оптимального варианта на вкусы разработчика.
:wink:
Реклама
User avatar
a1000
Первый раз сказал Мяу!
Posts: 31
Joined: Sun Oct 18, 2020 19:01:52
Location: Харьковская область

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

Post by a1000 »

Если у вас одиночный модуль, тогда да, его можно вертеть как угодно. А если линейка из четырёх модулей, тут уже всё зафиксировано. А если трудно запомнить, что адрес это столбец, а отправляемый байт строка - не надо и начинать писать программы.
Это Спарта! В смысле, ассемблер. Все ручками.
User avatar
BOB51
Друг Кота
Posts: 15589
Joined: Tue Mar 16, 2010 22:02:27
Location: ДОНЕЦК

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

Post by BOB51 »

Как раз для нескольких модулей более выгодно "классическое" распределение точек (принятое в MAX7219) - по вертикали "сегментные", а по горизонтали "позиционные".
Строкой принято называть развертку по горизонтали.
Или развертку пакета из энного числа байт позиционного ("сегментного") кода в результате которого на дисплее отображается строка символов.
Хотя... терминология без схемы - штука весьма вредная (общепринятой обязательной не существует).
Посему и требуется вместе с прожкой выкладывать точную привязку и собственную, принятую для конкретной программы систему обозначений.
Иначе алгоритмы обработки у каждого из занимающихся одним и тем же вопросом будут кардинально отличаться (и в то же время быть справедливы для каждой из конкретных схем).
8)
А вот чего там на самом деле, когда матрицы в едином блоке на общей платке смонтированы - это надо конкретную платку смотреть и проверять.
8)
onwire
Родился
Posts: 17
Joined: Sat Feb 25, 2017 07:26:17

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

Post by onwire »

Понимаю что не в тему но в лом искать подходящую, что-то они все закрытые.
Видно АВР совсем не в моде нынче..
Надо стало быстрое деление константы 32767 на переменную 16 бит.
Придумал вот такую делилку.
Она проста, понятна, легко может быть приспособлена под любую разрядность
Для сравнения, делилка 16\16 из АВР аппноты тратит 260 тактов


DivU_TempHL_BT: ; TempH:L делимое (потом здесь будет удвоенный остаток)-
ldi Cnt, 1 ; -Buff:Temp делитель, R1:R0 округленный результат
mov One, Cnt
clr R1 clr R0
mov R2, One ; начальное значение маски для записи единиц в результат-
clr R3 clr Zero ; -она же будет счетчиком в цикле деления
cpi Temp, 128
cpc Buff, Zero
brsh shl
cpi Temp, 32 ; чтоб не повиснуть при делении на 0 :
cpc Buff, Zero
brsh swdv
ldi Temp, 32
swdv:
mov Buff, Temp ; для ускорения работы, если делитель <128-
clr Temp ; -можно сдвинуть делитель влево сразу на 8 бит
mov R3, One ; -и маску тоже
clr R2
shl:
sbrc Buff, 6
rjmp dv
lsl Temp rol Buff ; сделать делитель близким к делимому
lsl R2 rol R3 ; при этом приготовить маску
rjmp shl
dv:
cp Temp_L, Temp ; в цикле, сравнить делимое и делитель
cpc Temp_H, Buff
brlo shr
sub Temp_L, Temp ; если можно то вычесть
sbc Temp_H, Buff
or R1, R3 ; и маской внести единицу в результат
or R0, R2
shr:
lsr R3 ror R2 ; в любом случае, сдвинуть 1 в маске вправо
brcs edv ; (пока она совсем не обнулится, тогда выйти из цикла)
lsr Buff ror Temp ; и сдвинуть вправо делитель
rjmp dv
edv:
lsl Temp_L rol Temp_H ; удвоить остаток
cp Temp, Temp_L ; сравнить его с делителем
cpc Buff, Temp_H
adc R0, Zero ; округлить
adc R1, Zero
ret ; 185 тактов макс. время, мин. время 31 тактов
User avatar
Эйлер Леонард
Встал на лапы
Posts: 104
Joined: Mon Nov 04, 2019 09:58:29
Location: г. Нижний Тагил Свердл. обл.

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

Post by Эйлер Леонард »

Добрый день. Решил всё-таки освоить ассемблер для AVR. И как следовало ожидать - грабли полезли отовсюду. Простые инструкции проходят. Но даже присвоить литеральный псевдоним регистру - нет. Да многе чего. Компилятор просто пишет "не знаю что это такое" и падает. Вот сделал сложение двух 32-разрядных чисел, получилось. Инкремент 8-разрядных тоже работает. Я создаю файл с расширением S, а в файле на C/C++ функцию со спецификаторами доступа, либо напрямую с помощью ассемблерных вставок. В протеусе скомпоновал "испытательный стенд" из двух 7-сегментных индикаторов на ТМ1637 и контроллера ATtiny84.
На github.com(ссылка) есть библиотека которую мне хотелось бы местами использовать. Как говорится в релизе
"ТРЕБОВАНИЯ И ЗАВИСИМОСТИ:"
"Данная реализация написана на языке ассемблера "AVRASM2". Соответственно, она предназначена для разработки программных прошивок (firmware) на языке ассемблер, для микроконтроллеров Atmel AVR (8-bit)."
ссылка на библиотеку
Но, что-то идет не так.
main.cpp
Спойлер

Code: Select all

/* -std=c++11 
   -std=gnu++11
   Atmel Studio 7
   ATtiny84
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include "TM1637.h"

using namespace IO;
// два иникатора (красный и синий )
typedef TM1637<Pa1/*DIO_pin*/,Pa0/*CLK_pin*/> tm1637_0;
typedef TM1637<Pa3/*DIO_pin*/,Pa2/*CLK_pin*/> tm1637_1;


extern "C" {
extern uint32_t add32(uint32_t arg1, uint32_t arg2);[color=#808000]// сложение двух uint32_t чисел[/color]
//extern uint32_t inc32(uint8_t c);// инкремент до uint32_t числа
}

volatile uint32_t Counter0;
register uint8_t Counter1 asm("r2");//


ISR(INT0_vect){	
	//Counter0++;
	//asm volatile("inc %[VAL]" : [VAL]"=r" (Counter0) : "[VAL]" (Counter0));
	//asm volatile("inc %0" : "=r" (Counter0) : "0" (Counter0));
	//asm volatile("inc %0" : "+r"(Counter0) );

	asm volatile("inc r2");
	tm1637_0::output(Counter1);// синий
	//tm1637_1::output(Counter0);// красный
}

int main(void){
	
	PORTB |=  (1<<PB2); //Устанавливаем pull-up режим ножки PB2
	DDRB &= ~(1<<PB2); //Настраиваем ножку PB2 в режим входа
		 // Инициализация внешнего прерывания для вывода PB2
	GIMSK |= (1<<INT0);
	MCUCR |= (1<<ISC01)|(1<<ISC00); // Нарастающий фронт INT0 генерирует прерывание.
	sei(); // Разрешить все прерывания

tm1637_0::init();
tm1637_1::init();

uint32_t n = add32(222222,333333);
tm1637_1::output(n);
	
    while (1) {		
//if( Counter1 == 10 ){ tm1637_1::output(654321); }		
    }
}
add32.S
Этот работает. Вставляется так:
extern "C" {
extern uint32_t add32(uint32_t arg1, uint32_t arg2);// сложение двух uint32_t чисел
}
Спойлер

Code: Select all

	.global add32
	.func   add32
add32:
  add    r20, r16  ; Add low bytes // Добавить младшие байты
  adc    r21, r17  ; Add higher bytes with carry // Добавить старшие байты с переносом
  adc    r22, r18   
  adc    r23, r19
  adc    r24, r20   
  adc    r25, r21

	ret
	.endfunc
В файле...
uint32_t n = add32(222222,333333);
tm1637_1::output(n);// = 555555
НО шаг вправо, шаг влево - сплошные грабли. То - не то, это - не это. Извините за глупый вопрос - куда копать?
Attachments
Test-1.gif
Тренеровочно-испытательный стенд в протеусе
(120.15 KiB) Downloaded 244 times
User avatar
Gudd-Head
Друг Кота
Posts: 20092
Joined: Thu Sep 18, 2008 12:27:21
Location: Столица Мира Санкт-Петербург

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

Post by Gudd-Head »

Эммм... А зачем в СИ-шный код вставлять сложение двух регистров на АСМе?
Может, глобально задача совсем другая?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
User avatar
BOB51
Друг Кота
Posts: 15589
Joined: Tue Mar 16, 2010 22:02:27
Location: ДОНЕЦК

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

Post by BOB51 »

Есть два разных варианта:
"чистый ассемблер" - avrasm2
и
ассемблерные вставки в рамках Си
подход соответственно будет также различным.
Если с "чистым вариантом" особо проблем нету, то с ассемблерными вставками только СИшники помочь могут...
:roll:
User avatar
Эйлер Леонард
Встал на лапы
Posts: 104
Joined: Mon Nov 04, 2019 09:58:29
Location: г. Нижний Тагил Свердл. обл.

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

Post by Эйлер Леонард »

Gudd-Head, Задача - научиться. А там, как звезды покажут. В жизни всякое может пригодиться. Самообразование понимаете.
User avatar
Gudd-Head
Друг Кота
Posts: 20092
Joined: Thu Sep 18, 2008 12:27:21
Location: Столица Мира Санкт-Петербург

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

Post by Gudd-Head »

Тогда учитесь на чистом АСМе. К чему эти СИшные вставки?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
User avatar
BOB51
Друг Кота
Posts: 15589
Joined: Tue Mar 16, 2010 22:02:27
Location: ДОНЕЦК

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

Post by BOB51 »

Хорошая идея... только чуток посложнее...
8)
dgrett
Вымогатель припоя
Posts: 615
Joined: Sun Dec 28, 2014 21:54:05

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

Post by dgrett »

Здравствуйте, я где-то видел (а теперь не нахожу) пример масштабирования диапазонов. Например, есть некая величина, изменяющаяся от 0А до 8С. Как её растянуть до диапазона байта? Какова там математика? Может кто-нибудь тоже встречал? Подскажите, пж, где искать.
Я всё-всё узнAю и стану профессором.
Reflector
Поставщик валерьянки для Кота
Posts: 2089
Joined: Sun Jun 19, 2016 09:32:03

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

Post by Reflector »

[uquote="dgrett",url="/forum/viewtopic.php?p=4010207#p4010207"]Например, есть некая величина, изменяющаяся от 0А до 8С. Как её растянуть до диапазона байта? Какова там математика?[/uquote]
Очевидно же, что нужно умножать на 256 / 0x8C = ~1.83. Если под дробную часть выделить 7 бит, т.е. 128 будет равно 1, то 1.83 превращается в 1.83 * 128 = 234, что удобно, т.к. есть аппаратное умножение 8x8:
(234 * 0x0A) >> 7 = 18
(234 * 0x8C) >> 7 = 255
dgrett
Вымогатель припоя
Posts: 615
Joined: Sun Dec 28, 2014 21:54:05

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

Post by dgrett »

Понял, спасибо.
О, немного не так. 0А должно было стать нулём. Запутался.
Я всё-всё узнAю и стану профессором.
akl
Друг Кота
Posts: 4447
Joined: Fri Mar 07, 2008 06:54:43
Location: Ижевск

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

Post by akl »

Как вариант
X=[(CODE-10)*502+128]/256
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

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

Post by ARV »

между 8C и 0A лежит 130 чисел. если диапазон 0-255 приводить к этому количеству, то коэффициент будет не 1,8 а 1,97, т.е. почти 2.
следовательно, из кода надо отнять 10 и результат умножить на 2 - примерно то и выйдет, что надо.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Post Reply

Return to “AVR”