Ассемблер (ASM) для AVR в вопросах и ответах
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А у меня случалось на похожем примере: опрос матричной клавиатуры, первая строка кнопок "активируется" нулём с порта "B0", через кнопку - нуль поступает на pinB5.
cbi portB,0 ;активировать строку кнопок (0 активный = нажато)
nop ;cbi происходит в 2 такта поэтому pin здесь заценивать рано
sbic pinB,5 ;кнопка 1 = 0? (зажата?)
rjmp b2 ;НЕТ, к следующей кнопке
;...или далее
Как результат при отсутствии "nop" не работали все первые кнопки в строках.
cbi portB,0 ;активировать строку кнопок (0 активный = нажато)
nop ;cbi происходит в 2 такта поэтому pin здесь заценивать рано
sbic pinB,5 ;кнопка 1 = 0? (зажата?)
rjmp b2 ;НЕТ, к следующей кнопке
;...или далее
Как результат при отсутствии "nop" не работали все первые кнопки в строках.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
При вводе/выводе - да надо. Если клавиатура подключена через длинный шлейф, то может одного "nop" и не хватить.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
sbiw сама отработает за два такта и ничего не будет отложено "на потом". Там всё нормально.
А вот с кнопками у вас именно аппаратная беда - емкость входа, выставили значение и пройдёт сотни наносекунд пока оно установится, поэтому нужны какие-то задржки. Кстати когда плата загрязнится одного нопа может оказаться недостаточно - это потенциально проблемное место, работа которого зависит от "RACE CONDITION". Поэтому я делаю наоборот - сначала читаю кнопки с ПРЕДЫДУЩЕЙ линии, потом меняю линию опроса - к следующему такту(через 1-2мс) всё давно уже устаканится.
А вот с кнопками у вас именно аппаратная беда - емкость входа, выставили значение и пройдёт сотни наносекунд пока оно установится, поэтому нужны какие-то задржки. Кстати когда плата загрязнится одного нопа может оказаться недостаточно - это потенциально проблемное место, работа которого зависит от "RACE CONDITION". Поэтому я делаю наоборот - сначала читаю кнопки с ПРЕДЫДУЩЕЙ линии, потом меняю линию опроса - к следующему такту(через 1-2мс) всё давно уже устаканится.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Для "устаканивания" данных вместо NOPов обычно хватает
Код: Выделить всё
CBI PORTB,0
RCALL PAUSE_RET ; 7 тактов
SBIC PINB,5
;................................
;................................
;................................
RET
;********************************
PAUSE_RET:
RET
;********************************
NOP не нужен. Вот режим работы модуля сравнения имеет значение, т.к. OCR1 может принять данные не только напрямую, а ещё и защёлкнуться в буфере. Перенос содержимого буфера в OCR1 произойдет при выполнении условия режима работы.Серый_ писал(а):в данном случае "по научному" нужно ставить "nop"?
sbiw x,1 ;минуснуть 1 из пары (выполнится за 2 такта)
nop ;(поэтому пустотакт перед отправкой куда-либо)
out ocr1AH,xH ;отправить
out ocr1AL,xL
Сдвиг 4-байтового числа на 4 бита быстрее 16 тактов
Приветствую.
Коллеги, есть ли способ сдвинуть 4-байтовое число на 4 бита быстрее 16 тактов.
Для определённости пусть используются 4 старших регистра, а сдвиг вправо.
Сомнения терзают из-за наличия командочки swap...
Коллеги, есть ли способ сдвинуть 4-байтовое число на 4 бита быстрее 16 тактов.
Для определённости пусть используются 4 старших регистра, а сдвиг вправо.
Сомнения терзают из-за наличия командочки swap...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Для "устаканивания" данных вместо NOPов обычно хватает... PAUSE_RET:
В общем да, было так:
Спойлер
sbi portB,0 ;деактивация 1-й строкиcbi portB,1 ;и сразу активация 2-й строки
Были ложные срабатывания в 1-ом столбце (по нажатию первых кнопок любой строки). Между данными командами вклинил:
rcall bl_zvon ;блокировка звона меж строк
bl_zvon:
nop
ret ;и того 3+1+4 такта
Ложных срабатываний не выдавил при всём желании.
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Перед применением swap нужно в текущем регистре на место младшего ниббла поместить младший ниббл старшего регистра. И уложиться в меньше 3-х тактов, т.е. в два или один. Хороша задачка.
Docendo discimus
Re: Сдвиг 4-байтового числа на 4 бита быстрее 16 тактов
Приветствую.
Коллеги, есть ли способ сдвинуть 4-байтовое число на 4 бита быстрее 16 тактов.
Для определённости пусть используются 4 старших регистра, а сдвиг вправо.
Сомнения терзают из-за наличия командочки swap...
Коллеги, есть ли способ сдвинуть 4-байтовое число на 4 бита быстрее 16 тактов.
Для определённости пусть используются 4 старших регистра, а сдвиг вправо.
Сомнения терзают из-за наличия командочки swap...
Для одиночного байта
SWAP Rd - обмен тетрадами
и
XCH Z,Rd - для обмена только с ОЗУ по указателю в Z (но не во всех подгруппах МК и для АВРстудио 4.19 неведомое)
плюсиком макрос обмена между регистрами
Код: Выделить всё
.macro XCHRR
EOR @0,@1
EOR @1,@0
EOR @0,@1
.endmacroЕсли было б в наборе подобие
XCHD a,@Ri
как у mcs51 -возможно было бы проще.
Иначе макрос делать придется...

Re: Ассемблер (ASM) для AVR в вопросах и ответах
pyzhman, BOB51, как работает swap и про обмен xor-ом я знаю. Спасибо за напоминание.
PS: Что-то "велосипед" на swap-е меньше 17 тактов не выходит. Видать никак...
Хороша задачка.
Да, есть такое. Решил, вот, поискать на просторах интернета, да людей поспрашивать прежде чем предпринять попытку изобрести велосипед.PS: Что-то "велосипед" на swap-е меньше 17 тактов не выходит. Видать никак...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Starichok51
- Модератор
- Сообщения: 19039
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
4 байта сдвинуть 4 раза и без swap займет 16 циклов (а не тактов).
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
SWAP - быстрый обмен тетрадами.
(7-4) <-> (3-0) в текущем регистре меняются местами тетрады.
Использовался для скоростных преобразований в двоично-десятичной математике (Упакованный двоично-десятичный формат, ежли склероз не изменяет). Также удобен при формировании тетрадных цифирек под БИС с аппаратным дешифратором семисегментного кода.
На сегодня такие алгоритмы весьма редко применяются, ибо почти всюду используется табличный знакогенератор, да и быстродействие МК заметно возросло.
Из современных СБИС в которых возможно встретиться с режимом тетрадного дешифратора - MAX7219 к примеру.

(7-4) <-> (3-0) в текущем регистре меняются местами тетрады.
Использовался для скоростных преобразований в двоично-десятичной математике (Упакованный двоично-десятичный формат, ежли склероз не изменяет). Также удобен при формировании тетрадных цифирек под БИС с аппаратным дешифратором семисегментного кода.
На сегодня такие алгоритмы весьма редко применяются, ибо почти всюду используется табличный знакогенератор, да и быстродействие МК заметно возросло.
Из современных СБИС в которых возможно встретиться с режимом тетрадного дешифратора - MAX7219 к примеру.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
4 байта сдвинуть 4 раза и без swap займет 16 циклов (а не тактов).
Именно поэтому я и спрашивал про быстрее 16 циклов/тактов.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Если допускается получение результата в других регистрах и сдвиг не циклический, то можно быстрее 16-ти:
Это вправо, результат в R5-R2
Код: Выделить всё
ldi r16,16 ;сдвиг на 4
mul r31,r16
movw r4,r0
mul r30,r16
mov r3,r0
or r4,r1
mul r29,r16
mov r2,r0
or r3,r1
mul r28,r16
or r2,r1Это вправо, результат в R5-R2
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Тогда уж просто умножение на 16 одним разом. Равноценно сдвигу влево на 4 бита.
Но... с занесением младших нулей, а не замена тетрад - придется добавлять несколько команд
для помещения старшей тетрады на новое место.
Хотя... как алгоритм... ЗАСЛУЖИВАЕТ ВНИМАНИЯ, особо в тех МК, где есть аппаратное умножение.

