1 | //
|
2 | // Anpassungen im makefile:
|
3 | // ATMega8 => MCU=atmega8 im makefile einstellen
|
4 | // lcd-routines.c in SRC = ... Zeile anhängen
|
5 | //
|
6 | #include <avr/io.h>
|
7 | #include <util/delay.h>
|
8 | #include "lcd-routines.h"
|
9 | #include "ADC.c"
|
10 | #include <stdlib.h>
|
11 |
|
12 | int main(void)
|
13 | {
|
14 | // fuer Rueckgabe ADC-Wert
|
15 | uint16_t adcval;
|
16 |
|
17 | // fuer Timer/ Zaehler
|
18 | uint8_t teiler=0x00;
|
19 | uint8_t sec = 0;
|
20 | uint8_t min = 0;
|
21 | uint16_t std=0;
|
22 | uint8_t zaehler_1=0;
|
23 |
|
24 | struct
|
25 | {
|
26 | unsigned hold:1; // hold für zaehlen Impulse PC1
|
27 | unsigned b1:1;
|
28 | unsigned b2:1;
|
29 | unsigned b3:1;
|
30 | unsigned b4:1;
|
31 | unsigned b5:1;
|
32 | unsigned b6:1;
|
33 | unsigned b7:1;
|
34 | } bin;
|
35 |
|
36 | // buffer fuer Konvertierung value to char
|
37 | char buf[5];
|
38 |
|
39 | //set PORTD for output: DDRD = 0xFF;
|
40 | DDRD = 0xFF;
|
41 |
|
42 | // folgende Zeilen sind für das LCD-Dicplay
|
43 | lcd_init();
|
44 |
|
45 | // TimerCounterControlRegister, setze Timer auf CPU-Takt/1024 = 15625
|
46 | TCCR0 = (1<<CS02) | (0<<CS01) | (1<<CS00);
|
47 | /*
|
48 | Der Zähler zählt nun aufwärts bis 255, um dann wieder bei 0 zu beginnen. Der aktuelle Zählerstand steht in TCNT0. Bei jedem Überlauf von 255 auf 0 wird das
|
49 | Timer Overflow Flag TOV0 im Timer Interrupt Flag TIFR-Register gesetzt und, falls so konfiguriert, ein entsprechender Timer-Overflow-Interrupt ausgelöst
|
50 | und die daran gebundene Interrupt-Routine abgearbeitet. Das TOV Flag lässt sich durch das Hineinschreiben einer 1 und nicht wie erwartet einer 0 wieder
|
51 | zurücksetzen.
|
52 | */
|
53 |
|
54 | // set PC1 for digital input
|
55 | DDRC &= ~( 1 << PC1 ); /* PIN PC1 auf Eingang (Taster) */
|
56 | PORTC |= ( 1 << PC1 ); /* Pullup-Widerstand aktivieren */
|
57 |
|
58 |
|
59 | while(1)
|
60 | {
|
61 | if (TIFR == (1<<TOV0))
|
62 | {
|
63 | // diese Routine wird alle 16384us aufgerufen
|
64 | // dies ergibt sich aus: 16Mhz=0.0625us
|
65 | // 8Bit-Timer: 0.0625us*8=16us
|
66 | // 1024 Prescaler: 16us*1024=16384us
|
67 | teiler ++;
|
68 | TIFR |= (1<<TOV0);
|
69 |
|
70 | // zaehlen Impulse PC1
|
71 | if (PINC & ( 1 << PC1))
|
72 | {
|
73 | if (!bin.hold)
|
74 | {
|
75 | bin.hold = 1;
|
76 | zaehler_1 ++;
|
77 | }
|
78 | }
|
79 | else
|
80 | {
|
81 | bin.hold = 0;
|
82 | }
|
83 | }
|
84 | switch (teiler)
|
85 | {
|
86 | case 11: // Aufruf 1* pro sec
|
87 | // wechseln des Zusandes PORTD.6
|
88 | PORTD ^= (1<<6);
|
89 | teiler ++;
|
90 | break;
|
91 |
|
92 | case 22: // Aufruf 1* pro sec
|
93 | // lesen Analog Channel 0 (10Bit)
|
94 | adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 -> PC0*/
|
95 | teiler ++;
|
96 | break;
|
97 |
|
98 | case 33: // Aufruf 1* pro sec
|
99 | if ( sec % 2 ) // sekünliche Abwechslung der Ausgabe
|
100 | {
|
101 | // Ausgabe des ADC-Messwertes auf dem Display
|
102 | utoa( 4.8876 * adcval, buf, 10); // Messbereichsendwert: 5000mVolt, Auflösung 10Bit=1023
|
103 | set_cursor(0,2);
|
104 | lcd_string("=>_____mVolt");
|
105 | set_cursor(0,2); // Spalte 2, Zeile 2
|
106 | lcd_string(buf); // write ADC-mV to display
|
107 | }
|
108 | else
|
109 | {
|
110 | // Ausgabe des Zaehler PinC.1 auf dem Display
|
111 | utoa( zaehler_1, buf, 10);
|
112 | set_cursor(0,2);
|
113 | lcd_string("=>_____Zaehler1");
|
114 | set_cursor(0,2); // Spalte 2, Zeile 2
|
115 | lcd_string(buf); // write ADC-mV to display
|
116 | }
|
117 | teiler ++;
|
118 | break;
|
119 |
|
120 | case 44: // Aufruf 1* pro sec
|
121 | // Ausgabe des Timer 0 auf dem Display
|
122 | set_cursor(0,1);
|
123 | lcd_string("________________");
|
124 |
|
125 | utoa( sec, buf, 10); // convert uint to char
|
126 | set_cursor(10,1); // Spalte 8, Zeile 1
|
127 | lcd_string(buf); // write ADC-value to display
|
128 |
|
129 | utoa( min, buf, 10); // convert uint to char
|
130 | set_cursor(5,1); // Spalte 8, Zeile 1
|
131 | lcd_string(buf); // write ADC-value to display
|
132 |
|
133 | utoa( std, buf, 10); // convert uint to char
|
134 | set_cursor(0,1); // Spalte 8, Zeile 1
|
135 | lcd_string(buf); // write ADC-value to display
|
136 |
|
137 | teiler ++;
|
138 | break;
|
139 |
|
140 | case 55: // Aufruf 1* pro sec
|
141 | // wechseln des Zusandes PORTD.6
|
142 | PORTD ^= (1<<6);
|
143 | teiler ++;
|
144 | break;
|
145 |
|
146 | case 66: // Aufruf 1* pro sec
|
147 | // nun ist eine Sekunde vergangen
|
148 | // erhöhe den Sekundenzähler
|
149 | teiler = 0;
|
150 | sec ++;
|
151 |
|
152 | if (sec==60)
|
153 | {
|
154 | min ++;
|
155 | sec = 0;
|
156 | }
|
157 |
|
158 | if (min==60)
|
159 | {
|
160 | std ++;
|
161 | min = 0;
|
162 | }
|
163 | }
|
164 | //_delay_ms(500);
|
165 | }
|
166 | return 0;
|
167 | }
|
168 |
|
169 |
|
170 | /*
|
171 | ab hier der Quellcode von ADC.c
|
172 |
|
173 |
|
174 |
|
175 | // Analog-Wert einlesen an PC1/adc1
|
176 | // Fuer ATmega8 mit 16Mhz externes Quarz
|
177 | // AVCC als Referenz
|
178 | // Grosam 13.10.2008
|
179 |
|
180 | uint16_t ReadChannel(uint8_t mux)
|
181 | {
|
182 | uint8_t i;
|
183 | uint16_t adcwert;
|
184 |
|
185 | ADMUX = (mux); //setze Bit für ADC Multiplexer Select Register, Kanal PC1 aktiviert
|
186 | ADMUX |= (1<<REFS0) | (0<<REFS1); //VCC als Referenz
|
187 |
|
188 | ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<< ADPS0); //16000000/128=125kHz
|
189 | // ADEN (ADC Enable)
|
190 | // ADPS2...ADPS0 (ADC Prescaler Select Bits) Teilungsfaktor für ADC-Takt
|
191 |
|
192 | // nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
193 | // also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen"
|
194 | ADCSRA |= (1<<ADSC); //setze Bit für ADSC (ADC Start Conversion)
|
195 | while (ADCSRA & (1<<ADSC) ) {
|
196 | ; // auf Abschluss der Konvertierung warten
|
197 | }
|
198 | adcwert = ADCW; //16Bit ADC-Wert
|
199 |
|
200 | //Richtiges Readout
|
201 |
|
202 | // Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen
|
203 | adcwert = 0;
|
204 | for( i=0; i<4; i++ )
|
205 | {
|
206 | ADCSRA |= (1<<ADSC); //setze Bit für ADSC (ADC Start Conversion) eine Wandlung "single conversion"
|
207 | while (ADCSRA & (1<<ADSC) ) {
|
208 | ; // auf Abschluss der Konvertierung warten
|
209 | }
|
210 | adcwert += ADCW; //16Bit ADC-Wert
|
211 | }
|
212 | ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
|
213 |
|
214 | adcwert /= 4; // Summe durch vier teilen = arithm. Mittelwert
|
215 |
|
216 | return adcwert;
|
217 | }
|
218 | */
|