1 | #include <stdint.h>
|
2 | #include <avr/io.h>
|
3 | #include <inttypes.h>
|
4 |
|
5 | #define LED_TOGGLE_CYCLE 1000
|
6 |
|
7 | uint16_t adcmessung(uint8_t ref_und_mux)
|
8 |
|
9 | {
|
10 | uint16_t messwert;
|
11 | uint8_t i;
|
12 |
|
13 | ADMUX = ref_und_mux;
|
14 | ADCSRA = (1<<ADEN);
|
15 |
|
16 | /*
|
17 | Nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen,
|
18 | man liest also einen Wert und verwirft diesen, um den ADC
|
19 | "warmlaufen zu lassen"
|
20 | */
|
21 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
22 | while ( ADCSRA & (1<<ADSC) )
|
23 | {
|
24 | ; // auf Abschluss der Konvertierung warten
|
25 | }
|
26 | messwert = ADCW; // Auslesen (Pflicht!)
|
27 |
|
28 | /*
|
29 | Eigentliche Messung: Mittelwert aus 4 Wandlungen
|
30 | */
|
31 | messwert = 0;
|
32 | for( i=0; i<4; i++ )
|
33 | {
|
34 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
35 | while ( ADCSRA & (1<<ADSC) )
|
36 | {
|
37 | ; // auf Abschluss der Konvertierung warten
|
38 | }
|
39 | messwert += ADCW; // Wandlungsergebnisse aufaddieren (messwert=messwert+ADCW)
|
40 | }
|
41 |
|
42 | ADCSRA &= ~(1<<ADEN); // ADC disable (Stromsparen)
|
43 | messwert /= 4; // Summe durch vier teilen = arithm. Mittelwert
|
44 | return messwert;
|
45 | }
|
46 |
|
47 |
|
48 | /*
|
49 | Spannungsmessung zur Batterieueberwachung
|
50 | MUX5...0 1,1 V (interne Referenz) auf ADC geben
|
51 | und mit Referenzspg. = VCC messen.
|
52 | */
|
53 | void batterieueberwachung(void)
|
54 | {
|
55 | uint16_t messwert; // Variable messwert
|
56 |
|
57 | messwert = adcmessung((0<<REFS1)|(0<<REFS0)|(1<<MUX5)|(1<<MUX0));
|
58 |
|
59 | /*
|
60 | 1D6h = 470d; bei VCC 2,4V entspricht 1,1V der
|
61 | externen Referenz 470 "Stufen" im 10Bit ADC
|
62 | ADCW = 1024 * 1.1 / Vcc
|
63 | */
|
64 | if(messwert >= ((1024*11)/24))
|
65 | {
|
66 | PORTB &= ~(1<<PB1); // Batterie-LED an (low-active)
|
67 | }
|
68 | }
|
69 |
|
70 |
|
71 | void feuchtemessung(void)
|
72 | {
|
73 | //unsigned long PassCount = 0;
|
74 | //unsigned char byToggle = 0;
|
75 | //PassCount ++;
|
76 |
|
77 | uint16_t messwert;
|
78 |
|
79 | messwert = adcmessung((0<<REFS1)|(0<<REFS0)|(0<<MUX5)|(0<<MUX0));
|
80 |
|
81 | if(messwert >= 0x96)
|
82 | {
|
83 | //if(PassCount % LED_TOGGLE_CYCLE == 0)
|
84 | //{
|
85 | // if(byToggle == 0)
|
86 | // {
|
87 | PORTA ^= (1<<PA1); // rote LED toggeln
|
88 | PORTA |= (1<<PA2)|(1<<PA3); // restl. LEDs aus
|
89 | // byToggle = 1;
|
90 | // }
|
91 | // else
|
92 | // {
|
93 | // PORTA = (1<<PA1);
|
94 | // PORTA |= (1<<PA2)|(1<<PA3);
|
95 | // byToggle = 0;
|
96 | // }
|
97 | // }
|
98 | }
|
99 | else if((messwert > 0x32) && (messwert < 0x96))
|
100 | {
|
101 | PORTA ^= (1<<PA2); // gelbe LED toggeln
|
102 | PORTA |= (1<<PA1)|(1<<PA3); // restl. LEDs aus
|
103 | }
|
104 | else if(messwert <= 0x32)
|
105 | {
|
106 | PORTA ^= (1<<PA3); // gruene LED toggeln
|
107 | PORTA |= (1<<PA1)|(1<<PA2); // restl. LEDs aus
|
108 | }
|
109 | }
|
110 |
|
111 |
|
112 | int main(void)
|
113 | {
|
114 | unsigned char trigger = 0;
|
115 |
|
116 | /* Initialisierung PortA */
|
117 | DDRA = (1<<PA1)|(1<<PA2)|(1<<PA3); // PA1, PA2, PA3 = Ausgang
|
118 | PORTA = (1<<PA1)|(1<<PA2)|(1<<PA3); // alle LEDs aus
|
119 |
|
120 | /* Initialisierung PortB */
|
121 | DDRB |= (1<<PB1); // PB1 LED fuer Batterieueberwachung
|
122 | DDRB &= ~(1<<PB2); // PB2 Taster Eingang (low-active)
|
123 | PORTB = (1<<PB1)|(1<<PB2); // Taster an PB2 mit int. Pull-UP, Bat-LED aus
|
124 |
|
125 | while(1)
|
126 | {
|
127 | // z.B. jedes 256.te Mal
|
128 | if (trigger == 0)
|
129 | batterieueberwachung();
|
130 |
|
131 | // z.B. jedes 16. Mal
|
132 | if ((trigger & 16) == 0)
|
133 | feuchtemessung();
|
134 |
|
135 | trigger++;
|
136 | }
|
137 | }
|