Code:
'*** Küchentimer **************************************************************
'*** mit Atmega8 und 6 x LED 7 Segment-Anzeigen *******************************
'*** Anregung und Grundlagen von http://www.elektronik-radio.de ***************
'*** Andreas Hickmann
'*** besonderer Dank gilt Daniel(molleonair) vom Roboternetz.de-Forum *********
'Konfiguration der Ports
'
'******************************************************************************
'
' Port B:
' PB0 = Encoder A (Zeiteinstellung)
' PB1 = Encoder B (Zeiteinstellung)
' PB2 = Encoder D (Taste-Digitwechsel Stunden/Minuten)
' PB3 = Taster(Start/Stop Countdown)
' PB5 = Summer
' PB6 = XTAL1 Quarz
' PB7 = XTAL2 3,6864 Mhz
'
' Port C:
' Treiber = UDN2981A
' PC0 = Ziffer 1 gem.Anode
' PC1 = Ziffer 2 gem.Anode
' PC2 = Ziffer 3 gem.Anode
' PC3 = Ziffer 4 gem.Anode
' PC4 = Ziffer 5 gem.Anode
' PC5 = Ziffer 6 gem.Anode
' PC6 = Reset
'
' Port D:
' Treiber = ULN2803A
' PD0 = Segment "a" Kathode
' PD1 = Segment "b" Kathode
' PD2 = Segment "c" Kathode
' PD3 = Segment "d" Kathode
' PD4 = Segment "e" Kathode
' PD5 = Segment "f" Kathode
' PD6 = Segment "g" Kathode
' PD7 = frei
'
'******************************************************************************
'*** Hardware ******************************************************************
$regfile = "m8def.dat"
$crystal = 3686400 '3,6864 Mhz
'*** Ports konfigurieren********************************************************
Ddrb = &B00111000 'PB => 1=Ausgang / 0=Eingang
Portb = &B00001111 '1=PullUp eingeschaltet
Ddrc = &B11111111 'PC => Multiplexen der Anzeige
Ddrd = &B11111111 'PD => 7-Segmente
'Sekundentakt erzeugen
On Timer1 Ontimer1
Config Timer1 = Timer , Prescale = 64 ' siehe unten!)=1Hz
Enable Timer1
Stop Timer1
'Blinktakt erzeugen für die Zahlenstellen Minuten-Einer bis Stunden-Zehner
On Timer2 Ontimer2
Config Timer2 = Timer , Prescale = 1024 ' siehe unten!)=2Hz
Enable Timer2
Stop Timer2
'Multiplexfrequenz erzeugen
On Timer0 Ontimer0
Config Timer0 = Timer , Prescale = 256 '3,6864 Mhz = 400Hz
Enable Timer0
Enable Interrupts
'*** Variablen *****************************************************************
Dim Wert As Byte 'Ziffer die ausgegeben wird
Dim Multiplex As Byte 'Stellenwert (1,2,4,8,16,32)
Dim Sek_einer As Byte
Dim Sek_zehner As Byte
Dim Min_einer As Byte
Dim Min_zehner As Byte
Dim Std_einer As Byte
Dim Std_zehner As Byte
Dim Uhr_lauft As Bit
Dim Enc As Byte
Dim Enc_zaehler As Byte
Dim Digit_active As Byte
Dim Timer2_zaehler As Byte
Dim 2hz_zaehler As Bit
Set 2hz_zaehler
Digit_active = 4
Declare Sub Start_stopp
Declare Sub Count_up
Declare Sub Count_down
Declare Sub Drehtaster
Multiplex = 1 'Startwert
Timer1 = 7936 'Für den Start der Uhr nach 1 Sekunde
'*** Main (Zeit einstellen) ****************************************************
Do
Enc = Encoder(pinb.0 , Pinb.1 , Count_up , Count_down , 0) 'Drehimpulsgeber
Debounce Pinb.3 , 0 , Start_stopp , Sub 'Taste Starten und Stoppen Timer1
Debounce Pinb.2 , 0 , Drehtaster , Sub 'Taste vom Drehimpulsgeber
Loop
'*** Sub-Routinen (Zeit einstellen) ********************************************
Sub Start_stopp 'starten und stoppen des Timers1
If Uhr_lauft = 0 Then
Start Timer1
Uhr_lauft = 1
Stop Timer2
Set 2hz_zaehler
Else
Stop Timer1
Uhr_lauft = 0
Digit_active = 4
Start Timer2
End If
End Sub
Sub Count_up 'Drehimpulsgeber - Zeit stellen(hochzählen)
If Enc_zaehler = 4 Then
Stop Timer1
Start Timer2
Uhr_lauft = 0
If Digit_active = 1 And Std_zehner < 2 Then
Incr Std_zehner
Elseif Digit_active = 2 And Std_einer < 9 Then
Incr Std_einer
Elseif Digit_active = 3 And Min_zehner < 5 Then
Incr Min_zehner
Elseif Digit_active = 4 And Min_einer < 9 Then
Incr Min_einer
End If
Enc_zaehler = 0
Else
Incr Enc_zaehler
End If
Waitms 5
End Sub
Sub Count_down 'Drehimpulsgeber - Zeit stellen(runterzählen)
If Enc_zaehler = 4 Then
Stop Timer1
Start Timer2
Uhr_lauft = 0
If Digit_active = 1 And Std_zehner > 0 Then
Decr Std_zehner
Elseif Digit_active = 2 And Std_einer > 0 Then
Decr Std_einer
Elseif Digit_active = 3 And Min_zehner > 0 Then
Decr Min_zehner
Elseif Digit_active = 4 And Min_einer > 0 Then
Decr Min_einer
End If
Enc_zaehler = 0
Else
Incr Enc_zaehler
End If
Waitms 5
End Sub
Sub Drehtaster
Incr Digit_active 'Drehimpulsgeber schaltet die Zahlenstellen Min_einer bis Std_zehner durch
If Digit_active = 5 Then Digit_active = 1
End Sub
'*** Interrupt-Routinen ********************************************************
Ontimer1: 'Aufruf im Sekundentakt
Timer1 = 7936 '65536-7936=57600 => 1Hz
Portb.5 = Not Portb.5 'Doppelpunkte blinken im Sekundentakt - ist aber nicht angeschlossen
Portb.4 = Portb.5
Decr Sek_einer 'Sekunde Einer-Stelle runterzählen
'Die Sekunden-Einer runterzählen => 0,9,8,7,6,5,4,3,2,1
If Sek_einer > 10 Then 'Wenn Sekunde-Einer größer 10
Sek_einer = 9 'dann Sekunde Einer-Stelle auf 9 setzen
Decr Sek_zehner 'und Sekunde Zehner-Stelle runterzählen
End If
'Die Sekunden-Zehner runterzählen => 5, 4, 3, 2, 1, 0
If Sek_zehner > 6 Then 'Wenn Sekunde-Zehner größer 6 '
Sek_zehner = 5 'dann Sekunde Zehner-Stelle auf 5
Decr Min_einer 'und Minute Einer-Stelle runterzählen
End If
'Die Minuten-Einer runterzählen => 0,9,8,7,6,5,4,3,2,1
If Min_einer > 10 Then 'usw.
Min_einer = 9
Decr Min_zehner
End If
If Min_zehner > 6 Then
Min_zehner = 5
Decr Std_einer
End If
If Std_einer > 10 Then
Std_einer = 9
Decr Std_zehner
End If
If Std_zehner >= 2 And Std_einer >= 4 Then 'Wenn 24 Uhr alles 00:00:00 setzen
Min_zehner = 9
Min_zehner = 5
Std_zehner = 2
Std_einer = 3
End If
Return
Ontimer0: 'Der Multiplexer!
Timer0 = 1000 '= 400Hz
'Hier wird die Umschaltsequenz (Multiplexen) der 6 Segmente erzeugt!
Multiplex = Multiplex * 2 '1,2,4,8,16,32,(64)
If Multiplex = 64 Then Multiplex = 1
'400Hz/6Segmente=> 66Hz. Die kpl. Anzeige wird also mit 66Hz gemultiplext!
Portd = &B11111111 'Alle Segmente vor dem Umschalten ausschalten
Portc = Multiplex 'Das anzusteuernde Segment auswählen
If Multiplex = 1 Then Wert = Sek_einer 'Ab hier erfolgt die Zuordnung von Anzeige und Wert
If Multiplex = 2 Then Wert = Sek_zehner
If Multiplex = 4 Then Wert = Min_einer
If Multiplex = 4 And 2hz_zaehler = 0 And Digit_active = 4 Then Wert = 10 'Zahlenstelle beim stellen blinken
If Multiplex = 8 Then Wert = Min_zehner
If Multiplex = 8 And 2hz_zaehler = 0 And Digit_active = 3 Then Wert = 10 'Zahlenstelle beim stellen blinken
If Multiplex = 16 Then Wert = Std_einer
If Multiplex = 16 And 2hz_zaehler = 0 And Digit_active = 2 Then Wert = 10 'Zahlenstelle beim stellen blinken
If Multiplex = 32 Then
If Std_zehner = 0 And Uhr_lauft = 1 Then 'Wenn 0 soll die Anzeige dunkel bleiben
Wert = 10 '10 bedeutet => kein Segment ist an.
Else
Wert = Std_zehner
End If
End If
If Multiplex = 32 And 2hz_zaehler = 0 And Digit_active = 1 Then Wert = 10
'Hier erfolgt die die Auswahl (Dekodierung) welche Segmente leuchten sollen
Select Case Wert
Case 0
Portd = &B00111111 '0
Case 1
Portd = &B00000110 '1
Case 2
Portd = &B01011011 '2
Case 3
Portd = &B01001111 '3
Case 4
Portd = &B01100110 '4
Case 5
Portd = &B01101101 '5
Case 6
Portd = &B01111101 '6
Case 7
Portd = &B00000111 '7
Case 8
Portd = &B01111111 '8
Case 9
Portd = &B01101111 '9
Case Else
Portd = &B00000000 'Anzeige dunkel schalten
End Select
Return
Ontimer2: 'Timer2(14Hz) für Zahlenblinker(2Hz) beim stellen
Incr Timer2_zaehler 'Zähler zählt bis 7 dann wieder 0
If Timer2_zaehler = 7 Then
Timer2_zaehler = 0
Toggle 2hz_zaehler 'durch toggle werden 2Hz erreicht
End If
Return
Lesezeichen