Untitled
unknown
plain_text
a year ago
4.6 kB
11
Indexable
; ------------------------------------------------
; --- H E A D E R ---
; ------------------------------------------------
.NOLIST
; .INCLUDE "m328pdef.inc"
.LIST
.DEF zero = r1
.DEF count_minutes = r16 ; Minuten Zähler
.DEF count_seconds = r17 ; Sekunden Zähler
.DEF tmp = r18
.DEF waitLow = r19 ; Wartezeit - Low Byte
.DEF waitHigh = r20 ; Wartezeit - High Byte
.EQU waitLowValue = 0x01
.EQU waitHighValue = 0x00
; ------------------------------------------------
; --- R E S E T A N D I N T E R R U P T S ---
; ------------------------------------------------
.CSEG
.ORG $0000
rjmp init ; Reset-Vector
reti ; Return from interrupt
; ------------------------------------------------
; --- I N I T ---
; ------------------------------------------------
init:
; Stack initialisieren
ldi r16, LOW(RAMEND) ; Niedriges Byte von RAMEND
out SPL, r16
ldi r16, HIGH(RAMEND) ; Hohes Byte von RAMEND
out SPH, r16
; Port D - 7-Segment-Display
ldi tmp, $FF
out PORTD, tmp
out DDRD, tmp ; Alle Pins als Ausgänge setzen, Zustand hoch
; Port B
ldi tmp, $80
out DDRB, tmp ; Pin 7 als Ausgang, alle anderen als Eingänge
ldi tmp, $87
out PORTB, tmp ; Ausgang: Pin 7 hoch, Eingänge: Pins 0, 1, 2 mit Pull-Up
; Initialisieren
ldi count_minutes, 3 ; 3 Minuten initialisieren
ldi count_seconds, 0 ; Sekunden auf 0 setzen
rcall resetWaitCounter ; Wartezeit zurücksetzen
rcall display ; Minuten:Sekunden anzeigen
; Timer-Setup (16-Bit Timer, Prescaler 64)
ldi r16, (1 << CS01) | (1 << CS00) ; Timer mit Prescaler 64
out TCCR0B, r16
sei ; Globale Interrupts aktivieren
; ------------------------------------------------
; --- H A U P T P R O G R A M M ---
; ------------------------------------------------
main:
rjmp mainend
mainend:
rjmp main
; ------------------------------------------------
; --- S U B R O U T I N E S ---
; ------------------------------------------------
; --- Interrupt-Service-Routine für Timer ---
; Wenn der Timer 1 Sekunde vergangen ist
TIMER0_COMPA_vect:
; Sekunden erhöhen
inc count_seconds
cpi count_seconds, 60 ; Wenn Sekunden 60 erreichen
brne seconds_1
ldi count_seconds, 0 ; Sekunden auf 0 zurücksetzen
dec count_minutes ; Minuten um 1 verringern
seconds_1:
; Wenn Minuten 0 erreichen, stoppen (Timer beendet)
cpi count_minutes, 0
brne continue_timer
rjmp timer_end
continue_timer:
rcall display ; Minuten und Sekunden auf Display aktualisieren
reti ; Interrupt zurückkehren
timer_end:
rjmp timer_end ; Endlosschleife, wenn der Timer abgelaufen ist
; --- Wartezeit zurücksetzen ---
resetWaitCounter:
ldi waitLow, waitLowValue
ldi waitHigh, waitHighValue
ret
; --- Zählerwert anzeigen ---
display:
; Minuten anzeigen
ldi ZL, LOW(2*codes) ; Startadresse der Anzeige-Codes in Z
ldi ZH, HIGH(2*codes)
; Minuten (Tens)
mov tmp, count_minutes
swap tmp ; Tausche die Nibble
andi tmp, 0x0F ; Hol die unteren 4 Bits
add ZL, tmp ; Addiere zur Adresse des Codes
lpm ; Lade Code-Byte
out PORTD, r0 ; Zeige die Zahl auf dem Display
; Minuten (Ones)
mov tmp, count_minutes
andi tmp, 0x0F
add ZL, tmp
lpm
out PORTD, r0 ; Zeige die Zahl auf dem Display
; Sekunden anzeigen
ldi ZL, LOW(2*codes)
ldi ZH, HIGH(2*codes)
; Sekunden (Tens)
mov tmp, count_seconds
swap tmp
andi tmp, 0x0F
add ZL, tmp
lpm
out PORTD, r0 ; Zeige die Zahl auf dem Display
; Sekunden (Ones)
mov tmp, count_seconds
andi tmp, 0x0F
add ZL, tmp
lpm
out PORTD, r0 ; Zeige die Zahl auf dem Display
ret
; ------------------------------------------------
; --- D A T A S E C T I O N ---
; ------------------------------------------------
codes:
.db 0b00111111, 0x00 ; 0
.db 0b00000110, 0x00 ; 1
.db 0b01011011, 0x00 ; 2
.db 0b01001111, 0x00 ; 3
.db 0b01100110, 0x00 ; 4
.db 0b01101101, 0x00 ; 5
.db 0b01111101, 0x00 ; 6
.db 0b00000111, 0x00 ; 7
.db 0b01111111, 0x00 ; 8
.db 0b01101111, 0x00 ; 9
Editor is loading...
Leave a Comment