Untitled

 avatar
unknown
plain_text
5 months ago
4.0 kB
3
Indexable
;
; Steckbrett.asm
;
;  Created: 30.09.2014 14:20:30
;  Author: akreienkamp
;

.NOLIST
; .INCLUDE "m328pdef.inc" ; Include-Datei für ATmega328P
.LIST
; Definitions
.DEF temp = R16         ; Temporäres Register
.DEF counter = R17      ; Zähler für das 7-Segment-Display
.DEF eeprom_value = R18 ; EEPROM-Wert
.DEF delay_timer = R19  ; Verzögerungstimer

.EQU SEG_PORT = PORTD   ; 7-Segment-Display Port
.EQU LED_PORT = PORTB   ; LED Port
.EQU BUTTON_PORT = PINC ; Taster Port
.EQU BUTTON_UP = PC0    ; Hochzählen-Taster
.EQU BUTTON_DOWN = PC1  ; Runterzählen-Taster

; Segmentcodes
.EQU DIGIT_0 = 0b00111111
.EQU DIGIT_1 = 0b00000110
.EQU DIGIT_2 = 0b01011011
.EQU DIGIT_3 = 0b01001111
.EQU DIGIT_4 = 0b01100110
.EQU DIGIT_5 = 0b01101101
.EQU DIGIT_6 = 0b01111101
.EQU DIGIT_7 = 0b00000111

; Interruptvektoren
.ORG 0x0000
    RJMP INIT          ; Reset-Handler
.ORG 0x0002
    RJMP BUTTON_ISR    ; External Interrupt

; Initialisierung
INIT:
    ; Ports konfigurieren
    LDI temp, 0xFF
    OUT DDRD, temp       ; 7-Segment als Ausgang
    LDI temp, 0x00
    OUT DDRC, temp       ; Taster als Eingang
    LDI temp, 0x01
    OUT DDRB, temp       ; LED als Ausgang

    ; EEPROM-Wert laden
    RCALL EEPROM_READ
    MOV counter, eeprom_value

    ; Timer konfigurieren (CTC-Modus)
    LDI temp, 0x0A          ; Prescaler = 64
    OUT TCCR0B, temp
    LDI temp, 0xF9          ; Vergleichswert für ~1 Hz
    OUT OCR0A, temp
    LDI temp, 0x02          ; CTC-Modus aktivieren
    OUT TCCR0A, temp

    ; Aktivierung von Output Compare Interrupt (TIMSK)
    LDI temp, (1 << OCIE0A) ; Aktiviert den Compare Match Interrupt
    OUT TIMSK, temp         ; Use TIMSK instead of TIMSK0

    ; Interrupts aktivieren
    SEI

    ; Hauptprogramm starten
MAIN:
    RCALL DISPLAY_UPDATE
    RJMP MAIN

; Taster-Interrupt-Service-Routine
BUTTON_ISR:
    IN temp, BUTTON_PORT
    SBIC temp, BUTTON_UP
    RCALL INCREMENT_COUNTER
    SBIC temp, BUTTON_DOWN
    RCALL DECREMENT_COUNTER
    RETI

; Timer-Interrupt-Service-Routine
.ORG 0x0012
TIMER_ISR:
    IN temp, LED_PORT
    EOR temp, 0x01       ; LED umschalten
    OUT LED_PORT, temp
    RETI

; Unterprogramme

; Zähler hochzählen
INCREMENT_COUNTER:
    INC counter
    CPI counter, 8       ; Begrenzen auf 7
    BRLO NO_RESET
    LDI counter, 0
NO_RESET:
    RCALL EEPROM_WRITE   ; Zählerstand speichern
    RET

; Zähler runterzählen
DECREMENT_COUNTER:
    DEC counter
    BRMI NO_RESET_DOWN   ; Nicht unter 0 gehen
    LDI counter, 7
NO_RESET_DOWN:
    RCALL EEPROM_WRITE   ; Zählerstand speichern
    RET

; 7-Segment-Display aktualisieren
DISPLAY_UPDATE:
    MOV temp, counter
    CPI temp, 0
    BREQ LOAD_DIGIT_0
    CPI temp, 1
    BREQ LOAD_DIGIT_1
    CPI temp, 2
    BREQ LOAD_DIGIT_2
    CPI temp, 3
    BREQ LOAD_DIGIT_3
    CPI temp, 4
    BREQ LOAD_DIGIT_4
    CPI temp, 5
    BREQ LOAD_DIGIT_5
    CPI temp, 6
    BREQ LOAD_DIGIT_6
    CPI temp, 7
    BREQ LOAD_DIGIT_7
    RET

LOAD_DIGIT_0:
    LDI temp, DIGIT_0
    RJMP OUTPUT_SEGMENT
LOAD_DIGIT_1:
    LDI temp, DIGIT_1
    RJMP OUTPUT_SEGMENT
LOAD_DIGIT_2:
    LDI temp, DIGIT_2
    RJMP OUTPUT_SEGMENT
LOAD_DIGIT_3:
    LDI temp, DIGIT_3
    RJMP OUTPUT_SEGMENT
LOAD_DIGIT_4:
    LDI temp, DIGIT_4
    RJMP OUTPUT_SEGMENT
LOAD_DIGIT_5:
    LDI temp, DIGIT_5
    RJMP OUTPUT_SEGMENT
LOAD_DIGIT_6:
    LDI temp, DIGIT_6
    RJMP OUTPUT_SEGMENT
LOAD_DIGIT_7:
    LDI temp, DIGIT_7

OUTPUT_SEGMENT:
    OUT SEG_PORT, temp
    RET

; EEPROM-Wert lesen
EEPROM_READ:
    LDI temp, 0x00
    OUT EEARL, temp      ; Adresse 0
    SBI EECR, EERE       ; Lesen auslösen
    IN eeprom_value, EEDR
    RET

; EEPROM-Wert schreiben
EEPROM_WRITE:
    OUT EEARL, temp      ; Adresse 0
    OUT EEDR, counter    ; Wert schreiben
    SBI EECR, EEMPE      ; Schreibbefehl vorbereiten
    SBI EECR, EEPE       ; Schreiben auslösen
    RET
Editor is loading...
Leave a Comment