Да, тут я с BREQ/BRNE, пожалуй, несколько ошибся. Одного флага будет недостаточно, например, для чисел вроде 0x5678 и 0x5531 (младшие байты не равны, старшие отличаются на 1) будет ошибочно воспринято равенство. 0x78..0x31 установят C, а 0x56..0x55+1 ошибочно его снимут.
одначе собственно по случаю размещения данных в регистровом файле конструкция с срс более оптимальна...
dimmer "0 - число" не одно и то же, что "число - 0"... ежли уж "сокращать"
Код:
com ng1l com ng1h subi ng1l,low(-1) sbci ng1h,high(-1)
так используя то, что система команд АВР для двухбайтовых значений надурняк предоставляет
Код:
com ng1l com ng1h adiw ng1l,1
разместив ng1h:ng1l где-нибудь в парах R25:R24, R27:R26, R29:R28 или R31:R30. НО... поскольку последние три индекс-указатели, то для двухбайтовых и прочих фоуксов весьма напрашивается R25:R24 с выделением этой пары с отметкой "псевдобазовый регистр"...
Как проверять на равенство... да много байтев... адрес массива в указатель (X,Y,Z) какой-нить счетчик количества байт cntb... ну и покатились...
Код:
loop_cp: ld r16,x+ ld r17,y+ CPSE R16,R17 ;имелась в виду spse r16,r17 rjmp error dec cntb brne loop_cp return ; or rjmp adr error: обрабатываем ошибку
как-то и без срс и размер массива побольше...
Команда CPSE сравнивает регистры, НЕ меняя флаги. Бывает полезно. По мне, лучше определить конец массива, по которому определять окончание процедуры. Тогда и счетчик cntb не нужен.
Это в случае когда массив не пересекает переход старшего байта через 0, а это в общем случае неверно. Тем более для ассемблерной вставки, когда массив ей предоставляется языком высокого уровня и неизвестно заранее куда он его распределил. А в таком случае придется проверять оба байта, то есть нет выигрыша ни по скорости, ни по ОЗУ. Выигрыш будет либо при ручном распределении памяти, либо если размер массива больше 256 байт, либо на младших моделях, где меньше 256 байт ОЗУ.
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Ср окт 19, 2016 07:49:14
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
COKPOWEHEU писал(а):
Это в случае когда массив не пересекает переход старшего байта через 0, а это в общем случае неверно.
Если Вы про флаг C, то в данном циклическом алгоритме он и не нужен. Достаточно определить любую пару неравных регистров (или ее не найти), чтобы понять равные ли области памяти или нет. Так что алгоритм с командой CPSE в цикле рабочий.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Можно еще глупость спрошу? просто, когда я задаю здесь вопросы, то их надо написать, а когда пишешь, то их приходится понятно формулировать, а когда понятно формулируешь, часто ответ сам находится. .
Короче, можно ли в АВР загрузить в ОЗУ некоторый массив данных (довольно много, но определенный) из ФЛЕШа, а потом его тупо с какого-либо адреса начать читать и с легкой обработкой выдавать ПОБИТНО (последовательно) в порт? Или вообще без обработки отдавать ПОБИТНО в порт? Ну, например, пошли нули, то и вывод порта в нуле, пошли единицы - переключился в единицу... понимаю, что это не СТМ32, у которого всякие DMI или как их там...
Короче, можно ли в АВР загрузить в ОЗУ некоторый массив данных (довольно много, но определенный) из ФЛЕШа, а потом его тупо с какого-либо адреса начать читать и с легкой обработкой выдавать ПОБИТНО (последовательно) в порт? Или вообще без обработки отдавать ПОБИТНО в порт?
Конечно можно. Вот моя подпрограмма для печати строки, находящейся во флеш. Вам нужно делать также, только полученные данные не печатать, а помещать в ОЗУ. Спойлер
Код:
;Подпрограмма вывода строки, хранящейся в программной памяти ;В регистровой паре Z начало строки, в регистре R19 адрес первой позиции вывода в строке дисплея PRNSTR: push R18 ; lsl ZL ;Умножить адрес начала строки на 2, так как доступ нужно rol ZH ;осуществлять побайтно PRNS1: lpm R18,Z+ ;Занести в R18 байт из памяти программ, содержащий код выводимого символа cpi R18,$0 ;Сравнение с нулем - кодом конца строки brne PRNS2 ;Если принят не нуль, то переход на метку PRNS1 pop R18 ret ;Строка напечатана, выход из подпрограммы PRNS2: rcall PRNSYM ;Печать символа, хранящегося в R18, в позицию, адрес которой в R19 inc R19 ;Увеличение адреса для вывода следующего символа rjmp PRNS1 ;Возврат на метку PRNSTR
А можно обойтись и без создания буфера в ОЗУ, если модификация данных не требуется. Сразу из флеш брать и отдавать
СКАЗОЧНИК писал(а):
Ну, например, пошли нули, то и вывод порта в нуле, пошли единицы - переключился в единицу...
Написать подпрограмму, выдвигающую байт побитно в порт (на один из выводов порта) элементарно Только надо протокол продумать - нужны ли старт-стоповые биты и т.д.
Ежли сразу из флешки - скорость значительно ниже максимально возможной. Это ежли только при внешнем параллельном ОЗУ (флешка с параллельным доступом) - тогда еще вписаться в максимум скорости можно. СКАЗОЧНИК Речь как я понял о тех же WS2812B? я ж вроде уже ссыль на исходник того алгоритма давал... Там побитовая передача ШИМ 1/3-2/3 причем желательно без накопления "лишнего времени". И никаких стартовых/стоповых - гонится массив по три байта на каждый светик без каких-либо разделителей и/или разрывов передачи. Весьма тоскная задачка...
Да, про них... Вашу реализацию уже изучал. Для меня замудрено. Смысл ихнего протокола понимаю и скорости тоже. Сейчас попробую реализовать сам, посчитать все задержки, такты, циклы... А потом уже дальше с вопросами приду.
Не надо ничего там менять - программно более оптимальный вариант не получится - скорость там на пределе возможного (разве что только частоту еще до 20МГц поднять - рассчет велся/проверялся под 16МГц для внутреннего RC генератора) там в одном из последних слотов и так все такты выбраны. Можно как в "типовых решениях" грузить рутину на SPI или USART -но там предварительное дробление для каждого байта и выбор лапок ограничен аппаратными "традициями".
Короче, написал. И даже работает! ))) Один минус... Плату, которую я делал для этого испортил... Вот там пожаловался. viewtopic.php?p=2893655#p2893655
Добавлено after 11 minutes 33 seconds: Работает вообще по тупому... И с первого раза. Главная задержка у них это первая самая, а вторую можно растягивать, как я понял даже до 10 мкс. Поэтому у меня вышло при 20 МГц тактировании - 1 такт = 50 нс. Первую соблюдаем, т.е. надо было 8 тактов для нуля и 16 тактов для единицы (+- 3 такта). А вторые главное выдержать самую мелкую с учетом всех процессов обсчета следующего бита или даже байта, который брался из Флеша. И все пашет.
Там один "подводный камень"... ежли использовать для анализа бита данных обычные команды условного перехода будем иметь непредсказуемую накапливающуюся ошибку до +/- 8 тактов на каждом байте (не считая анализатор счетчика массива - еще добавочное время, но более предсказуемо). Ибо теоретически каждый байт содержит разное количество нуликов и единичек. Как результат - возможность подпакостить при больших длительностях (больше 50 светиков). На практике возможно допуск технологических отклонений от такого защищает, одначе желательно от того "джиттера" изначально избавится. Вот ту задачу моя алгоритма и выполняет.
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт окт 20, 2016 10:21:06
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Отличные светодиоды. Не знал про такие. Спасибо за инфу.
Стало интересно и решил попробовать написать код выдачи пакета цифр из ОЗУ, может самому пригодится. Ну например, для 200 светодиодов. Что-то мне подсказывает, требуется именно это количество. Всего то 6 мс требуется чтобы передать на них данные.
МК - Атмега8. Тактовая частота 16МГц. Выход - PB2 .Прерывания должны быть запрещены при передачи. Вроде как работает. Вы бы не могли, ув. СКАЗОЧНИК, проверить этот код в железе. У меня то светодиодов нет. Принцип передачи - FAST PWM таймера1, т.е. на нем все привязки по времени и никаких сдвигов и накоплений ошибок не должно происходить.
Спойлер
Код:
.def zero=R1
.def buf=R16
.def Bit1 =R17 .def Bit0 =R18 .def SbrosFlag=R19
.def Chislo=R20
//---------- .macro SetBit out TIFR,SbrosFlag //sbrc chislo,@0 out OCR1BL,bit1 sbrs chislo,@0 out OCR1BL,bit0 .endm
.Macro WaitFlag//ждем когда сбросится счетчик in BUF,TIFR ANDi buf,1<<TOV1 breq PC-2 .endm //----------
ldi Zl,low(0x60) //адрес откуда считывать данные ldi ZH,High(0x60)
out TCNT1h, zero //установить счетчик чуть меньшим значение верха ldi buf,$11 out TCNT1l,buf
//************************* //Занести ноль в старшой буфер out OCR1BH,zero //переключение выхода
ld chislo,Z+ //ldi chislo,0x55 SetBit 7
//---------- // понеслась LDI buf,(1<<WGM10)|(1<<WGM11)|(1<<COM1B1)|(0<<COM1B0) out TCCR1A,buf LDI buf,(1<<WGM13)|(1<<WGM12)+1 out TCCR1B,buf //_____
WaitFlag
Cicle: SetBit 6 WaitFlag
SetBit 5 WaitFlag
SetBit 4 WaitFlag
SetBit 3 WaitFlag
SetBit 2 WaitFlag
SetBit 1 WaitFlag
SetBit 0 WaitFlag
SBIW X,1 breq Stop ld chislo, Z+
SetBit 7 WaitFlag
rjmp Cicle
//таймер стоп Stop: out TCCR1B,zero out TCCR1A,zero //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& loop:
rjmp loop
Если код рабочий, можно попроовать биты тоже в цикле передавать. Слегка объем уменьшится.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
На данный момент могу проверить на 3х светодиодах... Т.к. плату первую, где их было хотя бы 36, испортил.... ((( и если портировать код на ТИНИ2313, не надо там много менять? Просто я не вникал еще. ))
Написан в Студии? Нету там КодеВиженовских извращенных синтаксисов?
Просто макетка у меня с 2313. А Мегу8 надо плату травить и в квадратном планарном распаивать. Другой нету. ( И если не сложно, поправьте сразу на РВ1, либо РВ2, либо на РВ3. ))) ну, что-то такое. )))) А я залью и посмотрю.
Когда вытравлю новое кольцо-плату для светодиодов. смогу и на ней проверить, то это будет дня через два. А пока есть три таких светодиода на макетке. ))))
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Чт окт 20, 2016 17:22:26
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Тактовая частота то какая? Данный алгоритм не получится при снижении частоты. Ну и оперативки явно меньше у 2313, но это для реализации алгоритма конечно не важно.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Последний раз редактировалось Z_h_e Чт окт 20, 2016 17:25:13, всего редактировалось 1 раз.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения