Привет, Коты, такое дело Понадобилось мне в байте добавлять и убавлять единицы. Это типа бйт статуса светодиодной шкалы, которая подсвечивается динамически.
Смысл такой:
Исходный байт 0b00000000
Жмём +, получаем 0b00000001
Жмём +, получаем 0b00000011
Жмём +, получаем 0b00000111
Жмём +, получаем 0b00001111
Жмём +, получаем 0b00011111
Жмём -, получаем 0b00001111
и т.п. Я сделал так:
А если перевернуть (единички с другой стороны пускать), то можно asr/lsl использовать.
Ну чуть короче. Изящнее ли? Не знаю.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Как при моём прошлом вопросе, в целом я понял, что будет, но в деталях - не уверен Я такие вопросы щас задаю, потому что я уже что-то научился делать сам, придумываю различные решения в зависимости от поставленных задач, но при этом боюсь начать "быдлокодить" Спасибо!
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
ldi ZH, high(Level_Table * 2)
ldi ZL, low(Levet_Table * 2)
lds Temp1, Level
add ZL, Temp1
brcc pc + 2
inc ZH
lpm Temp1, Z
out PORT, Temp1
, и это только если удалось развести все выходы в пределах одного и того же порта.
А при попытке переразвести новую версию платы придётся переписывать ещё и программу.
Площадь платы стоит денег.
Дополнительная площадь усугубляет массогабаритные проблемы.
Уменьшение ширины дорожек и/или зазоров между ними усугубляет технологические проблемы, то есть опять стоит денег (как минимум).
Лишний код - просто "другое" состояние тех же самых ячеек памяти.
Лишние микросекунды - а мы куда-то настолько сильно спешим?
Команды сдвига для этого алгоритма - довольно очевидны, но... в таком варианте есть проблемы. если что пойдет не так, то двигаться будет не столбик, а "жидкость с пузырьками", применение чувствительно к содержимому сдвигаемого столбика. Гораздо технологичней, воссоздавать столбик каждый раз когда это нужно при помощи подпрограммы - на входе число = высоте столбика, на выходе в регистре отрисованный столбик. Но и этот вариант обладает недостатком - применить можно только к жестко заданному порядку бит, а на реальных контроллерах один порт может быть разбросан по всем сторонам корпуса, и лови-разводи эти выводы в строгом порядке! Посему... проще, когда алгоритм подпрограммы строит столбик "побитно" - тупо, быстро но много памяти отъедает на тупой алгоритм. Поэтому, применяют более простое решение - столбик задается в виде таблицы, и извлекается из нее заранее прорисованное состояние столбика по индексу - и быстро, и гарантировано и памяти немного потребляет. При необходимости вывода столбика побитно раскинутого на 2-3 порта можно просто расширить таблицу.
А не проще ли тогда сделать по-битный вывод "правильного" байта по разбросанным по портам битам? А то ещё и маску в таблицу надо запихивать и обрабатывать её как при формировании сдвига, так и при выводе в порты. Что будет не очень компактно, IMHO, в сравнении с простым распихиванием битов. Так как записью целого байта в порт у AVR нет возможности какие-то биты установить/сбросить, а остальные не затрагивать (инвертировать можно, но не на всех МК). Да, к тому же, и обработка маски сведётся к распихиванию битов в цикле (по одному циклу на порт). Тут уж надо выбирать исходя из потребностей - некая универсальность или компактность.
Остаётся, конечно, вариант read-modify-write, но применимость этого метода сильно зависит от задачи и прочих условий реализации.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Всем привет. Если кто богат, более или менее, быстрым кодом деления чисел 32бит на 16бит на асме поделитесь, что-то никаких мыслей умных в голову не приходит, а простым вычитанием не айс.
Я прицепил к PortB 5 (он же SCK) светодиод, и без резика пустил его на землю. То чота плохо читался и записывался камень. Посадил через резистор - во, стало лучше.
.org 14 ;вектор прер. АЦП
rjmp adc_complete ;подпрограмма АЦП
...
ldi R16, 0b01000000 ;AD_Converter ADMUX byte
out ADMUX, R16
ldi R16, 0b10001011 ;AD_Converter ADCSRA byte, 125kHz
out ADCSRA, R16
sei ;вкл. прерывания в ЦП
...
rcall delay2s
sbi ADCSRA,6 ;старт одиночного замера АЦП
...
adc_complete:
in R28, ADCL
...перевожу состояние стартового бита в "1", идет замер, и срабатывает прерывание по АЦП"счет окончен"(014), все нормально, вывожу данные на ЖК, но после первой порции от АЦП более данных не поступает. Цикл идет, АЦП делает переход по прерыванию, но "вместимое" регистров АЦП не изменяется сколько не кручу резистор(( АЦП дает новые данные, только если, откл. и вкл. питание, и они корректно меняются с положением резистора, а в цикле не хочет, пользовался этой инструкцией
Прилепил счетчик на adc_complete, он считает а вместимое меньшего регистра ADCL не меняется. Переключил в непрерывный замер АЦП(ADFR=1), счетчик замеров бежит, а ADCL все равно не меняется... Я уже не знаю чего делать...
When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently,
if the result is left adjusted and no more than 8-bit precision is required, it is
sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.