Ассемблер (ASM) для AVR в вопросах и ответах
Дак мы тут уж 100500 способов реализовали, просто мусолим их, от делать нечего 
- Реклама
ROR R16 ROL R17 ROR R16 ROL R17... тоже можно в одну строчку написать, студия схомячит и не подавитсяploop писал(а):Да, на Си хорошо получается, даже в одну строчку
Kavka, в этих примерах все конечно красиво и правильно, но тема именно про ассемблер, и мы тут стараемся у кого длинкороче и быстрее код, так что Сишные программы нам немного неподходят
вставлю свои "5коп"

а если прикрутить SWAP, то и 16 байт флеша под таблицу хватитEngineer_Keen писал(а): О! Кстати, если не жалко 256 байт флеша...
Где-то я это уже сегодня слышал. А, ну да, на предыдущей страницеGP1 писал(а):а если прикрутить SWAP, то и 16 байт флеша под таблицу хватит
У меня быстро и компактно не получилось, я правда особо не заморачивался. Может представите свой код, интересно как он отличается от моего?
а тут "быстро и компактно" не получится
либо "большая" таблица и быстрое выполнение
либо "маленькая" таблица и более долгое выполнение
впрочем как обычно - где-то выиграл, где-то проиграл.
либо "большая" таблица и быстрое выполнение
либо "маленькая" таблица и более долгое выполнение
впрочем как обычно - где-то выиграл, где-то проиграл.
просмотрелГде-то я это уже сегодня слышал. А, ну да, на предыдущей странице
- Реклама
- Сообщения: 1163
- Зарегистрирован: Ср янв 05, 2011 16:25:15
... если таблица выровнена на 256-байтной границе, то все немного лучшеEngineer_Keen писал(а):К таблице придется обращаться 2 раза, а это уже 14 тактов (по два раза 2xLDI Z, 2xZ+адрес+LPM) + выделение младшего полубайта адреса (2 раза) + склейка результатов 2х операций с таблицами. Больше 20 тактов и почти столько же флеша
Код: Выделить всё
ldi ZH,high(table<<1) ; 1
mov ZL,r16 ; 1
andi ZL,0xF ; 1
lpm ; 3
swap r16 ; 1
mov ZL,r16 ; 1
andi ZL,0xF ; 1
lpm r16,Z ; 3
swap r16 ; 1
add r16,r0 ; 1 PS. ... для 256 байтной таблицы все аналогично ....
Да можно и так... По всякому можно. Но лучше потратить несколько байт или тактов, чем через месяц вкуривать, что ты там накодил 