Но... с занесением младших нулей, а не замена тетрад - придется добавлять несколько команд
для помещения старшей тетрады на новое место.
Хотя... как алгоритм... ЗАСЛУЖИВАЕТ ВНИМАНИЯ, особо в тех МК, где есть аппаратное умножение.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Так тут и есть умножение на 16, которое "разбирает" регистр на две тетрады с одновременным обнулением второй. Причем для сдвига влево или вправо меняется только порядок сборки тетрад в байты.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
То для одного байта - эквивалент SWAP, а вот при длинном составном в несколько регистров... надо отслеживать, что удобнее...


Re: Ассемблер (ASM) для AVR в вопросах и ответах
Да, если результат умножения байта собрать в один регистр, то получается точный эквивалент SWAP. Естественно, смысла в этом нет - что может быть быстрее одноциклового SWAP. А вот использовать умножение на 16 для выделения чистых тетрад без дополнительных ANDI очень даже быстро.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
У меня были подобные задачи по смещению части битового поля для ЖКИ индикаторов на основе NJU6432 и KS0035...
Там весьма помудрить порой приходится - помимо прочего зависит и от конкретной привязки сегментов к ячейкам ОЗУ (при изготовлении индикатора).

Там весьма помудрить порой приходится - помимо прочего зависит и от конкретной привязки сегментов к ячейкам ОЗУ (при изготовлении индикатора).

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Здравствуйте.
Коротко о себе и моём уровне подготовки:
Я перевожу один проект под свои нужды. Основная цель - замена дисплея на цветной TFT.
Хоть я и радиолюбитель с определённым стажем, но мой род занятий и образование не связаны с электроникой и тем более программированием. Так же нет возможности "развиваться в команде" - то есть одиночество абсолютное.
Тем не менее три месяца тотального красноглазия над AVR Assembler-ом дало ощутимые плоды.
Суть проблемы такая:
При выводе текста на дисплеи бОльших размеров моноширинный шрифт смотрится (мяхко говоря) неуклюже. (кстати шрифты делаю сам, практически в ручную, на коленке, попиксельно).
Решил использовать пропорциональный шрифт и создать свою таблицу ASCII. Полный знак примерно 8x16px. Три нижних строки пустые для вывода хвостов от всяких q, y, g, ... щ, ц, ... и запятых.
Ну и естественно вопрос: как реализовать нахождение шрифта в таблице символов и получить ширину символа при выводе.
Готовых решений не прошу.
Буду признателен за любую информацию, которая укажет правильное направление.
Коротко о себе и моём уровне подготовки:
Я перевожу один проект под свои нужды. Основная цель - замена дисплея на цветной TFT.
Хоть я и радиолюбитель с определённым стажем, но мой род занятий и образование не связаны с электроникой и тем более программированием. Так же нет возможности "развиваться в команде" - то есть одиночество абсолютное.
Тем не менее три месяца тотального красноглазия над AVR Assembler-ом дало ощутимые плоды.
Суть проблемы такая:
При выводе текста на дисплеи бОльших размеров моноширинный шрифт смотрится (мяхко говоря) неуклюже. (кстати шрифты делаю сам, практически в ручную, на коленке, попиксельно).
Решил использовать пропорциональный шрифт и создать свою таблицу ASCII. Полный знак примерно 8x16px. Три нижних строки пустые для вывода хвостов от всяких q, y, g, ... щ, ц, ... и запятых.
Ну и естественно вопрос: как реализовать нахождение шрифта в таблице символов и получить ширину символа при выводе.
Готовых решений не прошу.
Буду признателен за любую информацию, которая укажет правильное направление.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Да в общем-то, так же, как и на Си или другом языке. Традиционно есть 2 подхода:
1. При описании каждого символа шрифта указываетс его ширина. Т.е. в массиве байтов, описывающих пикселы символа первый байт задает ширину этого символа.
2. Создается отдельная таблица, в которой хранится ширина и адрес начала символа в знакогенераторе, а сам знакогенератор в отдельной таблице
Оба подхода вынуждают использовать не традиционный массив с одинаковыми элементами, а "хитрый" массив (точнее - по сути список), в котором размер всех элементов разный, а значит адрес доступа к любому элементу уже невозможно вычислить простым умножением размера на номер элемента.
Поэтому в первом подходе приходится "сканировать" знакогенератор с самого первого символа, всякий раз вычисляя адрес начала следующего (первый байт - количество столбцов, умножаем на количество строк, прибавляем 1 и получаем адрес следующего символа) до тех пор, пока не найдется нужный. Процесс доступа долгий, зато создание знакогенератора простое.
Во втором случае наличие отдельной таблицы с размерами и адресами начала символа в знакогенераторе (т.е. по сути это таблица индексов, как в базах данных) резко ускоряет доступ к символам: все элементы этой таблицы одинаковы по размеру, поэтому вычисление реального адреса символа в шрифте осуществляется просто. Но создавать знакогенератор по этому принципу гораздо сложнее.
Так же в первом случае сложновато делать знакогенератор для шрифтов с "пропуском символов", например, не всегда нужна псевдографика или там латинские символы... Потому что в этом случае надо помимо сканирования списка символов еще и отслеживать "дыры". Во втором случае это проще: в индексной таблице просто пропускаются "лишние" позиции, и все.
Кстати, есть специальные программы для создания пиксельных шрифтов, поддерживающих ОБА способа, и позволяющих практически мышкой нарисовать любой знакогенератор и получить на выходе исходник со всеми данными на любом языке программирования, в т.ч. и ассемблере. Рекомендую поискать. Ключевые слова LCD font editor или generator
1. При описании каждого символа шрифта указываетс его ширина. Т.е. в массиве байтов, описывающих пикселы символа первый байт задает ширину этого символа.
2. Создается отдельная таблица, в которой хранится ширина и адрес начала символа в знакогенераторе, а сам знакогенератор в отдельной таблице
Оба подхода вынуждают использовать не традиционный массив с одинаковыми элементами, а "хитрый" массив (точнее - по сути список), в котором размер всех элементов разный, а значит адрес доступа к любому элементу уже невозможно вычислить простым умножением размера на номер элемента.
Поэтому в первом подходе приходится "сканировать" знакогенератор с самого первого символа, всякий раз вычисляя адрес начала следующего (первый байт - количество столбцов, умножаем на количество строк, прибавляем 1 и получаем адрес следующего символа) до тех пор, пока не найдется нужный. Процесс доступа долгий, зато создание знакогенератора простое.
Во втором случае наличие отдельной таблицы с размерами и адресами начала символа в знакогенераторе (т.е. по сути это таблица индексов, как в базах данных) резко ускоряет доступ к символам: все элементы этой таблицы одинаковы по размеру, поэтому вычисление реального адреса символа в шрифте осуществляется просто. Но создавать знакогенератор по этому принципу гораздо сложнее.
Так же в первом случае сложновато делать знакогенератор для шрифтов с "пропуском символов", например, не всегда нужна псевдографика или там латинские символы... Потому что в этом случае надо помимо сканирования списка символов еще и отслеживать "дыры". Во втором случае это проще: в индексной таблице просто пропускаются "лишние" позиции, и все.
Кстати, есть специальные программы для создания пиксельных шрифтов, поддерживающих ОБА способа, и позволяющих практически мышкой нарисовать любой знакогенератор и получить на выходе исходник со всеми данными на любом языке программирования, в т.ч. и ассемблере. Рекомендую поискать. Ключевые слова LCD font editor или generator
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!