Страница 4 из 22
Re: Хитрые, необычные алгоритмы и код
Добавлено: Вт сен 03, 2013 00:10:16
ILYAUL
Ну , что коллеги . Вот Вам код. Он не дописан до конца. Используя всего лишь три регистра , два из которых я уже показал , можно получить полезное бытовое устройство , без сильных затрат.
Задачка такая , что делает первая часть кода и дополните оставшиеся две части.
ПРИЗ ПОБЕДИТЕДЮ -
AVR DRAGON + БОНУСЫ.
Естественно это математическая задачка , но по применённой Вами константе, которую Вы найдёте сами , я сразу определю решили Вы ее или нет
Код: Выделить всё
ldi XL,0xA6
mov XH,XL
sei
;**************************************************
;* MAIN *
;**************************************************
MAIN:
..............
subi XL,-1
brhc INIT
SUM: mov temp1,XL
subi temp1,0xA6
rcall OUT_LCD
rjmp MAIN
INIT_SEC:
tst XL
breq ADD_M
subi XL,-6
rjmp SUM
ADD_M:
clr temp1
rcall OUT_LCD
LDI XL,0xA6
subi XH,-1
продолжите С ЭТОГО МЕСТА
rjmp MAIN
Re: Хитрые, необычные алгоритмы и код
Добавлено: Вт сен 03, 2013 05:57:33
akl
По мне, это очень оригинальный код часового счетчика. Естественно плюсанул, ну и попробовал дописАть
Спойлер
Код: Выделить всё
;Ну , что коллеги . Вот Вам код. Он не дописан до конца.
;Используя всего лишь три регистра , два из которых я уже показал,
; можно получить полезное бытовое устройство , без сильных затрат.
;Задачка такая , что делает первая часть кода и дополните оставшиеся две части.
;ПРИЗ ПОБЕДИТЕДЮ - AVR DRAGON + БОНУСЫ.
;Естественно это математическая задачка , но по применённой Вами константе,
; которую Вы найдёте сами , я сразу определю решили Вы ее или нет
.INCLUDE "2313def.inc"
INIT:
CLR R20
CLR R21
CLR R22
RCALL OUT_LCD
ldi XL,0xA6
mov XH,XL
LDI YL,0xD6
sei
;**************************************************
;* MAIN *
;**************************************************
MAIN:
RCALL OUT_LCD
;..............
subi XL,-1
brhc INIT_SEC
SUM:
mov R22,XL
subi R22,0xA6
rjmp MAIN
INIT_SEC:
tst XL
breq ADD_MIN
subi XL,-6
rjmp SUM
ADD_MIN:
clr R22
LDI XL,0xA6
subi XH,-1
;**************************************************
;продолжите С ЭТОГО МЕСТА
brhc INIT_MIN
SUM_MIN:
MOV R21,XH
subi R21,0xA6
rjmp MAIN
INIT_MIN:
TST XH
BREQ ADD_HOURS
SUBI XH,-6
RJMP SUM_MIN
ADD_HOURS:
CLR R21
LDI XH,0xA6
SUBI YL,-1
BRHC INIT_HOURS
SUM_HOURS:
MOV R20,YL
SUBI R20,0xD6
CPI YL,0xFA
BRCS MAIN
RJMP INIT
INIT_HOURS:
TST YL
BREQ INIT
SUBI YL,-6
RJMP SUM_HOURS
;**************************************************
OUT_LCD:
STS $62,R22
STS $61,R21
STS $60,R20
RET
Re: Хитрые, необычные алгоритмы и код
Добавлено: Вт сен 03, 2013 07:29:31
ploop
Так не интересно, метки стоило бы переименовать

Re: Хитрые, необычные алгоритмы и код
Добавлено: Вт сен 03, 2013 11:30:29
ILYAUL
akl Браво! Контакты в личку , плиз.
Код: Выделить всё
OUT_LCD:
STS $62,R22
STS $61,R21
STS $60,R20
RET
У меня эта подпрограмма, сразу вывод на LCD т.к. в темпах мы получаем сразу упакованный BCD
Вечером выложу свой вариант - он дома
Так не интересно, метки стоило бы переименовать
Оставил маленькие подсказки

