Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .include "m16def.inc"
- ; =============================================================================
- ; Interrupt-Vektor-Tabelle
- ; =============================================================================
- .cseg
- .org 0x000
- jmp main
- ; =============================================================================
- ; ; Loesung zu 11.2 c ii)
- ; =============================================================================
- .org 0x008
- ; jmp clock_isr ; im Sekundentakt: Ueberlauf von Timer2
- ; =============================================================================
- ; Tabelle mit Ziffernansteuerung
- ; Loesung zu 11.2 a i)
- ; =============================================================================
- ; =============================================================================
- .org 0x02a
- digittab: ; Tabelle mit den Ansteuerungsbitmustern:
- .db 0x3f,0x06 ; 0, 1
- .db 0x5b,0x4f ; 2, 3
- .db 0x66,0x6d ; 4, 5
- .db 0x7d,0x07 ; 6, 7
- .db 0x7f,0x6f ; 8, 9
- ; =============================================================================
- ; Reservierter Speicher fuer Zeitwerte
- ; =============================================================================
- .dseg
- .org 0x0100
- seconds: .byte 1
- minutes: .byte 1
- hours: .byte 1
- ; =============================================================================
- ; Beginn Programmcode
- ; =============================================================================
- .cseg
- .org 0x034
- ; =============================================================================
- ; Loesung zu 11.2 a ii)
- ; =============================================================================
- digitout:
- push R16
- ldi ZL,low(digittab*2) ; lade den
- ldi ZH,high(digittab*2) ; entsprechenden
- add ZL,R17 ; Tabelleneintrag
- lpm R17, Z ; in R17
- ser R16 ; Maske = 0b11111111
- out DDRA, R16 ; PORTA in Schreibmodus setzen
- out PORTA, R17 ; R17 auf PORTA ausgeben
- pop R16
- ret
- ; *****************************************************************************
- ; *****************************************************************************
- ; Vorgegebene Unterprogramme
- ; *****************************************************************************
- ; *****************************************************************************
- ; INC_SEC
- ; -------
- inc_sec:
- push R16 ;Register retten.
- lds R16,seconds ;Sekundenwert holen.
- cpi R16,$59 ;Bereits $59?
- breq inc_sec_59 ;Dann Sonderbehandlung.
- inc R16
- sts seconds,R16 ;abspeichern.
- jmp inc_sec_end ;Das war's.
- inc_sec_59:
- clr R16 ;Sekunden auf $00
- sts seconds,R16 ;setzen.
- inc_sec_end:
- pop R16 ;Register wiederherstellen
- ret
- ; INC_MIN
- ; -------
- inc_min:
- push R16 ;Register retten.
- lds R16,minutes ;Minutenwert holen.
- cpi R16,$59 ;Bereits $59?
- breq inc_min_59 ;Dann Sonderbehandlung.
- inc R16
- sts minutes,R16 ;abspeichern.
- jmp inc_min_end ;Das war's.
- inc_min_59:
- clr R16 ;Minuten auf $00
- sts minutes,R16 ;setzen.
- inc_min_end:
- pop R16 ;Register wiederherstellen
- ret
- ; INC_HOURS
- ; -------
- inc_hours:
- push R16 ;Register retten.
- lds R16,hours ;Stundenwert holen.
- cpi R16,$23 ;Bereits $23?
- breq inc_hours_23 ;Dann Sonderbehandlung.
- inc R16
- sts hours,R16 ;abspeichern.
- jmp inc_hours_end ;Das war's.
- inc_hours_23:
- clr R16 ;Stunden auf $00
- sts hours,R16 ;setzen.
- inc_hours_end:
- pop R16 ;Register wiederherstellen
- ret
- ; CLOCK_UPDATE
- ; -------
- clock_update:
- push R16 ;Register retten.
- call inc_sec ;Sekunden weiterzaehlen.
- tst R16 ;Ueberlauf (59 -> 00)?
- brne clock_update_end ;Nein, dann fertig.
- call inc_min ;Sonst Minuten weiterzaehlen.
- tst R16 ;Ueberlauf (59 -> 00)?
- brne clock_update_end ;Nein, dann fertig.
- call inc_hours ;Sonst Stunden weiterzaehlen.
- clock_update_end:
- pop R16 ;Register wiederherstellen.
- ret
- ; DIV_8U
- ; -------
- div8u: push R18
- clr r15 ;clear remainder and carry
- ldi r18,9 ;init loop counter
- d8u_1: rol r16 ;shift left dividend
- dec r18 ;decrement counter
- brne d8u_2 ;if done
- pop R18
- ret ;return
- d8u_2: rol r15 ;shift dividend into remainder
- sub r15,r17 ;remainder = remainder - divisor
- brcc d8u_3 ;if result negative
- add r15,r17 ;restore remainder
- clc ;clear carry to be shifted into result
- rjmp d8u_1 ;else
- d8u_3: sec ;set carry to be shifted into result
- rjmp d8u_1
- ; *****************************************************************************
- ; *****************************************************************************
- ; =============================================================================
- ; Initialisierung
- ; Loesung zu 11.2 b i)
- ; =============================================================================
- main:
- ldi R16,low(RAMEND) ; Stack-
- out SPL,R16 ; pointer-
- ldi R17,high(RAMEND) ; initiali-
- out SPH,R17 ; sierung
- ser R16 ; R21 <- 0xFF
- out DDRB,R16 ; PORTA in Schreibemodus setzen
- ; =============================================================================
- ; ; Loesung zu 11.2 c i)
- ; =============================================================================
- ldi R16,(1<<CS22)|(1<<CS20) ; CLK/128 (Prescale)
- out TCCR2,R16 ; Modus setzen
- ldi R16,(1<<TCN2UB) ; Bit 3 des Asynchronous Status
- out ASSR, R16 ; Registers setzen (32768Hz-Takt)
- ldi R16,(1<<TOIE2) ; Interrupt
- out TIMSK,R16 ; enablen
- ; =============================================================================
- ; Initialisierung
- ; Loesung zu 11.2 b ii)
- ; =============================================================================
- loop:
- lds R16,seconds ; Dividend = Sekunden
- ldi R17,2 ; Divisor = 2
- call div8u ; Unterprogramm aufrufen und dividieren
- ldi R18,(1<<PINB0) ; 0. Anzeigenelement
- ldi R18,(1<<PINB4) ; Anzeigenelement (Doppelpunkt)
- clr R19 ; Segmentwert
- cpi R17,0 ; bei geraden Sekunden...
- breq weiter ; ... Doppelpunkt nicht aktivieren
- ldi R19,1 ; Doppelpunkt an
- weiter:
- out PORTB,R18 ; Doppelpunkt setzen
- out PORTA,R19 ; ... auf den entsprechenden Wert
- ; ... hier jetzt alle einzelnen Anzeigenelemente durchlaufen
- ; und auf den jeweiligen Segmentwert setzen...
- rjmp loop ; Schloop
- ; =============================================================================
- ; Initialisierung
- ; Loesung zu 11.2 c iii)
- ; =============================================================================
- clock_isr: ; jede Sekunde:
- call clock_update ; Uhr updaten
Advertisement
Add Comment
Please, Sign In to add comment