1 | //Einbinen von Headerdateien
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 | //#include "C:\Users\patricke21\Documents\warten.h"
|
5 |
|
6 | // Taktfequenz der CPU
|
7 | #define F_CPU 16000000UL
|
8 |
|
9 |
|
10 |
|
11 | //Zentrale eingabe der Maximalwerte
|
12 |
|
13 | /*______________________________________________________________________________________________________________________________*/
|
14 |
|
15 | #define LIMIT_SPEED 2 // <- Hier die gewünsche MAXIMALE Windgeschwindigkeit in km/h eingeben!
|
16 |
|
17 | #define MELDEVERZOEGERUNG_WIND 0 // <- Hier die gewünschte Meldeverzögerung für Wind in Minuten eingeben!
|
18 |
|
19 | #define PULSEREGEN_LIMIT 2 // <- Hier die gewünschte Regenmenge eingeben!
|
20 |
|
21 | #define TIMEREGEN 10 // <- Hier Zeit, in Sekunden, zur Messung der Regenmenge eingeben!
|
22 |
|
23 | /*______________________________________________________________________________________________________________________________*/
|
24 |
|
25 |
|
26 |
|
27 | //Umrechnung der oben eingegebenen Werte:
|
28 |
|
29 | #define PULSEWIND_LIMIT ( (LIMIT_SPEED * 1800 ) / 60 / 2 ) //Berechung der MAXIMALEN Pulse für 15 Sekunden
|
30 |
|
31 | #define WARTEZEIT_WIND ( MELDEVERZOEGERUNG_WIND * 4 ) //Umrechung der MELDEVERZÖGERUNG für den Wind
|
32 |
|
33 |
|
34 |
|
35 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
36 | //Variablen deklaration:
|
37 |
|
38 | volatile uint8_t timewind = 0, timeregen = 0/*, Messungfertig = 0, Merker2 = 0*/;
|
39 |
|
40 | uint8_t vorherwind, jetztwind, wartezeitwind, vorherregen, jetztregen, pulseregen = 0, wind = 0;
|
41 |
|
42 | uint8_t Windrichtung = 0, Lichtsensor1 = 1, Lichtsensor2 = 2, Lichtsensor3 = 3, Lichtsensor4 = 4, Lichtsensor5 = 5, Spannung = 6, Strom = 7;
|
43 |
|
44 | uint16_t pulsewind;
|
45 |
|
46 | float windrichtung;
|
47 |
|
48 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
49 |
|
50 | /*----------- Einbinden von Funktionen ------------*/
|
51 |
|
52 | void DDR_config ( void ) ;
|
53 | void TIMER_config ( void ) ;
|
54 | void INTERRUPT_config ( void ) ;
|
55 | void adc_init ( void ) ;
|
56 | uint16_t adc_read ( uint8_t ) ;
|
57 |
|
58 |
|
59 |
|
60 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
61 | //Timer ISR zur Zeitmessung
|
62 |
|
63 | ISR(TIMER1_COMPA_vect)
|
64 | {
|
65 | if ( timewind > 0 )
|
66 | {
|
67 | timewind--;
|
68 | }
|
69 | if ( timeregen > 0 )
|
70 | {
|
71 | timeregen--;
|
72 | }
|
73 | }
|
74 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
75 |
|
76 |
|
77 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
78 | //ISR Regenerkennung:
|
79 |
|
80 | ISR(INT0_vect)
|
81 | {
|
82 | pulseregen++; //Aufaddieren der Pulse vom PIND2
|
83 | }
|
84 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
85 |
|
86 |
|
87 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
88 | //ISR zur Windrichtungsauslesung
|
89 |
|
90 | ISR(INT1_vect)
|
91 | {
|
92 | // PORTB ^= ( 1 << PB5 );
|
93 | }
|
94 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
95 |
|
96 |
|
97 | // Hauptprogramm:
|
98 |
|
99 | int main (void)
|
100 |
|
101 | {
|
102 |
|
103 | DDR_config ( ) ; //Aufruf des Daten Richtungs Registers zur Konfiguration der Ein- u. Ausgänge
|
104 | TIMER_config ( ) ; //Interner Timer1 konfigurieren
|
105 | INTERRUPT_config ( ) ; //Externe Interrupts ( INT0 bis INT2 ) konfigurieren
|
106 | sei ( ) ; //Interrupts AKTIVIEREN!!!!
|
107 |
|
108 |
|
109 | // adc_init ();
|
110 |
|
111 |
|
112 | /*------------- Zeiteinstellungen -------------*/
|
113 |
|
114 | //Zeit für Wind:
|
115 | timewind = 15;
|
116 |
|
117 | //Zeit für Regen:
|
118 | timeregen = TIMEREGEN;
|
119 |
|
120 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
121 | //Definieren der ersten Zustände für Flankenerkennung:
|
122 |
|
123 | vorherwind = ( PIND & ( 1 << PD0 ) );
|
124 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
125 |
|
126 |
|
127 | //Ständig laufendes Programm:
|
128 |
|
129 | while(1)
|
130 | {
|
131 |
|
132 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
133 | //Ermittlung der Windgeschwindigkeit:
|
134 |
|
135 | jetztwind = ( PIND & ( 1 << PD0 ) ); //Abfrage ob Taster gedrückt und Abfrage speichern
|
136 |
|
137 | if ( jetztwind != vorherwind ) //Vergleich der beiden Vaiablen, wenn ungleich dann weiter
|
138 | {
|
139 | vorherwind = jetztwind; //aktueller Wert speichern
|
140 |
|
141 | if ( jetztwind )
|
142 | {
|
143 | pulsewind++; //Wird um 1 erhöht, wenn steigende Flanke am Eingang PD0 erkannt
|
144 | }
|
145 | };
|
146 |
|
147 | if ( timewind == 0 ) //Abfrage der Zeit
|
148 | {
|
149 | if ( pulsewind > PULSEWIND_LIMIT ) //Abfrage der Pulse
|
150 | {
|
151 | wind++;
|
152 |
|
153 | if ( wind >= WARTEZEIT_WIND )
|
154 | {
|
155 | PORTD |= ( 1 << PD1 ); // Ausgang zum Haupt uC an PIND2 INT0
|
156 | PORTB |= ( 1 << PB0 ); // Anzeige LED
|
157 | wind = 0;
|
158 | }
|
159 | }
|
160 |
|
161 | else
|
162 | {
|
163 | PORTD &= ~( 1 << PD1 ); //Ausgang zum Haupt uC an PIND2 INT0
|
164 | PORTB &= ~( 1 << PB0 ); //Anzeige LED
|
165 | wind = 0;
|
166 | }
|
167 |
|
168 | pulsewind = 0; //Zurücksetzen der Werte
|
169 | timewind = 15; //Zurücksetzen der Werte
|
170 | }
|
171 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
172 |
|
173 |
|
174 | /*------------------------------------------------------------------------------------------------------------------------------*/
|
175 | // Ermittlung der Regenmenge
|
176 |
|
177 | if ( ( pulseregen >= PULSEREGEN_LIMIT ) && ( timeregen == 0 ) ) //Abfrage der Pulse und der Zeit
|
178 | {
|
179 | //Einschalten der Ausgänge
|
180 |
|
181 | PORTD |= ( 1 << PD4 ); //Ausgang zum Haupt uC an PIND3 INT1
|
182 | PORTB |= ( 1 << PB1 ); //Anzeige LED
|
183 |
|
184 | // windrichtung = adc_read ( Windrichtung );/*ADCW; //Auslesen des Ergebnisses der ADC Wandlung*/
|
185 |
|
186 | /* Ergebnisse für die Himmelsrichtungen:
|
187 | N = 788, NO = 464, O = 93, SO = 186, S = 288, SW = 634, W = 946, NW = 889*/
|
188 |
|
189 | pulseregen = 0; //Zurücksetzen der Werte
|
190 | timeregen = TIMEREGEN; //Zurücksetzen der Werte
|
191 | };
|
192 |
|
193 | if ( ( pulseregen < PULSEREGEN_LIMIT ) && ( timeregen == 0 ) ) //Abfrage der Pulse und der Zeit
|
194 | {
|
195 | //Ausschalten der Ausgänge
|
196 |
|
197 | PORTD &= ~( 1 << PD4 ); //Ausgang zum Haupt uC an PIND3 INT1
|
198 | PORTB &= ~( 1 << PB1 ); //Anzeige LED
|
199 |
|
200 | pulseregen = 0; //Zurücksetzen der Werte
|
201 | timeregen = TIMEREGEN; //Zurücksetzen der Werte
|
202 | };
|
203 | }
|
204 | return 0;
|
205 | }
|
206 |
|
207 |
|
208 |
|
209 | /*---------- Konfigurieren des DDRA Register ----------*/
|
210 |
|
211 | void DDR_config ( void )
|
212 | {
|
213 | // DDRA = _BV ( PB ); //Konfiguration der Ein und Ausgänge an Pord A; 0=Eingang, 1=Ausgang
|
214 | DDRB = _BV ( PB1 ) | _BV ( PB0 ); //Konfiguration der Ein und Ausgänge an Pord B; 0=Eingang, 1=Ausgang
|
215 | // DDRC = _BV ( PB ); //Konfiguration der Ein und Ausgänge an Pord C; 0=Eingang, 1=Ausgang
|
216 | DDRD = _BV ( PD4 ) | _BV ( PD1 ); //Konfiguration der Ein und Ausgänge an Pord D; 0=Eingang, 1=Ausgang
|
217 | }
|
218 |
|
219 |
|
220 | /*---------- Initialisierung und einstellen des ADC ----------*/
|
221 |
|
222 | void adc_init ( void )
|
223 | {
|
224 | //ADC Wandler einstellen:
|
225 |
|
226 | ADCSRA = _BV ( ADEN ) | _BV ( ADPS0 ) | _BV ( ADPS1 ) | _BV ( ADPS2 ); /*Aktivieren
|
227 | und einstellen des ADC Wandlers, hier Prescaler auf 128 bei CPU Takt 16 MHz, entspricht 125kHz Taktfrequenz
|
228 | für ADC*/
|
229 | ADMUX = _BV ( REFS0 ); //AVCC als REFERENZSPANNUNG
|
230 |
|
231 | // "Dummy-Readout" /*Erste Messung zur Kallibrierung*/
|
232 |
|
233 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
234 | while (ADCSRA & (1<<ADSC) )
|
235 | { // auf Abschluss der Konvertierung warten
|
236 | }
|
237 | (void) ADCW; /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
238 | Wandlung nicht übernommen. */
|
239 | }
|
240 |
|
241 |
|
242 | /*---------- Werte am ADC messen ----------*/
|
243 |
|
244 | uint16_t adc_read ( uint8_t channel )
|
245 | {
|
246 | ADMUX &= ~ ( _BV ( MUX0 ) | _BV ( MUX1 ) | _BV ( MUX2 ) | _BV ( MUX3 ) | _BV ( MUX4 ) ) ;
|
247 | channel &= ( _BV ( MUX0 ) | _BV ( MUX1 ) | _BV ( MUX2 ) ) ; /*Maskieren der Variable Channel, damit keine falschen
|
248 | übergeben werden können */
|
249 | ADMUX |= channel ;
|
250 | ADCSRA |= _BV ( ADSC ) ; //Start der Messung
|
251 | while (ADCSRA & (1<<ADSC) ) // auf Abschluss der Messung warten
|
252 | {
|
253 | }
|
254 | return ADCW ; //Wert aus ADCW zurückgeben
|
255 | }
|
256 |
|
257 |
|
258 | /*---------- Timer einstellen----------*/
|
259 |
|
260 | void TIMER_config ( void )
|
261 | {
|
262 | TCCR1B = _BV ( WGM12 ) | _BV ( CS12 ) | _BV ( CS10 ) ; //Timer1 konfigurieren
|
263 | OCR1A = 15624 ; //Vergleichsregister setzten
|
264 | TIMSK = _BV ( OCIE1A ) ; //Timer1 CompA-Interrupt AKTIVIEREN
|
265 | }
|
266 |
|
267 |
|
268 | /*---------- Interrupts einstellen----------*/
|
269 |
|
270 | void INTERRUPT_config ( void )
|
271 | {
|
272 | MCUCR = _BV ( ISC11 ) | _BV ( ISC01 ); // 0b00001010; //Externe Interrupts konfigurieren (Fallende Flanke)
|
273 | GICR = _BV ( INT1 ) | _BV ( INT0 ); // 0b11000000; //Freigeben der Externen Interrups
|
274 | }
|