Nachdem die grundlegende Funktion des Interrupt klar ist, gibt es hier eine weitere einfache Anwendung für den Interrupt. Die Funktion einer Uhr besteht ja darin, die Zeit zu zählen. Wenn sie das mit einer Genauigkeit von 1 Sekunde machen soll, dann braucht sie nur 1 mal pro Sekunde etwas tun. Das lässt sich z.B. durch einen Interrupt steuern, der genau 1 mal pro Sekunde ausgelöst wird.
In diesem Beispiel löst der Timer0 jede Sekunde einen Interrupt aus, woraufhin die Uhr die Zeit um 1 Sekunde erhöht, und die Anzeige neu mit der aktuellen Zeit beschreibt.
Schaltung
Das Display ist mit 7 Leitungen am Port
B angeschlossen.
Ein Schalter ist zwischen RB1 und Masse angeschlossen. Die Schaltung entspricht der LCD-Tastatur-Platine , verbunden mit der 16F84-Testplatine oder der 16F84-Miniplatine . |
Besonderheiten
In Uhren werden Quarze mit der Frequenz 32,768 kHz eingesetzt, das
sind genbau 215 Hz. Durch 15-faches Teilen durch 2
erhält
man einen Sekundentakt.
Wird ein PIC mit 32,768 kHz betrieben, und der PIC-Takt über
den
auf 32:1 eingestellten Vorteiler auf den Timer0 gegeben, dann
läuft
der Timer0 genau im Sekundentakt über (32768Hz /4 /32 /256 = 1Hz)
und kann dann einen Interrupt auslösen. Das nutzt man aus, und
betreibt
den PIC im stromsparenden LP-Mode.
; 1 Hz-Timer-Interrupt einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten movlw B'10000100' ; internen Takt zählen, ; Vorteiler zum Timer0, 32:1 movwf OPTION_REG bcf STATUS, RP0 ; auf Bank 0 zurückschalten clrf TMR0 ; ((32,768 kHz : 32 ): 256 = 1 Hz) bsf INTCON, T0IE ; Timer0 interrupt erlauben bsf INTCON, GIE ; Interrupt erlauben |
Um auf mathematische Berechnungen größerer Art
(binär
zu dezimal oder BCD) verzichten zu können, behandle ich jede
Anzeigestelle individuell. So wird z.B. bei jedem Interrupt die
Sekunden-Einerstelle
um 1 erhöht. Danach wird getestet, ob diese Stelle nun 10 anzeigen
möchte (was auf einer Stelle natürlich nicht geht). Ist dem
so,
dann wird die Stelle auf 0 zurückgesetzt, und anschließend
die
nächsthöhere Stelle (Sekunden-Zehnerstelle) um 1 erhöht.
So arbeite ich mich bis zur Stunden-Zehnerstelle hoch.
incf
ES,
f
; 1 Sekunden erhöhen movlw D'10' subwf ES, w btfss STATUS, Z goto Int_end ; 1 Sekunden <> 10 clrf ES incf ZS, f ; 10 Sekunden erhöhen |
Zur Ausgabe auf dem LCD-Display müssen die einstelligen Zahlen
noch in ihren ASCCI-Code gewandelt werden. Das erfolgt durch eine
ODER-Verknüpfung
mit dem ASCCI-Code des Zeichens '0'.
movfw
ZH
;
10er-Stundenstelle iorlw '0' ; wandeln in ASCCI call OutLcdDaten ; Ausgabe zum LCD-Display |
Es fehlen Tasten zur Zeiteinstellung, es gibt lediglich eine
00:00:00-Taste,
die die Uhr auf Mitternacht setzt.
Es steht aber jedem frei, daraus eine bessere Uhr mit 32,768 kHz Takt
und Tasten zur Frequenzeinstellung zu machen.
Programmablauf
Programmlisting
Weiterführende Gedanken
Kann man auf dieser Basis auch eine Stoppuhr mit 1/10 und 1/100
Sekunden-Anzeige
bauen???
Nein! es gibt keine Möglichkeit, aus einem 32768-Hz-Takt durch Teilung ein 10Hz oder 100Hz-Signal abzuleiten. Folglich müssen Stoppuhren mit ganz anderen Quarzen bestückt sein.
Wenn man aber mit einem Microcontroller arbeitet, kann man auch scheinbar ungerade Teilerverhältnisse realisieren. Ein Beispiel ist das andere LCD-Uhren-Beispiel, in dem mit einem 10-MHz-Quarz gearbeitet wird.