1 | #include "lcd.c"
|
2 | #include <avr/interrupt.h>
|
3 |
|
4 | volatile unsigned long time_ist; // globale Vergleichsvariable
|
5 | unsigned char Buffer[30]; // globales Array für die Strings
|
6 | unsigned int std = 0; // globale Variable für die Sekunden
|
7 | unsigned int min = 0; // globale Variable für die Minuten
|
8 | unsigned int sek = 0; // globale Variable für die Stunden
|
9 | unsigned int counter = 0;
|
10 | unsigned int gestellt = 0; // Uhr gestellt = 1; Uhr ist nicht gestellt = 0;
|
11 |
|
12 | ISR (TIMER1_COMPA_vect ) {
|
13 | time_ist++; //nach jedem Interrupt die Vergleichsvariable hochzählen
|
14 | if ( gestellt == 1){
|
15 | if(++counter >= 250){
|
16 | counter = 0;
|
17 | if(++sek == 60){ //nach einer Sekunde hochzählen der Variable für Sekunden
|
18 | sek = 0; //wenn diese 60 erreicht, dann wird sie auf null zurückgesetzt
|
19 | if(++min == 60){ //und die Variable für Minuten wird um eins hochgezählt
|
20 | min = 0; //wenn diese 60 erreicht, dann wird sie auf null zurückgesetzt
|
21 | if(++std == 24){ //und die Variable für Stunden wird um eins hochgezählt
|
22 | std = 0; //wenn diese 60 erreicht, dann wird sie auf null zurückgesetzt
|
23 | }
|
24 | }
|
25 | }
|
26 | }
|
27 | }
|
28 | }
|
29 |
|
30 | void timer (unsigned long time_soll) {
|
31 | time_ist = 0; // Vergleichsvariable wieder 0 setzen
|
32 | while (time_soll >= time_ist) {} // Abwarten bis die gewünschte Zeit abgelaufen ist
|
33 | }
|
34 |
|
35 | int zeit (int einheit, int umbruch,const char* name){ //übertragen des aktuellen Werts (leichter nachzustellen), der Zahl bis welche sie gehen darf (für Stunden 24, für Minuten 60 und für Sekunden ebenfalls 60) und der String welcher die Einheit angibt, welche abgegfragt wird
|
36 | lcd_clrscr (); // der Inhalt des Dispays wird gelöscht
|
37 | lcd_puts (name); // der Name der abgefragten Zeiteinheit wird ausgegeben
|
38 | itoa( einheit, Buffer, 10 ); // wandelt die Integerzahl von einheit in einen String um, welcher im Array Buffer gespeichert wird (die 10 bedeutet, dass der Integerwert dezimal ist)
|
39 | lcd_puts (Buffer); // String des aktuellen Werts der Zeiteinheit wird ausgegeben
|
40 | timer(150); // kurzes Abwarten, da sonst wegen Prellung die Eingabe von Minuten und Sekunden übersprungen wird
|
41 | while(PIND & (1<<PIND4) ) // solange bis der rechte Taster gedrückt wird, kann der Wert der abgefragten Zeiteinheit geändert werden
|
42 | if(!(PIND & (1<<PIND3) )) { // wenn der linke Taster gedrückt wird, dann soll folgendes gemacht werden
|
43 | if(++einheit == umbruch) einheit = 0; //der aktuelle Wert soll um eins erhöht werden, falls er größer ist als er sein darf, wird er wieder auf 0 gesetzt
|
44 | lcd_clrscr (); // der Inhalt des Dispays wird gelöscht
|
45 | lcd_puts (name); // der Name der abgefragten Zeiteinheit wird ausgegeben
|
46 | itoa( einheit, Buffer, 10 ); // wandelt die Integerzahl von einheit in einen String um, welcher im Array Buffer gespeichert wird (die 10 bedeutet, dass der Integerwert dezimal ist)
|
47 | lcd_puts (Buffer); // String des aktuellen Werts der Zeiteinheit wird ausgegeben
|
48 | timer(50); // kurzes Abwarten, da sonst der Wert der Zeiteinheit aufgrund von Prellungen unkontrolliert inkrementiert werden würde
|
49 | }
|
50 | return einheit; // überträgt den Wert in die entsprechende Variable von std, min oder sek
|
51 | };
|
52 |
|
53 | void stellen(){
|
54 | gestellt = 0; // damit die Sekunden nicht weiterlaufen
|
55 | std = zeit(std,24,"Stunden: "); // Aufrufen der Funktion zum Stellen der Stunden
|
56 | min = zeit(min,60,"Minuten: "); // Aufrufen der Funktion zum Stellen der Minuten
|
57 | sek = zeit(sek,60,"Sekunden: "); // Aufrufen der Funktion zum Stellen der Sekunden
|
58 | gestellt = 1; // Uhr läuft ab sofort
|
59 | }
|
60 |
|
61 | int main (void) { // Beginn des Hauptprogramms
|
62 |
|
63 | PORTD= 0x18; // PULLUP-Widerstand von PORT D4 und D3 aktiviert
|
64 | DDRD = 0x00; // PORTD auf Input setzen
|
65 | lcd_init (LCD_DISP_ON); // initialisiert das Dispay
|
66 | TCCR1A = 0; // Timer arbeitet als Timer und nicht als PWM
|
67 | TCCR1B = 1 <<CS10; // Quelle ist der ungeteilte Quarztakt
|
68 | TCCR1B |= 1 <<WGM12; // Clear Timer on Compare Match
|
69 | OCR1A = 64000 ; // Output Compare Register auf 64000 setzen entspricht 4 ms
|
70 | TIMSK = 1 << OCIE1A; // Interrupt setzen bei Output Compare Match
|
71 | sei(); // Interrupts einschalten
|
72 | stellen(); // Aufrufen der Funktion zum Stellen
|
73 | timer(150); // Abwarten, damit nicht sofort erneut in den Stellmodus gesprungen wird
|
74 |
|
75 |
|
76 | for (;;){ // Endlosschleife
|
77 | timer(150); // Abwarten, damit das Display was anzeigt, Uhrzeit läuft im Hintergrund weiter
|
78 | lcd_clrscr (); // der Inhalt des Dispays wird gelöscht
|
79 | lcd_puts (" "); // leere Stellen werden auf dem Display ausgegeben um die Uhrzeit zentriert darzustellen
|
80 | if(std < 10) lcd_puts("0"); // gibt die Ziffer 0 aus, wenn die die "Stundenzahl" einstellig ist, damit die "Stundenzahl" immer zweistellig ist
|
81 | itoa( std, Buffer, 10 ); // wandelt die Integerzahl von std in einen String um, welcher im Array Buffer gespeichert wird (die 10 bedeutet, dass der Integerwert dezimal ist)
|
82 | lcd_puts (Buffer); // String der aktuellen "Stundenzahl" wird ausgegeben
|
83 | lcd_puts(":"); // das Trennungszeichen wird ausgegeben
|
84 | if(min < 10) lcd_puts("0"); // gibt die Ziffer 0 aus, wenn die die "Minutenzahl" einstellig ist, damit die "Minutenzahl" immer zweistellig ist
|
85 | itoa( min, Buffer, 10 ); // wandelt die Integerzahl von min in einen String um, welcher im Array Buffer gespeichert wird (die 10 bedeutet, dass der Integerwert dezimal ist)
|
86 | lcd_puts (Buffer); // String der aktuellen "Minutenzahl" wird ausgegeben
|
87 | lcd_puts(":"); // das Trennungszeichen wird ausgegeben
|
88 | if(sek < 10) lcd_puts("0"); // gibt die Ziffer 0 aus, wenn die die "Sekundenzahl" einstellig ist, damit die "Sekundenzahl" immer zweistellig ist
|
89 | itoa( sek, Buffer, 10 ); // wandelt die Integerzahl von min in einen String um, welcher im Array Buffer gespeichert wird (die 10 bedeutet, dass der Integerwert dezimal ist)
|
90 | lcd_puts (Buffer); // String der aktuellen "Sekundenzahl" wird ausgegeben
|
91 | if(!(PIND & (1<<PIND4))) stellen(); // wenn der rechte Taster gedrückt wird, kann die Uhr erneut gestellt werden
|
92 | };
|
93 | }
|