Пжалста. Вот и я грю, порой без поллитра не обойтись и самые элементарные вещи кажутся чем-то невероятным.
Кстати, вопрос по таймерам. Есть ли такой режим типа мультивибратора — чтобы один раз протикал от 0 до FF (00) и остановился? Или единственный выход — принудительно останавливать его в прерывании (по флагу), т.к. если выбран источник тактирования, то таймер по-любому тикает?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Кажись, нет. Наверное можно остановить в прерывании по переполнению. Но на вход в прерывание уходит несколько тактов, так что без подделителя возможны погрешности на пару тиков. Хотя можно прерывание немного раньше вызвать, по сравнению с регистром OCR.
Мы в какой-то теме решали эту задачу.
А на счёт умножения. Мне п\программа умножения будет нужна и в других местах программы для других целей. По этому уже с умножением сделаю.
Последний раз редактировалось DX168B Пн июн 13, 2011 19:39:05, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!
Да вот недавно набрал кучку 2313х и мег 32х. Для ознакомления и отточения навыков.
Замок тоже на 2313й тине делаю, так как у 26й тиньки уже нехватает ног и UARTа нет, а он мне нужен там. Хочу, чтобы замком по UART можно было управлять и конфигурировать не только с клавы, но и с ПК. Программу для ПК написал, вот для МК осталось добить.
I am DX168B and this is my favourite forum on internet!
С первым тезисом согласен безоговорочно. Налицо и своеобразный стиль программирования. Никаких комментариев ( чтоб супостата запутать ) А то понаписывают некоторые:
; ------------------------------------------------
; Целочисленное беззнаковое умножение.
; R1 * R2 -> R25,R24
; Множители сохраняются.
; ------------------------------------------------
MUL: ..... и т. п.
Краткость - сестра таланта. Это чтобы вернувшись к задаче через месяц ( полгода ) чесать репу : "И какой идиот это накорябал! ... Да это ж я..."
Судя по тому, что умножение на 8 достигается троекратным сдвигом влево, идентификатор
MUL_8 обозначает в данном случае нечто совершенно иное и тоже призван запутать вероятного противника .
Это я и имел в виду. Умножение восьмибитных чисел. А результат может быть и 16-битным, в зависимости от самих умножаемых чисел. Умножитель я взял из Атмеловского аппноута по делениям\умножениям. Только имена регистров и меток подправил под себя.
А комменты я позже напишу, иначе на самом деле, позже и забыть можно. А на счёт изврата, я заранее предусмотрел ограничения, так что за пределы восьми бит никак не выйдет. Да и к скорости и оптимизации, будущая девайсина совсем не критична. (это будет применяться в некоторых пунктах меню настроек.)
Последний раз редактировалось DX168B Вт июн 14, 2011 12:33:53, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!
Опять я в ступоре, на этот раз более глубоком
В общем, имеется двухбайтное число (счётчик) в 2-х соседних регистрах. Необходимо сделать процедуру его уменьшения/увеличения на 1/10/100 (в зависимости от состояния 3-х флагов) таким образом, чтобы оно не выходило за произвольные нижнюю и верхнюю границы.
Если более подробно, то один флаг (Т) отвечает за направление счёта, два других (А и Б) за величину счёта (100 если А=Б=0; 1 если Б=1; и 10 если А=1_и_Б=0). Хотелось бы решить задачу в общем виде, т.е. чтобы пороги МАКС и МИН можно было задать любые (МАКС>МИН).
Сейчас это сделано только для инкремента/декремента на единицу, да и то коряво: перед соотв. действием текущее значение счётчика побайтно сравнивается с порогом. Например, если верхний порог МАКС равен $ABCD, то инкремент будет выглядеть
clr zeroreg;
ldi onesreg, 1;
...
cpi count_H, 0xAB; сравниваем старший байт с порогом
brlo PC+3; если меньше, то сразу переходим к вычислению
cpi count_L, 0xCD; сравниваем младший байт с порогом
brsh PC+3; если больше или равно, то пропускаем вычисление
add count_L, onesreg; инкремент младшего байта на единицу
adc count_H, zeroreg; прибавляем значение флага переноса к старшему байту
...
Самое простое было зациклить это на соотв. число циклов (1/10/100), однако время выполнения в таком случае может достигать 1000 тактов, что недопустимо.
Наверняка можно как-то компактно дополнить этот код.
Например, прибавляем 1. Проверяем флаг Б, если Б=0 то прибавляем ещё 9. Проверяем флаг А, если А=0 то прибавляем ещё 90. Но вот как проверить то, что после прибавления не будет превышен порог (при прибавлении чисел больше 1)? С учётом возможных ошибочных переходов $FFFF -> $0000 для порогов, близких к $FFFF.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Gudd-Head писал(а):...Необходимо сделать процедуру его уменьшения/увеличения на 1/10/100 (в зависимости от состояния 3-х флагов) таким образом, чтобы оно не выходило за произвольные нижнюю и верхнюю границы.
.. а что мешает перед вычитанием/увеличением делать проверку? (пишете отдельную ветку для уменьшения и увеличения - есть заем/перенос -> выход за границу ...)
ChipKiller писал(а): .. а что мешает перед вычитанием/увеличением делать проверку? (пишете отдельную ветку для уменьшения и увеличения - есть заем/перенос -> выход за границу ...)
В том-то и дело, не допираю как сделать проверку
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
имхо, решение в общем виде таково:
1. сохранили во временном месте значение текущего числа
2. увеличили/уменьшили его на заданное приращение
3. проверили на максимум/минимум
4 если есть выход за пределы - восстановили прежнее значение (или что-то там еще сделали)
все просто... и для любых приращений и пределов - алгоритм единый
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
ARV писал(а):2. увеличили/уменьшили его на заданное приращение
3. проверили на максимум/минимум
4 если есть выход за пределы - восстановили прежнее значение (или что-то там еще сделали)
Ага... Допустим, предел $FFFF, а текущее значение — $FFEF. Увеличили на 100 — получили $0053, что меньше порога, и благополучно проглотили.
UPD: Ладно, дополню сам себя: помимо сравнения двух байт счётчика с порогом, дополнительно проверить флаг С (после его прибавки к старшему байту) чтобы не получилось то, что я только что описал?..
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Я вот тут подумал, что если границы будут задаваться свои, то как вариант можно сделать такую проверку:
Для сложения:
Выполняем операцию: Правая граница - Текущее значение
Получившееся значение сравниваем со слагаемым - если меньше слагаемого, то прибавлять нельзя. (Вычитаем из результата слагаемое. Если флаг C после этого стоит, то складывать нельзя)
Для вычитания:
Выполняем операцию: Текущее значение - Левая граница
И далее тоже самое, только вместо слагаемого будет вычетаюшее число.
Оригинальное значение мы, естественно, сохраняем, например, в стек и достаём обратно после проверки.
Ну, как вариант. Не претендую на элегантность.
ВитГо писал(а):Очень нуждаюсь в алгоритме рисовании линии на ассемблере.
Интересно, конечно, где вы её (линию) будете рисовать — на бумаге?
А так — формула линии из алгебры 5-го класса: y = k*x + b, т.е. реализовать на АСМе умножение и сложение, потом подставлять вместо х нужный диапазон точек.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]