Re: Хитрые, необычные алгоритмы и код
Добавлено: Вт сен 03, 2013 23:50:25
ILYAUL
Собственно , выкладывать и нечего , только засорять тему практически одинаковыми кодами. Поэтому я поступил проще - дополнив свой код подробными комментами , что откуда следует и что из этого вытекает . Задачи сделать часы , я собственно перед собой и не ставил . Причина написания кода указана в комментах.
Кстати ув-ый
ploop раз уж форум разделился , может прикрепим темку . Вчера мин 5 искал , судя по часам
Код: Выделить всё
;- Как решить задачку по "быстрому" сделать часы, не используя длительных преобразований из HEX в BCD
;= Вспомним , что BIN, HEX или десятичное число в начале любого счета похожи как две капли воды
;= Максимальное число до которого может посчитать один регистр 255=0хFF. А нам из всего этого
;= числа нужно чуть-чуть ,два раза по 59 и один по 24 или 12.
;= Значит нам надо сделать так , чтобы младшая тетрада регистра считала до 0x0F девять раз
;= или 4 ну хотя бы 2, а старшая 5,2 или 1. Для всего подсчёта часов потребуется 3 регистра
;= и регистр для высчитывания упакованного BCD для секунд минут и часов. Всего один регистр
;= или чуть чуть памяти (см. код ALK)
ldi XL,0xA6 ;+ Вычитая из 0хFF-0x59 получаем константу 0хA6 которую и загружаем
mov XH,XL ;+ в регистры подсчёта секунд и минут
;= Да , конечно нам нужен счётчик , что нить из таймеров и его прерывание
;= Я использовал WDT - быстро и дёшево , но очень не точно. Мой отставал на 5 сек в минуту.
;= Cобственно проверка точности частоты WDT и послужило целью , что-то по быстрому набрасать
;= на имеющейся базе.
sei
;**************************************************
;* MAIN *
;**************************************************
MAIN:
sbrs Flags,fl_Second ; Ждём когда пройдёт секунда
rjmp Main
cbr Flags,1<<fl_Second ; Сбрасываем флажок секунд , чтобы не запутаться
subi XL,-1 ;- Прошла секунда "вычитаем" из 0xA6 единичку, на самом деле
;- прибавляем и чтобы больше не пояснять получаем 0хА7..0xB9 и т.д
brhc INIT_SEC ;- Пока вот эта команда сравнения не скажет - хватит
;- уже , ты 10-ть именно 10-ть раз посчитал секунды и в младшей тетраде уже ноль. Команда SUBI сбросит флаг (H) в регистре SREG на 10 -ой секунде.
;-
SUM:
mov temp1,XL ;- TEMP1 - ИМЕННО ЭТОТ РЕГИСТР ХРАНИТ ДАННЫЕ СРАЗУ В ДЕСЯТИЧНОМ КОДЕ
subi temp1,0xA6 ;- и для преобразования в десятичный вид нам нужно вычесть 0хA6 из выше полученной суммы
rcall OUT_CLOCK ;- запомнить или сразу вывести на экран десятичное число
rjmp MAIN ;- Возвращаемся ? - значит мы ещё не посчитали до 10
INIT_SEC:
tst XL ;- Проверяем , может мы посчитали все 60 секунд
breq ADD_MINUT ;- Да- прибавим минуту
subi XL,-6 ;- Нет - тогда к нулю (помним что младшей тетраде XL у нас 0
rjmp SUM ;- прибавим нужные нам (6) и вернёмся на подсчёт. При этом
;- сбросив младшую тетраду в ноль , процессор автоматом добавит 1 в старшую тетраду и когда мы
;- выведем число на экран то после 9 как и положено будет 10 и счёт до 10 начнётся заново.
ADD_MINUT:
clr temp1 ;- Ну раз уж мы попали сюда, то прошла уже целая минута
;- и регистр XL полностью по нулям. Можно по разному обнулить TEMP1 - это кому как нравится
rcall OUT_CLOCK ;- Конечно отобразить сей момент на экране
LDI XL,0xA6 ;- И начать считать всё заново
;**************************************************
subi XH,-1
brhc INIT_MINUTs
SUM_MINUTs:
mov temp1,XH ;- Используем тот же самый регистр и для минут , и потом и для часов и т.д
subi temp1,0xA6
rcall OUT_CLOCK
rjmp MAIN
INIT_MINUTs:
tst XH
breq ADD_HOURs
subi XH,-6
rjmp SUM_MINUTs
ADD_HOURs:
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 07:52:09
Kavka
ILYAUL, давайте не будем засорять эту тему подобными конкурсами. Можно было сделать отдельную темку для конкурса, а сюда потом поместить только код.
А код, да, прикольная идея!
ploop, думаю, что нужно почистить сообщения "конкурса" ILYAUL. (И это тоже.)
К тому же уже есть победитель.

Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 08:38:44
ploop
Да ладно, зачем чистить, прикольный код, пусть будет

Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 08:43:02
Gudd-Head
Делать часы на МК ИМХО изврат.
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 09:01:27
ploop
Вот блин взял и пол-форума извращенцами назвал

Нормально там всё, у меня 2 года тикают, точные как... часы

Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 09:20:06
Gudd-Head
Просто часы, или ещё календарь с учётом високосных годов? А если ещё сравнить потребление с теми же 1307?
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 09:39:59
ploop
1307 имеет ряд недостатков, например отсутствие коррекции.
Календарь реализуется легко. Даже тупо в лоб, без всяких красивых алгоритмов:
Спойлер
Код: Выделить всё
;-------------------------------------------------------------------------------
; Подпрограмма переводит часы на 1 секунду вперёд
;-------------------------------------------------------------------------------
run_clock:
; Крутим секунды
lds r16,clk_ss ; Берём текущее значение
inc r16 ; Увеличиваем
cpi r16,60 ; Проверяем на максимум
brcc rc_min ; Если равен - уходим на минуты
sts clk_ss,r16 ; Иначе сохраняем
ret ; И выходим из подпрограммы
; Крутим минуты
rc_min:
clr r16 ; Сначала очищаем секунды
sts clk_ss,r16 ; И сохраняем
lds r16,clk_mm ; Дальше аналогично с минутами
inc r16
cpi r16,60
brcc rc_hh
sts clk_mm,r16
ret
rc_hh: ; Крутим часы
clr r16 ; Аналогично
sts clk_mm,r16
;-------------------------
set ; Устанавливаем флаг необходимости
bld flags0,NEED_H_COR ; грубой коррекции
;-------------------------
lds r16,clk_hh
inc r16
cpi r16,24
brcc rc_dd
sts clk_hh,r16
ret
rc_dd: ; Крутим день
clr r16
sts clk_hh,r16
;-------------------------
set ; Устанавливаем флаг необходимости
bld flags0,NEED_L_COR ; точной коррекции
;-------------------------
lds r16,clk_dd ; Берём число
lds r17,clk_mnt ; Берём месяц
ldi2Z cnt_day ; Берём адрес массива с количеством дней
add16Z r17 ; в месяце и прибавляем ему смещение
lpm r19,Z ; Загружаем количество дней в месяце
lds r18,clk_yyyy ; Проверим на високосный год
andi r18,0b00000011 ; У него будет два младших бита в нулях
brne rc_dd3 ; Год високосный, сейчас февраль?
cpi r17,2 ; Если да
brne rc_dd3
inc r19 ; Увеличиваем кол-во дней в месяце
rc_dd3:
inc r16 ; Увеличиваем текущее
cp r19,r16 ; Проверяем текущее число с максимальным
brcs rc_mnt ; Перевалило - уходим на месяцы
sts clk_dd,r16
ret
rc_mnt: ; Крутим месяц
ldi r16,1 ; Он у нас уже есть в r17
sts clk_dd,r16
inc r17
cpi r17,13
brcc rc_yy
sts clk_mnt,r17
ret
rc_yy: ; Крутим год
ldi r17,1
sts clk_mnt,r17
lds ZL,clk_yyyy
lds ZH,clk_yyyy+1
adiw ZL,1
sts clk_yyyy,ZL
sts clk_yyyy+1,ZH
ret
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 09:42:46
Gudd-Head
ploop писал(а):отсутствие коррекции.
Не совсем понял, ну да ладно. Не будем флудить.
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 09:48:25
Аlex
Имеется в виду корректировка хода, типо чтоб не бежали и не отставали из-за погрешности тактового генератора.
У меня тоже уже года 2 часики тикают на полочке, так-же точные как часы

И без всяких внешних микросхем, всё тактируется от основного генератора.
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 09:50:01
ILYAUL
Gudd-Head писал(а):Просто часы, или ещё календарь с учётом високосных годов? А если ещё сравнить потребление с теми же 1307?
Да запросто , просто календарь надо свести в табличку , это и будут константы для подсчёта . А так как високосные года периодичны , то учесть их не составит труда.
К тому же можно выбросить подсчёт секунд , как пережиток. и считать сразу минутами т.к. хоть об этом и не пишут в DS , но практически любой проц имеет на своём борту 24 битный счётчик , так что частоту можно поделить на 16 777 216. И спать целую минуту глубоко и надёжно , что даже 1307 не снилось.
У меня тоже уже года 2 часики тикают на полочке, так-же точные как часы

И без
Я вместо кварца поставил DS32KHz того же Максима и за 4 , а уже практически 5 лет - 2 сек ухода
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 11:11:19
ploop
А так как високосные года периодичны , то учесть их не составит труда.
Просто смотрим на два младших бита в годе (или году?) - если нули, то високосный.
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 12:05:14
Kavka
ploop писал(а):Да ладно, зачем чистить, прикольный код, пусть будет

Да не код, а "конкурсные" и трёп, который развели

Вот
это оставить.
Re: Хитрые, необычные алгоритмы и код
Добавлено: Ср сен 04, 2013 12:48:13
ILYAUL
Поддерживаю!

Re: Хитрые, необычные алгоритмы и код
Добавлено: Чт сен 05, 2013 07:03:07
BOB51
Гораздо эффективнее двоичный счетчик + табличный декодер...
но не для AVR ок

Re: Хитрые, необычные алгоритмы и код
Добавлено: Чт сен 05, 2013 13:27:16
ILYAUL
BOB51 писал(а):Гораздо эффективнее двоичный счетчик + табличный декодер...
но не для AVR ок

А в этой теме без разницы какой процессор. Код , плиз
Re: Хитрые, необычные алгоритмы и код
Добавлено: Вс сен 08, 2013 16:04:45
*Trigger*
Не совсем алгоритм, но полезно. Мне не хватило в одной конструкции на ATMega8 внешних прерываний, поступил так: взял в качестве входа вход таймера T1, сам таймер настроил на сброс при совпадении, в регистр совпадения записал 0. Прерывание по совпадению - это внешнее прерывание...