; Versuchsreihe 1, Versuch 3, Aufgabe 2. ; Stopp-Uhr mit Sekunden-/Minuten-Anzeige. ; S5: Anhalten / Starten der Stopp-Uhr. ; Zeitmessung per TMR0-Interrupts. ; Tobias Schubert, März 2003. ; Definitionen. list p=16f84 include ; Variablen. S1 equ 0x0C S10 equ 0x0D M1 equ 0x0E M10 equ 0x0F Z0 equ 0x10 Z1 equ 0x11 CTRL equ 0x12 CTRH equ 0x13 IRQFlag equ 0x14 ; Reset-Vektor festlegen (--> Sprung in Hauptroutine). org 0x00 goto Hauptroutine ; TMR0-Interrupt. org 0x04 movlw 0x0A ; TMR0 = 10 initialisieren. movwf TMR0 bcf INTCON,2 ; TMR0 Interrupt-Flag löschen. incfsz CTRL,1 ; CTRL++. retfie ; CTRL > 0. incf CTRH,1 ; CTRH++ btfss CTRH,2 ; CTRH == 4? retfie ; CTRH < 4. clrf CTRH ; CTRH = 0. bsf IRQFlag,0 ; IRQFlag = 1. retfie org 0x50 ; Tabelle der benoetigten Zeichen. Number: addwf PCL,1 dt "0123456789" ; Pause. Delay movwf Z1 ; Z1 = W. clrf Z0 ; Z0 = 0. incfsz Z0,1 ; Z0++ und Test auf Z0 == 0. goto $-1 incfsz Z1,1 ; Z1++ und Test auf Z1 == 0. goto $-4 return ; Inhalt des "Working Registers" an PORTB / LCD ausgeben. WREG2LCD: movwf PORTB ; PORTB = WREG. bsf PORTA,2 ; "Enable LCD" aktivieren (E = 1). movlw 0xFD ; W = 0xFD (Parameter für Funktion Delay). call Delay bcf PORTA,2 ; "Enable LCD" deaktivieren (E = 0). return ; Funktion beenden. ; Taste S5 gedrueckt, auf zweiten Tastendruck warten. Taste: ; Pause zur Entprellung. movlw 0x40 ; W = 0x80 (Parameter für Funktion Delay). call Delay ; 2.Tastendruck. btfss PORTA,0 goto $-1 ; Pause zur Entprellung. movlw 0x40 ; W = 0x80 (Parameter für Funktion Delay). call Delay return ; Hauptroutine. Hauptroutine: ; PORTA / PORTB initialisieren. clrf PORTA ; PORTA loeschen. clrf PORTB ; PORTB loeschen. bsf STATUS,5 ; Bank 1 waehlen. bcf STATUS,6 clrf TRISB ; Alle Pins von PORTB als Ausgang. clrf TRISA ; TRISA initialisieren (Pin 2/3 als Ausgang, RS/E LCD). bsf TRISA,0 ; PIN 0 von PORTA als Eingang (Taster S5). bsf TRISA,1 ; PIN 1 von PORTA als Eingang (Taster S6). bcf STATUS,5 ; Bank 0 waehlen. ; LCD-Display initialisieren (siehe Datenblatt HD44780U, Seite 45). bcf PORTA,3 ; "Instruction Register" (RS=0). movlw b'00110000' ; Initialisierung. call WREG2LCD movlw b'00110000' ; Initialisierung. call WREG2LCD movlw b'00110000' ; Initialisierung. call WREG2LCD movlw b'00111000' ; 2 Zeilen, 5*8 Pixel (siehe Datenblatt HD44780U, Seite 29). call WREG2LCD movlw b'00001100' ; LCD ein, Cursor aus (siehe Datenblatt HD44780U, Seite 26-28). call WREG2LCD movlw b'00000001' ; Display loeschen. call WREG2LCD bsf PORTA,3 ; "Data Register" (RS=1). ; TMR0 initialisieren. clrf CTRL clrf CTRH clrf IRQFlag bsf STATUS,5 ; Bank 1 waehlen. bcf STATUS,6 movlw b'00000001' ; Prescaler 1:4 TMR0 movwf OPTION_REG bcf STATUS,5 ; Bank 0 waehlen. movlw b'10100000' ; Interrupt an TMRO aktivieren. movwf INTCON ; Initialisieren Variablen. clrf S1 clrf S10 clrf M1 clrf M10 Loop ; Zeit updaten? btfss IRQFlag,0 goto $-1 bcf IRQFlag,0 ; Tastendruck S5? btfsc PORTA,0 call Taste ; Ausgabe. movf M10,0 call Number call WREG2LCD movf M1,0 call Number call WREG2LCD movlw ":" call WREG2LCD movf S10,0 call Number call WREG2LCD movf S1,0 call Number call WREG2LCD ; Cursor verschieben. bcf PORTA,3 ; "Instruction Register" (RS=0). movlw b'00010000' ; Cursor um eine Position nach links verschieben. call WREG2LCD movlw b'00010000' ; Cursor um eine Position nach links verschieben. call WREG2LCD movlw b'00010000' ; Cursor um eine Position nach links verschieben. call WREG2LCD movlw b'00010000' ; Cursor um eine Position nach links verschieben. call WREG2LCD movlw b'00010000' ; Cursor um eine Position nach links verschieben. call WREG2LCD bsf PORTA,3 ; "Data Register" (RS=1). ; Sekunden-Zaehler "Einerstelle" inkrementieren. incf S1,1 ; "Zehnerstelle" Sekunden inkrementieren? btfss S1,3 goto Loop btfss S1,1 goto Loop ; Sekunden-Zaehler "Einerstelle" initialisieren. clrf S1 ; Sekunden-Zaehler "Zehnerstelle" inkrementieren. incf S10,1 ; "Einerstelle" Minuten inkrementieren? btfss S10,2 goto Loop btfss S10,1 goto Loop ; Sekunden-Zaehler "Zehnerstelle" initialisieren. clrf S10 ; Minuten-Zaehler "Einerstelle" inkrementieren. incf M1,1 ; "Zehnerstelle" Minuten inkrementieren? btfss M1,3 goto Loop btfss M1,1 goto Loop ; Minuten-Zaehler "Einerstelle" initialisieren. clrf M1 ; Minuten-Zaehler "Zehnerstelle" inkrementieren. incf M10,1 ; "Zehnerstelle" Minuten initialisieren? btfss M1,2 goto Loop btfss M1,1 goto Loop ; Minuten-Zaehler "Zehnerstelle" initialisieren. clrf M10 goto Loop ; Programm-Ende. end