1 | '*** UHR mit Atmega8 und Leuchtdioden zur Anzeige *****************************
|
2 |
|
3 | '*** Hardware *****************************************************************
|
4 | $regfile = "m8def.dat"
|
5 | $crystal = 4000000 '16 Mhz
|
6 |
|
7 | '*** Ports konfigurieren********************************************************
|
8 | Ddrb = &B00110000 'PB => 1=Ausgang / 0=Eingang
|
9 | Portb = &B00000011 '1=PullUp eingeschaltet
|
10 | Ddrc = &B11111111 'PC => Multiplexen der Anzeige
|
11 | Ddrd = &B11111111 'PD => 7-Segmente
|
12 |
|
13 | 'Sekundentakt erzeugen
|
14 | On Timer1 Ontimer1
|
15 | Config Timer1 = Timer , Prescale = 1024 '16Mhz/1024/(15625 siehe unten!)=1Hz
|
16 | Enable Timer1
|
17 |
|
18 | 'Multiplexfrequenz erzeugen
|
19 | On Timer0 Ontimer0
|
20 | Config Timer0 = Timer , Prescale = 256 '16Mhz/256/(156 siehe unten!)=400Hz
|
21 | Enable Timer0
|
22 |
|
23 | Enable Interrupts
|
24 |
|
25 | '*** Variablen *****************************************************************
|
26 | Dim Wert As Byte 'Ziffer die ausgegeben wird
|
27 | Dim Multiplex As Byte 'Stellenwert (1,2,4,8,16,32)
|
28 | Dim Sek_einer As Byte
|
29 | Dim Sek_zehner As Byte
|
30 | Dim Min_einer As Byte
|
31 | Dim Min_zehner As Byte
|
32 | Dim Std_einer As Byte
|
33 | Dim Std_zehner As Byte
|
34 |
|
35 | Declare Sub Minute
|
36 | Declare Sub Stunde
|
37 |
|
38 | Multiplex = 1 'Startwert
|
39 | Timer1 = 62000 'Für den Start der Uhr nach 1 Sekunde
|
40 |
|
41 | '*** Main (Zeit einstellen) ****************************************************
|
42 | Do
|
43 | Debounce Pinb.0 , 0 , Minute , Sub 'Minuten einstellen
|
44 | Debounce Pinb.1 , 0 , Stunde , Sub 'Stunden einstellen
|
45 | Loop
|
46 |
|
47 | '*** Sub-Routinen **************************************************************
|
48 | Sub Minute
|
49 | Incr Min_einer 'Minute um 1 erhöhen
|
50 | Sek_einer = 0 'Nullen der Sekunde (Einer)
|
51 | Sek_zehner = 0 'Nullen der Sekunde (Zehner)
|
52 | End Sub
|
53 |
|
54 | Sub Stunde 'Stunde um 1 erhöhen
|
55 | Incr Std_einer
|
56 | End Sub
|
57 |
|
58 | '*** Interrupt-Routinen ********************************************************
|
59 | Ontimer1: 'Aufruf im Sekundentakt
|
60 | Timer1 = 62000 '65536-15625=49911 => 1Hz
|
61 | Portb.5 = Not Portb.5 'Doppelpunkte blinken im Sekundentakt
|
62 | Portb.4 = Portb.5
|
63 | Incr Sek_einer 'Sekunde Einer-Stelle hochzählen
|
64 | 'Die Sekunden-Einer hochzählen => 0,1,2,3,4,5,6,7,8,9
|
65 | If Sek_einer >= 10 Then 'Wenn Sekunde-Einer größer 10
|
66 | Sek_einer = 0 'dann Sekunde Einer-Stelle Null setzen
|
67 | Incr Sek_zehner 'und Sekunde Zehner-Stelle hochzählen
|
68 | End If
|
69 | 'Die Sekunden-Zehner hochzählen => 0,1,2,3,4,5
|
70 | If Sek_zehner >= 6 Then 'Wenn Sekunde-Zehner größer 6 '
|
71 | Sek_zehner = 0 'dann Sekunde Zehner-Stelle Nullen
|
72 | Incr Min_einer 'und Minute Einer-Stelle hochzählen
|
73 | End If
|
74 | 'Die Minuten-Einer hochzählen => 0,1,2,3,4,5,6,7,8,9
|
75 | If Min_einer >= 10 Then 'usw.
|
76 | Min_einer = 0
|
77 | Incr Min_zehner
|
78 | End If
|
79 |
|
80 | If Min_zehner >= 6 Then
|
81 | Min_zehner = 0
|
82 | Incr Std_einer
|
83 | End If
|
84 |
|
85 | If Std_einer >= 10 Then
|
86 | Std_einer = 0
|
87 | Incr Std_zehner
|
88 | End If
|
89 |
|
90 | If Std_zehner >= 2 And Std_einer >= 4 Then 'Wenn 24 Uhr alles 00:00:00 setzen
|
91 | Std_zehner = 0
|
92 | Std_einer = 0
|
93 | End If
|
94 | Return
|
95 |
|
96 | Ontimer0: 'Der Multiplexer!
|
97 | Timer0 = 100 '16Mhz/256/(256-100)= 400Hz
|
98 |
|
99 | 'Hier wird die Umschaltsequenz (Multiplexen) der 6 Segmente erzeugt!
|
100 | Multiplex = Multiplex * 2 '1,2,4,8,16,32,(64)
|
101 | If Multiplex = 64 Then Multiplex = 1
|
102 |
|
103 | '400Hz/6Segmente=> 66Hz. Die kpl. Anzeige wird also mit 66Hz gemultiplext!
|
104 |
|
105 | Portd = &B11111111 'Alle Segmente vor dem Umschalten ausschalten
|
106 | Portc = Multiplex 'Das anzusteuernde Segment auswählen
|
107 |
|
108 | If Multiplex = 1 Then Wert = Sek_einer 'Ab hier erfolgt die Zuordnung von Anzeige und Wert
|
109 | If Multiplex = 2 Then Wert = Sek_zehner
|
110 | If Multiplex = 4 Then Wert = Min_einer
|
111 | If Multiplex = 8 Then Wert = Min_zehner
|
112 | If Multiplex = 16 Then Wert = Std_einer
|
113 | If Multiplex = 32 Then
|
114 | If Std_zehner = 0 Then 'Wenn 0 soll die Anzeige dunkel bleiben
|
115 | Wert = 10 '10 bedeutet => kein Segment ist an.
|
116 | Else
|
117 | Wert = Std_zehner
|
118 | End If
|
119 | End If
|
120 |
|
121 | 'Hier erfolgt die die Auswahl (Dekodierung) welche Segmente leuchten sollen
|
122 | Select Case Wert
|
123 | Case 0
|
124 | Portd = &B11000000 '0
|
125 | Case 1
|
126 | Portd = &B11111001 '1
|
127 | Case 2
|
128 | Portd = &B10100100 '2
|
129 | Case 3
|
130 | Portd = &B10110000 '3
|
131 | Case 4
|
132 | Portd = &B10011001 '4
|
133 | Case 5
|
134 | Portd = &B10010010 '5
|
135 | Case 6
|
136 | Portd = &B10000010 '6
|
137 | Case 7
|
138 | Portd = &B11111000 '7
|
139 | Case 8
|
140 | Portd = &B10000000 '8
|
141 | Case 9
|
142 | Portd = &B10010000 '9
|
143 | Case Else
|
144 | Portd = &B11111111 'Anzeige dunkel schalten
|
145 | End Select
|
146 | Return
|