Хитрые, необычные алгоритмы и код

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Хитрые, необычные алгоритмы и код

Сообщение 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
Реклама
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Хитрые, необычные алгоритмы и код

Сообщение akl »

По мне, это очень оригинальный код часового счетчика. Естественно плюсанул, ну и попробовал дописАть :oops:
Спойлер

Код: Выделить всё

;Ну , что коллеги . Вот Вам код. Он не дописан до конца.
;Используя всего лишь три регистра , два из которых я уже показал,
; можно получить полезное бытовое устройство , без сильных затрат.
;Задачка такая , что делает первая часть кода и дополните оставшиеся две части.
;ПРИЗ ПОБЕДИТЕДЮ - 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
Реклама
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Хитрые, необычные алгоритмы и код

Сообщение ploop »

Так не интересно, метки стоило бы переименовать :)
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Хитрые, необычные алгоритмы и код

Сообщение ILYAUL »

akl Браво! Контакты в личку , плиз.

Код: Выделить всё

OUT_LCD:
   STS   $62,R22
   STS   $61,R21
   STS   $60,R20
   RET
У меня эта подпрограмма, сразу вывод на LCD т.к. в темпах мы получаем сразу упакованный BCD
Вечером выложу свой вариант - он дома
Так не интересно, метки стоило бы переименовать

Оставил маленькие подсказки :)))
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Хитрые, необычные алгоритмы и код

Сообщение 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:
Реклама
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Хитрые, необычные алгоритмы и код

Сообщение Kavka »

ILYAUL, давайте не будем засорять эту тему подобными конкурсами. Можно было сделать отдельную темку для конкурса, а сюда потом поместить только код.
А код, да, прикольная идея! :beer:

ploop, думаю, что нужно почистить сообщения "конкурса" ILYAUL. (И это тоже.)
К тому же уже есть победитель. :)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Хитрые, необычные алгоритмы и код

Сообщение ploop »

Да ладно, зачем чистить, прикольный код, пусть будет :)
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Хитрые, необычные алгоритмы и код

Сообщение Gudd-Head »

Делать часы на МК ИМХО изврат.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Хитрые, необычные алгоритмы и код

Сообщение ploop »

Вот блин взял и пол-форума извращенцами назвал :)
Нормально там всё, у меня 2 года тикают, точные как... часы :)))
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Хитрые, необычные алгоритмы и код

Сообщение Gudd-Head »

Просто часы, или ещё календарь с учётом високосных годов? А если ещё сравнить потребление с теми же 1307?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Хитрые, необычные алгоритмы и код

Сообщение 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
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Хитрые, необычные алгоритмы и код

Сообщение Gudd-Head »

ploop писал(а):отсутствие коррекции.
Не совсем понял, ну да ладно. Не будем флудить.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Хитрые, необычные алгоритмы и код

Сообщение Аlex »

Имеется в виду корректировка хода, типо чтоб не бежали и не отставали из-за погрешности тактового генератора.
У меня тоже уже года 2 часики тикают на полочке, так-же точные как часы :)) И без всяких внешних микросхем, всё тактируется от основного генератора.
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Хитрые, необычные алгоритмы и код

Сообщение ILYAUL »

Gudd-Head писал(а):Просто часы, или ещё календарь с учётом високосных годов? А если ещё сравнить потребление с теми же 1307?
Да запросто , просто календарь надо свести в табличку , это и будут константы для подсчёта . А так как високосные года периодичны , то учесть их не составит труда.
К тому же можно выбросить подсчёт секунд , как пережиток. и считать сразу минутами т.к. хоть об этом и не пишут в DS , но практически любой проц имеет на своём борту 24 битный счётчик , так что частоту можно поделить на 16 777 216. И спать целую минуту глубоко и надёжно , что даже 1307 не снилось.
У меня тоже уже года 2 часики тикают на полочке, так-же точные как часы :)) И без
Я вместо кварца поставил DS32KHz того же Максима и за 4 , а уже практически 5 лет - 2 сек ухода
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Хитрые, необычные алгоритмы и код

Сообщение ploop »

А так как високосные года периодичны , то учесть их не составит труда.
Просто смотрим на два младших бита в годе (или году?) - если нули, то високосный.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Хитрые, необычные алгоритмы и код

Сообщение Kavka »

ploop писал(а):Да ладно, зачем чистить, прикольный код, пусть будет :)
Да не код, а "конкурсные" и трёп, который развели :)
Вот это оставить.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Хитрые, необычные алгоритмы и код

Сообщение ILYAUL »

Поддерживаю! :)))
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15561
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Хитрые, необычные алгоритмы и код

Сообщение BOB51 »

Гораздо эффективнее двоичный счетчик + табличный декодер...
но не для AVR ок 8)
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Хитрые, необычные алгоритмы и код

Сообщение ILYAUL »

BOB51 писал(а):Гораздо эффективнее двоичный счетчик + табличный декодер...
но не для AVR ок 8)
А в этой теме без разницы какой процессор. Код , плиз
Аватара пользователя
*Trigger*
Друг Кота
Сообщения: 3059
Зарегистрирован: Пн май 11, 2009 14:15:00
Откуда: СПб

Re: Хитрые, необычные алгоритмы и код

Сообщение *Trigger* »

Не совсем алгоритм, но полезно. Мне не хватило в одной конструкции на ATMega8 внешних прерываний, поступил так: взял в качестве входа вход таймера T1, сам таймер настроил на сброс при совпадении, в регистр совпадения записал 0. Прерывание по совпадению - это внешнее прерывание...
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.
Ответить

Вернуться в «Разные вопросы по МК»