Code:
list p=16f876a
;**************************************************************
;*
;* Pinbelegung
;* ----------------------------------
;* PORTA: 0 Ziffer -----------------------------------------+
;* 1 Ziffer -----------------------------+ I
;* 2 Ziffer -----------------+ I I
;* 3 Ziffer -----+ I I I
;* 4 Eingang I I I I
;* PORTB: 0 Segment B AAAAA AAAAA AAAAA AAAAA
;* 1 Segment F F B F B F B F B
;* 2 Segment A F B F B F B F B
;* 3 Segment G GGGGG GGGGG GGGGG GGGGG
;* 4 Segment H E C E C E C E C
;* 5 Segment C E C E C E C E C
;* 6 Segment E DDDDD HH DDDDD HH DDDDD HH DDDDD HH
;* 7 Segment D
;* PORTC: 0 MinutenTaster
;* 1 SekundenTaster
;* 2 StartTaster
;* 3 Relais
;**************************************************************
;
; Timer mit Schaltausgang, der aktiviert ist, solange gezählt wird
; Tasten für Minuteneinstellung, Sekundeneinstellung, Start und Reset.
; Timer läuft die eingestellte Zeit von max 99min.59sek rückwärts runter.
; 4Mhz Taktquelle
;
; basierend auf sprut's stoppuhr
;
;
;
;**************************************************************
; Includedatei für den 16F84 einbinden
#include <P16f876a.INC>
; Konstanten
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC & _BODEN_OFF & _LVP_OFF
DP Equ 4 ; Position des Dezimalpunkts in PORTB
; Variablennamen vergeben
w_copy Equ 0x20 ; Backup für Akkuregister
s_copy Equ 0x21 ; Backup für Statusregister
Ziffer1 Equ 0x22 ; Wert des LSD
Ziffer2 Equ 0x23 ; Wert der zweitkleinsten Stelle
Ziffer3 Equ 0x24 ; Wert der zweitgrößten Stelle
Ziffer4 Equ 0x25 ; Wert des MSD
Digit Equ 0x26 ; Ziffernzähler
ar Equ 0x27
Timer2 Equ 0x28 ; Vorteiler von 50 Hz auf 10 Hz
StartSignal Equ 0x29
Wait1 equ 0x30
Wait2 equ 0x31
Zehntel equ 0x32 ;zehntelsekunden, die nicht angezeigt werden
;**************************************************************
; los gehts mit dem Programm
org 0
goto Init
;**************************************************************
; die Interuptserviceroutine
org 4
intvec
bcf INTCON, GIE ; disable Interupt
movwf w_copy ; w retten
swapf STATUS, w ; STATUS retten
movwf s_copy ;
movlw D'131' ; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz)
movwf TMR0
; Intrupt servic routine
Int_serv
bcf PORTA, 0 ; Ziffer1 aus
bcf PORTA, 1 ; Ziffer2 aus
bcf PORTA, 2 ; Ziffer3 aus
bcf PORTA, 3 ; Ziffer4 aus
decf Digit,f ; Ziffernzähler verringern
;Digit=4: anzeigen Ziffer 4
;Digit=3: anzeigen Ziffer 3
;Digit=2: anzeigen Ziffer 2
;Digit=1: anzeigen Ziffer 1
;Digit=0: andere Aktionen, keine Anzeige
btfsc STATUS, Z
goto Int_0 ; Z-Flag=1 ergo Digit=0
movfw Digit
movwf ar
decf ar, f
btfsc STATUS, Z
goto Int_1 ; Digit=1
decf ar, f
btfsc STATUS, Z
goto Int_2 ; Digit=2
decf ar, f
btfsc STATUS, Z
goto Int_3 ; Digit=3
goto Int_4 ; Digit=4
Int_0
movlw 5
movwf Digit
btfss StartSignal, 0
goto Int_end ; ist start freigegeben?
bsf PORTC, 3 ;relais aktivieren
decf Timer2, f ; von 5 bis 0 zählen (50 Hz / 5 = 10 Hz)
btfss STATUS, Z
goto Int_end ; Timer2 <> 0
movlw 5
movwf Timer2 ;zähl die Zehntelsekunden
decf Zehntel, f
movlw D'255'
subwf Zehntel, w ;überprüf ob die ziffer überlief
btfss STATUS, Z
goto Int_end
movlw D'9'
movwf Zehntel
decf Ziffer1, f ; Sekunden erhöhen
movlw D'255'
subwf Ziffer1, w
btfss STATUS, Z
goto Int_end ; Sekunden <> 10
movlw D'9'
movwf Ziffer1
decf Ziffer2, f ; ZehnerSekunden erhöhen
movlw D'255'
subwf Ziffer2, w
btfss STATUS, Z
goto Int_end ; Zehner Sekunden <> 10
movlw D'5'
movwf Ziffer2
decf Ziffer3, f ; EinerMinuten erhöhen
movlw D'255'
subwf Ziffer3, w
btfss STATUS, Z
goto Int_end ; EinerMinuten <> 255
movlw D'9'
movwf Ziffer3
decf Ziffer4, f ; 10er Minuten erhöhen
movlw D'255'
subwf Ziffer4, w
btfss STATUS, Z
goto Int_end ; 10er Minuten <> 10
movlw D'9'
movwf Ziffer4
goto Int_end
Int_1
movfw Ziffer1 ; Wert der 1. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bsf PORTA, 0 ; 1. Ziffer einschalten
goto Int_end
Int_2
movfw Ziffer2 ; Wert der 2. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bsf PORTA, 1 ; 2. Ziffer einschalten
goto Int_end
Int_3
movfw Ziffer3 ; Wert der 3. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bcf PORTB, DP ; Dezimalpunkt ein
bsf PORTA, 2 ; 3. Ziffer einschalten
goto Int_end
Int_4
movfw Ziffer4 ; Wert der 4. Ziffer
call Segmente
movwf PORTB ; Segmente einschalten
bsf PORTA, 3 ; 4. Ziffer einschalten
goto Int_end
Int_end
movfw Ziffer1 ;Ziffer 1-4 werden logisch inklusic-or verknüpft
iorwf Ziffer2, w
iorwf Ziffer3, w
iorwf Ziffer4, w
btfsc STATUS, Z ;falls dabei 0 rauskomt, ist der zählerstand 00.00
call Nullzeit
swapf s_copy, w ; STATUS zurück
movwf STATUS
swapf w_copy, f ; w zurück mit flags
swapf w_copy, w
bcf INTCON, T0IF ; Interupt-Flag löschen
bsf INTCON, GIE ; enable Interupt
retfie
Nullzeit
bcf StartSignal, 0 ;Stoppe den Zählvorgang
bcf PORTC, 3 ;Schalte das Relais ab
return
; 7-Segment-Tabelle
Segmente
addwf PCL, f
retlw B'00011000' ; 0
retlw B'11011110' ; 1
retlw B'00110010' ; 2
retlw B'01010010' ; 3
retlw B'11010100' ; 4
retlw B'01010001' ; 5
retlw B'00010001' ; 6
retlw B'11011010' ; 7
retlw B'00010000' ; 8
retlw B'01010000' ; 9
;**************************************************************
; Port A/B auf Ausgabe stellen
Init
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'11110000' ; PortA RA0-RA3 output
movwf TRISA
movlw B'00000000' ; PortB alle output
movwf TRISB
movlw B'11110111' ;PortC eingang ausser RC3
movwf TRISC
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
movlw 5
movwf Digit ; Ziffernzähler einstellen
; 250 Hz-Timer-Interupt einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'10000100' ; internen Takt zählen, Vorteiler zum Timer0, 32:1
movwf OPTION_REG
movlw D'131' ; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz)
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
movwf TMR0
movlw 5
movwf Timer2 ; 50Hz -> 10 Hz Teiler
;ausgangszustand
clrf StartSignal
clrf Ziffer1
clrf Ziffer2
clrf Ziffer3
clrf Ziffer4
clrf Zehntel
bcf PORTC, 3
bsf INTCON, T0IE ; Timer0 interupt erlauben
bsf INTCON, GIE ; Interupt erlauben
loop
btfss PORTC, 1
call SekundenTaste
btfss PORTC, 0
call MinutenTaste
btfss PORTC, 2
call StartTaste
goto loop ; eine Endlosschleife, die die Tasten abfragt
StartTaste
bsf StartSignal,0 ;setzte das Startsignal
return
SekundenTaste
call Wait
btfss PORTC, 1
goto SekundenTaste
call Wait
btfss PORTC, 1
goto SekundenTaste
call Wait ;entprellen
incf Ziffer1, f ;EinerSekunden erhöhen, falls größer 9 erfolgt ein übertrag auf ziffer 2
movlw D'10'
subwf Ziffer1, w
btfss STATUS, Z
return
clrf Ziffer1
incf Ziffer2, f
movlw D'6'
subwf Ziffer2, w
btfss STATUS, Z
return
clrf Ziffer2
return
MinutenTaste
call Wait
btfss PORTC, 0
goto MinutenTaste
call Wait
btfss PORTC, 0
goto MinutenTaste
call Wait ;entprellen
incf Ziffer3, f ;EinerMinuten erhöhen, falls größer 9 erfolgt übertrag auf ziffer4
movlw D'10'
subwf Ziffer3, w
btfss STATUS, Z
return
clrf Ziffer3
incf Ziffer4, f
movlw D'10'
subwf Ziffer4, w
btfss STATUS, Z
return
clrf Ziffer4
return
;warteroutine für 20ms
Wait
movlw D'131'
movwf Wait1
movlw D'250'
movwf Wait2
loop1
incf Wait1, f
btfss STATUS, Z
goto loop1
incf Wait2, f
btfss STATUS, Z
goto loop1
return
;**********************************************************
end
man, das war der erste große brocken, den ich , wenn auch viel abgeguckt, alleine gemacht hab (natürlich mit hilfestellung)
Lesezeichen