Без таблицы быстрее народ делает.ChipKiller писал(а):... всего 14 тактов
PS. ... для 256 байтной таблицы все аналогично ....
И тут.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
итог - табличный декодер для величины размерностью в один байт - максимальная скорость и максимальный объём ПЗУ (или ОЗУ) требуется базовый адрес в двухбайтовом указателе,
сдвиг при участии 3-х регистров (опять же для величины размерностью в один байт) - долго, но с минимальными затратами ПЗУ
сдвиг при участии 3-х регистров (опять же для величины размерностью в один байт) - долго, но с минимальными затратами ПЗУ
Да, а если даже уж так, то тоже можно ещё слово/такт урыть, заменив mov + andi одним xor-ом (выиграть этому коду соревнование по бит-реверсу это не поможет, но как пример применения xor пойдётChipKiller писал(а): все немного лучшеКод: Выделить всё
ldi ZH,high(table<<1) ; 1 mov ZL,r16 ; 1 andi ZL,0xF ; 1 lpm ; 3 swap r16 ; 1 mov ZL,r16 ; 1 andi ZL,0xF ; 1 lpm r16,Z ; 3 swap r16 ; 1 add r16,r0 ; 1
Код: Выделить всё
ldi ZH,high(table<<1) ; 1
mov ZL,r16 ; 1 (A)
andi ZL,0xF ; 1 (B)
lpm ; 3
eor ZL, r16 ; 1 (C)
swap ZL ; 1 (D)
lpm r16,Z ; 3
swap r16 ; 1
add r16,r0 ; 1 Код: Выделить всё
ZL R16
(A) ABCDEFGH ABCDEFGH
(B) 0000EFGH ABCDEFGH (0 xor A == A, H xor H == 0)
(C) ABCD0000
(D) 0000ABCDhttp://graphics.stanford.edu/~seander/bithacks.html
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Такой вот вопрос:
Записываем в РОН данных на входе порта В.
Как можно сравнить с константой не весь порт, а только нужный бит?
Записываем в РОН данных на входе порта В.
Как можно сравнить с константой не весь порт, а только нужный бит?
Константа, стало быть тоже один бит... если выполнить XOR <константа> а затем AND <маска бита> то в признаке Z(равно нулю, если бит равен константе) узнаешь результат.
Но можно просто использовать SBIC/SBIS, и не забывать про ограничения адреса порта до которого они могут достать.
Так же можно воспользоваться командой BST.
Но можно просто использовать SBIC/SBIS, и не забывать про ограничения адреса порта до которого они могут достать.
Так же можно воспользоваться командой BST.
А если в оперативку всю таблицу при инит? тогда ещё два такта за счёт lpmДа, а если даже уж так, то тоже можно ещё слово/такт урыть, заменив mov + andi одним xor-ом (выиграть этому коду соревнование по бит-реверсу это не поможет, но как пример применения xor пойдёт)
Можно конечно, если RAM не жалко. Правда запись в память при инициализации съест еще немного флеша.
А так пока самый оптимальный вариант 13тактов/13слов (по ссылкам avreal). Наверно короче и быстрее невозможно.
А так пока самый оптимальный вариант 13тактов/13слов (по ссылкам avreal). Наверно короче и быстрее невозможно.
- Сообщения: 209
- Зарегистрирован: Ср ноя 03, 2010 14:46:17
Здравствуйте РадиоКоты. Попрошу у Вас совета по ШИМу. Решил сделать, чтобы светодиод плавно загорался - на макетке припаял панельку для МК (тини 2313V) и к пинам РВ3 и РВ4 (они же ОС1А и ОС1В - выходы ШИМ) напрямую светодиоды 2 шт. Написал прогу по книжке глядя в даташит(я-начинающий). Смысл проги - выдать ШИМ и увеличивать значение регистра сравнения таймера. Прошивал МК на 4 и 8МГц для внутр. генератора (отключив фьюз CKDIV8) - в результате работает, но уж слишком быстро все происходит, как мигалка обычная. Потыркался с регистрами сравнения для таймера - эффект невелик. Решил спросить :
1. Какие соотношения частоты-длительности-скважности и в каких пределах нужно их задавать чтобы диод плавно загорался?
2. Обязательно ли нужен сглаживающий фильтр перед диодом?(я припаял напрямую к пинам).
3. Нужна ли пауза и какая? (допустим чтобы МК выдал одну скважность импульсов - немного на ней поработал, потом другую, опять немного поработал и т.д).
з.ы. Приложу страх и ужас, который написал. Фоткать плату думаю смысла нет - там МК, 2 диода и 2 проводка питания, чего Вы там не видели...
1. Какие соотношения частоты-длительности-скважности и в каких пределах нужно их задавать чтобы диод плавно загорался?
2. Обязательно ли нужен сглаживающий фильтр перед диодом?(я припаял напрямую к пинам).
3. Нужна ли пауза и какая? (допустим чтобы МК выдал одну скважность импульсов - немного на ней поработал, потом другую, опять немного поработал и т.д).
з.ы. Приложу страх и ужас, который написал. Фоткать плату думаю смысла нет - там МК, 2 диода и 2 проводка питания, чего Вы там не видели...
- Вложения
-
- Шим.txt
- (2.58 КБ) 151 скачивание
Лень - двигатель прогресса!
Во-первых светодиоды подключаются через резисторы.
Во-вторых, тактовая частота (допустим 8МГц), деленная на 1024, получается примерно 8килогерц. С этой частотой будет считать счетчик. Он 16-разрядный, следовательно частота ШИМ будет 0.1 Гц, это слишком мееееедленоооо.
Зато само значение ШИМ меняется со скоростью почти в мегагерц. Строки кода
какой смысл имеют? В любом случае переход на m2.
Предсказать какой результат такого кода будет выглядеть визуально сложно, видимо получается именно то, что вы наблюдаете.
Советую не менять величину ШИМ и просто для начала поиграться с постоянным значением:
1) сделать "нормальную" частоту (убрать делитель на 1024, тогда ШИМ будет 120Гц, это как раз нормально)
2) задать 100% ШИМ, скомпилировать, убедиться что светодиод горит в полный накал
3) задать 75, 50,25%, проверить правильность.
А после этого уже можно думать как программно менять его величину. Например сделать прерывание по переполнению таймера и в нем увеличивать ШИМ сразу на 256 единиц (увеличивать OCR1H на 1), тогда период мигания должен быть примерно 2 секунды.
Во-вторых, тактовая частота (допустим 8МГц), деленная на 1024, получается примерно 8килогерц. С этой частотой будет считать счетчик. Он 16-разрядный, следовательно частота ШИМ будет 0.1 Гц, это слишком мееееедленоооо.
Зато само значение ШИМ меняется со скоростью почти в мегагерц. Строки кода
Код: Выделить всё
brlo m2;
rjmp m2;
Предсказать какой результат такого кода будет выглядеть визуально сложно, видимо получается именно то, что вы наблюдаете.
Советую не менять величину ШИМ и просто для начала поиграться с постоянным значением:
1) сделать "нормальную" частоту (убрать делитель на 1024, тогда ШИМ будет 120Гц, это как раз нормально)
2) задать 100% ШИМ, скомпилировать, убедиться что светодиод горит в полный накал
3) задать 75, 50,25%, проверить правильность.
А после этого уже можно думать как программно менять его величину. Например сделать прерывание по переполнению таймера и в нем увеличивать ШИМ сразу на 256 единиц (увеличивать OCR1H на 1), тогда период мигания должен быть примерно 2 секунды.
- Сообщения: 209
- Зарегистрирован: Ср ноя 03, 2010 14:46:17
спасибо, спрошу сразу:
1. Как задать 100, 75, 50,25% ШИМ? (что нужно вводить в регистр OCR1? или по другому при настройке как-то? или это просто 1 на выходе потра?).Engineer_Keen писал(а): задать 100% ШИМ, скомпилировать, убедиться что светодиод горит в полный накал
2. Вы имеете в виду что OCR1L+255+1 это OCR1H+1?(понимаю - глупый вопрос)увеличивать ШИМ сразу на 256 единиц (увеличивать OCR1H на 1)
Лень - двигатель прогресса!
Судя по настройкам TCCRA и TCCRB, у вас режим phase correct PWM 10-бит, значит максимум, это 0x03FF, следовательно 03 в OCR1H и FF в OCR1L.Челюскин писал(а):1. Как задать 100% ШИМ? (что нужно вводить в регистр OCR1? или по другому при настройке как-то?).
Тут я ошибся, просто не помню наизусть все регистры и режимы таймеров, раз режим не 16-битный, то лучше и не скакать через 256, просто увеличивайте OCR1 (до 0x03FF, потом по новой). Если использовать делитель на 64, период мигания будет примерно 8 секунд.Челюскин писал(а):2. Вы имеете в виду что OCR1L+255+1 это OCR1H+1?
- Сообщения: 209
- Зарегистрирован: Ср ноя 03, 2010 14:46:17
Спасибо большое за совет, сейчас пробовать буду...
Лень - двигатель прогресса!
А для простоты я бы посоветовал вам экспериментировать с 8-битным Fast PWM



