1 | /* Uhr_DCF.c
|
2 | * Created: 19.02.2012 23:45:47
|
3 | * Author: Niklas Neumeister
|
4 | */
|
5 |
|
6 | #include <stdint.h>
|
7 | #include <stdbool.h>
|
8 | #include <stdio.h>
|
9 | #include <avr/io.h>
|
10 | #include <avr/interrupt.h>
|
11 | #include <avr/portpins.h>
|
12 |
|
13 | volatile int hh = 0, mm = 0, ss = 0, hs = 0, mode = 0, counter = 0, n = 0, mmc = 0, hhc = 0, z = 1, DCF[60], i = 0x00, light = 0x00;
|
14 | bool time = false, zu = false;
|
15 |
|
16 | void portinit(void) //Ein- und Ausgaenge
|
17 | {
|
18 | DDRA = 0xFE; //PA7 Eingang sonst alle Ausgang
|
19 | DDRB = 0xFF;
|
20 | DDRC = 0xFF;
|
21 | DDRD = 0xFB;
|
22 | PORTA = 0x00; //Standart auf low
|
23 | PORTB = 0x00;
|
24 | PORTC = 0x00;
|
25 | PORTD = 0x00;
|
26 | }
|
27 | void timerinit(void) //Timer Interrupts
|
28 | {
|
29 | //Timer0
|
30 | TCCR0A |= (1<<WGM01); //CTC-Mode
|
31 | TCCR0B |= ((1<<CS01)|(1<<CS00)); //Teiler Osz/64 auf 125kHz
|
32 | OCR0A = 0x7C; //Interrupt alle ms; 1/125kHz=8us; 8us*0x7C=8us*125=1ms
|
33 | TIMSK0 |= (1<<OCIE0A); //Compare Match A Interrupt Enable
|
34 | //Timer1
|
35 | TCCR1B |= (1<<CS11); //Teiler Osz/8 auf 1Mhz
|
36 | TIMSK1 |= (1<<TOIE1); //Overflow Interrupt Enable
|
37 |
|
38 | }
|
39 | void adcinit(void) //ADC Einstellungen
|
40 | {
|
41 | ADMUX |= ((1<<REFS0)|(1<<ADLAR)); //Reference Selection AVCC mit Kondensator
|
42 | ADCSRA |= (1<<ADEN); //ADC Enable
|
43 | DIDR0 = 0xFE; //andere Pins disable (Sensor an PA0)
|
44 | }
|
45 | void intinit(void) //Externe Interrupts
|
46 | {
|
47 | EICRA |= (1<<ISC00); //INT0: immer wenn eine Zustandsaenderung ist
|
48 | EIMSK |= (1<<INT0); //INT0: ENABLE
|
49 | }
|
50 | int main (void) //Haubtprogramm
|
51 | {
|
52 | portinit();
|
53 | timerinit();
|
54 | adcinit();
|
55 |
|
56 | PORTD = 0x08; //high fuer DCF77
|
57 |
|
58 | intinit();
|
59 |
|
60 | sei(); //Alle Interrupts aktivieren
|
61 |
|
62 | PORTD = 0x00; //low fuer DCF77 / Start der Uhr
|
63 |
|
64 | while(1); //Warteschleife
|
65 | }
|
66 | ISR(INT0_vect) //DCF Signal
|
67 | {
|
68 | if (INT0 == 1) counter = 0; //Beginn des High
|
69 | else //Ende des High
|
70 | {
|
71 | if (counter <= 150) DCF[n] = 0;
|
72 | else if (counter <= 250) DCF[n] = 1;
|
73 | n++; //für nächsten durchlauf n+1
|
74 | if (counter >= 500) n = 0;
|
75 | }
|
76 | if(n == 36 && time == false) //Zeit das erstemal empfangen
|
77 | {
|
78 | if ( ((DCF[21] + DCF[22] + DCF[23] + DCF[24] + DCF[25] + DCF[26] + DCF[27])%2 == DCF[28]) && ((DCF[29] + DCF[30] + DCF[31] + DCF[32] + DCF[33] + DCF[34])%2 == DCF[35]) ) //Prüfen des empfangenen Signales
|
79 | {
|
80 | ss = 36;
|
81 | if (DCF[21] == 1) mm = mm + 1; //Minuten Einer
|
82 | if (DCF[22] == 1) mm = mm + 2;
|
83 | if (DCF[23] == 1) mm = mm + 4;
|
84 | if (DCF[24] == 1) mm = mm + 8;
|
85 | if (DCF[25] == 1) mm = mm + 10; //Minuten Zehner
|
86 | if (DCF[26] == 1) mm = mm + 20;
|
87 | if (DCF[27] == 1) mm = mm + 40;
|
88 | if (DCF[29] == 1) hh = hh + 1; //Stunden Einer
|
89 | if (DCF[30] == 1) hh = hh + 2;
|
90 | if (DCF[31] == 1) hh = hh + 4;
|
91 | if (DCF[32] == 1) hh = hh + 8;
|
92 | if (DCF[33] == 1) hh = hh + 10; //Stunden Zehner
|
93 | if (DCF[34] == 1) hh = hh + 20;
|
94 |
|
95 | time = true; //Zeit ist korrekt
|
96 | }
|
97 | if (DCF[19] == 1); //Sommer- oder Winterzeit
|
98 | {
|
99 | if ((DCF[17] == 1) && (DCF [18] == 0)) hh++; //MESZ
|
100 | if ((DCF[17] == 0) && (DCF [18] == 1)) hh--; //MEZ
|
101 | }
|
102 | if ((mm == 0) && (n==36)) //Zeitkontrolle
|
103 | {
|
104 | mmc = 0, hhc = 0, ss = 36;
|
105 | if (DCF[21] == 1) mmc = mmc + 1; //Minuten Einer
|
106 | if (DCF[22] == 1) mmc = mmc + 2;
|
107 | if (DCF[23] == 1) mmc = mmc + 4;
|
108 | if (DCF[24] == 1) mmc = mmc + 8;
|
109 | if (DCF[25] == 1) mmc = mmc + 10; //Minuten Zehner
|
110 | if (DCF[26] == 1) mmc = mmc + 20;
|
111 | if (DCF[27] == 1) mmc = mmc + 40;
|
112 | if (DCF[29] == 1) hhc = hhc + 1; //Stunden Einer
|
113 | if (DCF[30] == 1) hhc = hhc + 2;
|
114 | if (DCF[31] == 1) hhc = hhc + 4;
|
115 | if (DCF[32] == 1) hhc = hhc + 8;
|
116 | if (DCF[33] == 1) hhc = hhc + 10; //Stunden Zehner
|
117 | if (DCF[34] == 1) hhc = hhc + 20;
|
118 |
|
119 | if ((hh != hhc) && (mm != mmc)) //Wenn falsch dann aktualisieren
|
120 | {
|
121 | hh = hhc;
|
122 | mm = mmc;
|
123 | }
|
124 | }
|
125 | }
|
126 | }
|
127 | ISR(TIMER0_COMPA_vect) //Timer für Zeit
|
128 | {
|
129 | counter++;
|
130 | if(time == true)
|
131 | {
|
132 | hs++;
|
133 | if (hs == 1000) hs = 0, ss++, ADCSRA |= (1<<ADSC), light = ADCH; //Um einmal zu lesen dannach ist es wieder automatisch 0;
|
134 | if (ss == 60) ss = 0, mm++;
|
135 | if (mm == 60) mm = 0, hh++;
|
136 | if (hh == 24) hh = 0;
|
137 | mode = mm / 5;
|
138 | }
|
139 | }
|
140 | ISR(TIMER1_OVF_vect) //Timer für Anzeige
|
141 | {
|
142 | if (time == false) //Zu aendern je nach Beschaltung der LED-Strips
|
143 | {
|
144 | //1. FUNK 2. UHR
|
145 | }
|
146 | else
|
147 | {
|
148 | i++;
|
149 | if(i >= 0xFF) i = 0x00; //aendert die Helligkeit wenn man i höher oder niedriger zählen lässt
|
150 | if(i <= light)
|
151 | {
|
152 | switch (mode) //Zu aendern je nach Beschaltung der LED-Strips
|
153 | {
|
154 | case 0:
|
155 | //1. n 2. UHR (EINS ohne "S")
|
156 | break;
|
157 | case 1:
|
158 | //1. FÜNF 2. NACH 3. n
|
159 | break;
|
160 | case 2:
|
161 | //1. ZEHN 2. NACH 3. n
|
162 | break;
|
163 | case 3:
|
164 | //1. VIERTEL 2. n+1
|
165 | break;
|
166 | case 4:
|
167 | //1. ZWANZIG 2. NACH 3. n
|
168 | break;
|
169 | case 5:
|
170 | //1. FÜNF 2. VOR 3. HALB 4. n+1
|
171 | break;
|
172 | case 6:
|
173 | //1. HALB 2. n+1
|
174 | break;
|
175 | case 7:
|
176 | //1. FÜNF 2. NACH 3. HALB 4. n+1
|
177 | break;
|
178 | case 8:
|
179 | //1. ZEHN 2. NACH 3. HALB 4. n+1
|
180 | break;
|
181 | case 9:
|
182 | //1. DREI- 2. VIERTEL 3. n+1
|
183 | break;
|
184 | case 10:
|
185 | //1. ZEHN 2. VOR 3. n+1
|
186 | break;
|
187 | case 11:
|
188 | //1. FÜNF 2. VOR 3. n+1
|
189 | break;
|
190 | }
|
191 | }
|
192 | else PORTA = 0x00, PORTB = 0x00, PORTC = 0x00, PORTD = 0x00;
|
193 | }
|
194 | }
|