Untitled

 avatar
unknown
plain_text
5 months ago
3.9 kB
5
Indexable
.NOLIST
.LIST

; --- Definitionen ---
.DEF temp = r16
.DEF result = r17
.DEF tens = r18
.DEF ones = r19
.DEF calc_flag = r20      ; Flag für die Berechnung
.DEF eeprom_data = r21    ; EEPROM-Speicherwert

;.INCLUDE "m328Pdef.inc"   ; Definitionsdatei für den ATmega328P

.CSEG
.ORG $0000
    rjmp RESET            ; Reset-Vektor
    rjmp TIMER0_OVF_ISR   ; Timer0 Overflow Interrupt
    rjmp INT0_ISR         ; Externer Interrupt INT0

; --- RESET ---
RESET:
    ; Stack-Pointer initialisieren
    ldi temp, LOW(RAMEND)
    out SPL, temp
    ldi temp, HIGH(RAMEND)
    out SPH, temp

    ; Ports initialisieren
    ldi temp, 0xFF        ; PORTB (LED-Ausgang)
    out DDRB, temp
    ldi temp, 0x00        ; PORTD (Input, Taster und INT0)
    out DDRD, temp

    ; Timer0 konfigurieren (LED-Blinken)
    ldi temp, 0x03        ; Prescaler = 64 (CS00 und CS01 setzen)
    out TCCR0B, temp
    ldi temp, 0x00        ; Timer starten bei 0
    out TCNT0, temp
    ldi temp, 0x01        ; TOIE0 (Timer Overflow Interrupt) setzen
    sts TIMSK0, temp

    ; Externer Interrupt INT0 konfigurieren
    ldi temp, 0x02        ; Fallende Flanke konfigurieren
    sts EICRA, temp       ; Schreibe in EICRA
    ldi temp, 0x01        ; INT0 aktivieren
    out EIMSK, temp       ; Schreibe in EIMSK

    sei                   ; Globale Interrupts aktivieren

    ; Berechnungswerte initialisieren
    clr calc_flag         ; Berechnung nicht gestartet
    clr result            ; Ergebnis löschen
    clr tens
    clr ones

MAIN_LOOP:
    sbis PIND, 0          ; Warten, bis der Taster gedrückt wird
    rjmp MAIN_LOOP

    ldi calc_flag, 1      ; Berechnung starten
    rcall CALCULATE       ; Unterprogramm für Berechnung
    rjmp MAIN_LOOP

; --- BERECHNUNG ---
CALCULATE:
    cpi calc_flag, 1      ; Überprüfen, ob Berechnung gestartet ist
    brne CALC_DONE

    ; Zahlen laden und Ergebnis berechnen
    ldi temp, 3
    ldi result, 55
    add result, temp      ; result = 27 + 35
    lsl result            ; result = result * 2

    ; Ergebnis in Zehner und Einer zerlegen
    clr tens
DIV_LOOP:
    cpi result, 10
    brlo DIV_DONE
    subi result, 10
    inc tens
    rjmp DIV_LOOP
DIV_DONE:
    mov ones, result

    ; Ergebnis ins EEPROM schreiben
    ldi temp, 0x00        ; Adresse 0
    out EEARL, temp
    mov temp, tens        ; Zehner speichern
    out EEDR, temp
    sbi EECR, EEMPE       ; Schreibbefehl vorbereiten
    sbi EECR, EEPE        ; Schreiben starten

    ldi temp, 0x01        ; Adresse 1
    out EEARL, temp
    mov temp, ones        ; Einer speichern
    out EEDR, temp
    sbi EECR, EEMPE
    sbi EECR, EEPE

    ; Zehner und Einer anzeigen
    rcall DISPLAY_TENS
    rcall DISPLAY_ONES

    clr calc_flag         ; Berechnung abgeschlossen
CALC_DONE:
    ret

; --- ANZEIGEN ---
DISPLAY_TENS:
    ldi ZL, LOW(2*SEGMENT_CODES)
    ldi ZH, HIGH(2*SEGMENT_CODES)
    add ZL, tens
    adc ZH, r0
    lpm temp, Z
    out PORTC, temp
    ret

DISPLAY_ONES:
    ldi ZL, LOW(2*SEGMENT_CODES)
    ldi ZH, HIGH(2*SEGMENT_CODES)
    add ZL, ones
    adc ZH, r0
    lpm temp, Z
    out PORTD, temp
    ret

; --- INTERRUPT-SERVICE-ROUTINEN ---
TIMER0_OVF_ISR:
    in temp, PORTB        ; LED-Blinken
    com temp              ; LEDs umschalten
    out PORTB, temp
    reti

INT0_ISR:
    cli                   ; Interrupt deaktivieren
    clr temp              ; Alle LEDs aus
    out PORTB, temp
    reti

; --- SEGMENT-CODES ---
SEGMENT_CODES:
    .db 0b00111111   ; 0
    .db 0b00000110   ; 1
    .db 0b01011011   ; 2
    .db 0b01001111   ; 3
    .db 0b01100110   ; 4
    .db 0b01101101   ; 5
    .db 0b01111101   ; 6
    .db 0b00000111   ; 7
    .db 0b01111111   ; 8
    .db 0b01101111   ; 9
Editor is loading...
Leave a Comment