'*** Küchentimer ***************************************************************
'*** mit Atmega8 und 6 x LED 7 Segment-Anzeigen ********************************
'*** Andreas Hickmann
'*** Anregung und Grundlagen von http://www.elektronik-radio.de ****************
'*** Hardware ******************************************************************
$regfile = "m8def.dat"
$crystal = 3686400 '3,6864 MHz
'*** Ports konfigurieren********************************************************
Ddrb = &B00110000 'PB => 1=Ausgang / 0=Eingang
Portb = &B00000011 '1=PullUp eingeschaltet
Ddrc = &B11111111 'PC => Multiplexen der Anzeige
Ddrd = &B11111111 'PD => 7-Segmente
'Sekundentakt erzeugen
On Timer1 Ontimer1
Config Timer1 = Timer , Prescale = 64 '=1Hz
Enable Timer1
'Multiplexfrequenz erzeugen
On Timer0 Ontimer0
Config Timer0 = Timer , Prescale = 64 '=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
Declare Sub Minute
Declare Sub Stunde
Multiplex = 1 'Startwert
Timer1 = 7936 'Für den Start des Counters nach 1 Sekunde
'*** Main (Zeit einstellen) ****************************************************
Do
Debounce Pinb.0 , 0 , Minute , Sub 'Minuten einstellen
Debounce Pinb.1 , 0 , Stunde , Sub 'Stunden einstellen
Loop
'*** Sub-Routinen (Zeit einstellen) ********************************************
Sub Minute
Incr Min_einer 'Minute um 1 erhöhen
Sek_einer = 0 'Nullen der Sekunde (Einer)
Sek_zehner = 0 'Nullen der Sekunde (Zehner)
End Sub
Sub Stunde 'Stunde um 1 erhöhen
Incr Std_einer
End Sub
'*** Interrupt-Routinen ********************************************************
Ontimer1: 'Aufruf im Sekundentakt
Timer1 = 7936 '=> 1Hz
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 < 0 Then 'Wenn Sekunde-Einer kleiner 0
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 => 0,5,4,3,2,1
If Sek_zehner < 0 Then 'Wenn Sekunde-Zehner kleiner 0 '
Sek_zehner = 5 'dann Sekunde Zehner-Stelle auf 5 setzen
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 < 0 Then 'usw.
Min_einer = 9
Decr Min_zehner
End If
If Min_zehner < 0 Then
Min_zehner = 5
Decr Std_einer
End If
If Std_einer < 0 Then
Std_einer = 9
Decr Std_zehner
End If
If Std_zehner < 0 Then
Std_zehner = 3
End If
If Std_zehner >= 2 And Std_einer >= 4 Then 'Wenn 24 Uhr alles 00:00:00 setzen
Std_zehner = 0
Std_einer = 0
End If
Return
Ontimer0: 'Der Multiplexer!
Timer0 = 112 '= 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 = 8 Then Wert = Min_zehner
If Multiplex = 16 Then Wert = Std_einer
If Multiplex = 32 Then
If Std_zehner = 0 Then 'Wenn 0 soll die Anzeige dunkel bleiben
Wert = 10 '10 bedeutet => kein Segment ist an.
Else
Wert = Std_zehner
End If
End If
'Hier erfolgt die die Auswahl (Dekodierung) welche Segmente leuchten sollen
Select Case Wert
Case 0
Portd = &B11000000 '0
Case 1
Portd = &B11111001 '1
Case 2
Portd = &B10100100 '2
Case 3
Portd = &B10110000 '3
Case 4
Portd = &B10011001 '4
Case 5
Portd = &B10010010 '5
Case 6
Portd = &B10000010 '6
Case 7
Portd = &B11111000 '7
Case 8
Portd = &B10000000 '8
Case 9
Portd = &B10010000 '9
Case Else
Portd = &B11111111 'Anzeige dunkel schalten
End Select
Return