;=======================================================
; Проект 28. Цифровой вольтметр 0..5 В
; ATmega8, 8 МГц. Вход ADC0 (PC0)
; Индикация: целые вольты и десятые на двух разрядах
; Сегменты PB0..PB6 (PB7 — точка), разряды PD0/PD1
;=======================================================
.include "m8def.inc"
.def    temp  = r16
.def    volts = r17
.def    tenth = r18
.def    acc   = r19
.def    loops = r20
.def    d1    = r21
.def    d2    = r22

.cseg
.org    0x0000
        rjmp    RESET

SEGTAB: .db 0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110
        .db 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111

RESET:
        ldi     temp, low(RAMEND)
        out     SPL, temp
        ldi     temp, high(RAMEND)
        out     SPH, temp
        ldi     temp, 0xFF
        out     DDRB, temp
        ldi     temp, 0x03
        out     DDRD, temp
        cbi     DDRC, PC0
        ldi     temp, (1<<REFS0)|(1<<ADLAR)
        out     ADMUX, temp
        ldi     temp, (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)
        out     ADCSRA, temp

MAIN:
        rcall   ADC_READ
        mov     acc, temp
        rcall   CONVERT
        ldi     loops, 50
SHOW:
        cbi     PORTD, PD1
        mov     temp, volts
        rcall   SEG
        ori     temp, 0b10000000        ; точка после целых вольт
        out     PORTB, temp
        sbi     PORTD, PD0
        rcall   DELAY5MS
        cbi     PORTD, PD0
        mov     temp, tenth
        rcall   SEG
        out     PORTB, temp
        sbi     PORTD, PD1
        rcall   DELAY5MS
        dec     loops
        brne    SHOW
        rjmp    MAIN

;--- код 0..255 -> вольты и десятые (51 единица на вольт) ---
CONVERT:
        clr     volts
        mov     temp, acc
V_LOOP: cpi     temp, 51
        brlo    T_PART
        subi    temp, 51
        inc     volts
        rjmp    V_LOOP
T_PART:
        clr     tenth
T_LOOP: cpi     temp, 5
        brlo    C_END
        subi    temp, 5
        inc     tenth
        cpi     tenth, 10
        brne    T_LOOP
        clr     tenth
        rjmp    T_LOOP
C_END:  ret

ADC_READ:
        in      temp, ADCSRA
        ori     temp, (1<<ADSC)
        out     ADCSRA, temp
AD_W:   in      temp, ADCSRA
        sbrc    temp, ADSC
        rjmp    AD_W
        in      temp, ADCH
        ret

SEG:
        ldi     ZL, low(SEGTAB<<1)
        ldi     ZH, high(SEGTAB<<1)
        add     ZL, temp
        clr     temp
        adc     ZH, temp
        lpm     temp, Z
        ret

DELAY5MS:
        ldi     d2, 52
I2:     ldi     d1, 255
I1:     dec     d1
        brne    I1
        dec     d2
        brne    I2
        ret
