
;--------------------------------------------------------------------------
; Драйвер светодиодного дисплея
; четырех-значный индикатор, общий катод
;--------------------------------------------------------------------------
LED_DR:
	ldi	ZH, high(LED_TABLE*2) 
	ldi	ZL, low(LED_TABLE*2) 

	lds	r16, LED_Counter
	inc	r16
	sts	LED_Counter, r16	
	cpi	r16, 0x01 
	breq	LED_OUT_0
	cpi	r16, 0x02 
	breq	LED_OUT_1
	cpi	r16, 0x03 
	breq	LED_OUT_2

LED_OUT_3:
	sts	LED_Counter, ZERO	
	lds	r16, LED_value+3
	rcall	READ_LED_TABLE		
	cbi	PORTD, PD2
	sbi	PORTD, PD3
	ret	

LED_OUT_2:
	lds	r16, LED_value+2
	rcall	READ_LED_TABLE		
	cbi	PORTA, PA0
	sbi	PORTD, PD2
	ret	

LED_OUT_1:
	lds	r16, LED_value+1
	rcall	READ_LED_TABLE		
	cbi	PORTA, PA1
	sbi	PORTA, PA0
	ret	

LED_OUT_0:
	lds	r16, LED_value
	rcall	READ_LED_TABLE		
	cbi	PORTD, PD3
	sbi	PORTA, PA1
	ret	

READ_LED_TABLE:
	add	ZL, r16
	adc	ZH, ZERO
	lpm	r16, Z
	
; вывод байта в сдвиговый регистр
; вход: r16
; ресурсы r17 - счетчик бит
;--------------------------------------------------------------------------
OUT_REG:
	ldi	r17, 8

OUT_REG_LOOP:
	lsl	r16
	sbi	PORTB, PB6
	brcs	SCK_TAKT
	cbi	PORTB, PB6
	
SCK_TAKT:
	cbi	PORTB, PB7
	sbi	PORTB, PB7
	dec	r17
	brne	OUT_REG_LOOP	

RCK_TAKT:	
	cbi	PORTB, PB2
	sbi	PORTB, PB2
		
	ret

; Таблица соответствия символов светодиодного индикатора
;--------------------------------------------------------------------------
LED_TABLE:
;	  HGFEDCBA    HGFEDCBA
.db	~0b01000000, ~0b01111001	; 0 1 
.db	~0b10100100, ~0b00110000	; 2 3
.db	~0b00011001, ~0b00010010	; 4 5
.db	~0b00000010, ~0b01111000	; 6 7
.db	~0b00000000, ~0b00010000	; 8 9
.db	0b00000000, 0b01110110		; _ H

;*******************************************************************
;1. Текст программы "bin16BCD5"- преобразование 16-битного двоичного
;значения в упакованный BCD формат
;*******************************************************************
;* Количество слов кода            :25 + возврат
;* Количество циклов               :25/176 (Мин/Макс) + возврат
;* Использованные младшие регистры :нет
;* Использованные старшие регистры :4(fbinL,fbinH/tBCD0,tBCD1,tBCD2)
;* Использованные указатели        :нет
;*******************************************************************

;***** Регистровые переменные подпрограммы

#define    fbinL   r16            ;двоичное значение, младший байт
#define    fbinH   r17            ;двоичное значение, старший байт
#define    tBCD0   r17            ;BCD значение, цифры 1 и 0
#define    tBCD1   r18            ;BCD значение, цифры 3 и 2
#define    tBCD2   r19            ;BCD значение, цифра 4
;Примечание: Переменные fbinH и tBCD0 должны размещаться в одном
;регистре.

;***** Код

bin16BCD5:
        ldi     tBCD2, -1
bin16BCD5_loop_1:
        inc     tBCD2
        subi    fbinL, low(10000)
        sbci    fbinH, high(10000)
        brsh    bin16BCD5_loop_1
        subi    fbinL, low(-10000)
        sbci    fbinH, high(-10000)
        ldi     tBCD1, -0x11
bin16BCD5_loop_2:
        subi    tBCD1, -0x10
        subi    fbinL, low(1000)
        sbci    fbinH, high(1000)
        brsh 	bin16BCD5_loop_2
        subi    fbinL, low(-1000)
        sbci    fbinH, high(-1000)
bin16BCD5_loop_3:
        inc     tBCD1
        subi    fbinL, low(100)
        sbci    fbinH, high(100)
        brsh 	bin16BCD5_loop_3
        subi    fbinL, -100
        ldi     tBCD0, -0x10
bin16BCD5_loop_4:
        subi    tBCD0, -0x10
        subi    fbinL, 10
        brsh 	bin16BCD5_loop_4
        subi    fbinL, -10
        add     tBCD0, fbinL

; ПП расщепления числа BCD по байтам
;------------------------------------------------------------;
; Вход  - r17 - (1, 0), r18 - (3, 2) r19 - (4, -)
; Выход - r17 - (0), r20 - (1), r18 - (2), r21 -(3), r19 - (4) 
; Рабочие регистры: r20, r21
;------------------------------------------------------------;
BCD_allocate_byte:
	mov	r20, r17
	andi	r17, 0x0F
	swap	r20
	andi	r20, 0x0F

	mov	r21, r18
	andi	r18, 0x0F
	swap	r21
	andi	r21, 0x0F
	ret

; загрузка регистров индикации с гашением незначащих разрядов
;------------------------------------------------------------;
OUT_LED_VALUE:                  
	cp	r19, ZERO
	brne	NEXT_LED_value
	ldi	r19, 0x0A

	cp	r21, ZERO
	brne	NEXT_LED_value
	ldi	r21, 0x0A

	cp	r18, ZERO
	brne	NEXT_LED_value
	ldi	r18, 0x0A

	cp	r20, ZERO
	brne	NEXT_LED_value
	ldi	r20, 0x0A

NEXT_LED_value:
	sts	LED_value+0, r21
	sts	LED_value+1, r18
	sts	LED_value+2, r20
	sts	LED_value+3, r17

	ret	

