Hallo!
Ich probiere etwas mit dem ADC meines Atmega8 herum, und bin auf
folgendes Problem gestoßen:
Wenn ich den ADC in den Free-Running-Mode schalte und Interrupts
aktiviere, dann kann ändert sich der Wert von ADC innerhalb des
Interrupt-Handlers scheinbar nicht, er bleibt immer gleich.
Benutze ich einen Timer-Interrupt, dann kann ich den korrekten Wert von
ADC jeweils im Interrupt auslesen.
Hintergrund ist, dass ich einen gleitenden Mittelwert errechnen will
und dafür jedes Wandelergebnis in ein Array schreiben möchte.
Hier sind die wichtigen Codeteile:
1 | #include <stdint.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/signal.h>
|
4 |
|
5 | ...
|
6 |
|
7 | #define AVERAGE_VAL 100
|
8 |
|
9 | volatile uint16_t vals[AVERAGE_VAL];
|
10 | volatile uint8_t ind = 0;
|
11 |
|
12 | SIGNAL(SIG_ADC)
|
13 | {
|
14 | /* Read the new value into the average array */
|
15 | if (ind > AVERAGE_VAL)
|
16 | ind = 0;
|
17 |
|
18 | vals[ind] = ADC;
|
19 | ind++;
|
20 | }
|
21 |
|
22 | ...
|
23 |
|
24 | void adc_init(void)
|
25 | {
|
26 | /* Enable ADC and set prescaler to 64 */
|
27 | ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1);
|
28 |
|
29 | /* Use interrupts and free-running mode */
|
30 | ADCSRA |= _BV(ADFR) |_BV(ADIE);
|
31 |
|
32 | /* Use input channel 0 (PORTC0) */
|
33 | ADMUX = 0;
|
34 |
|
35 | /* Start conversion */
|
36 | ADCSRA |= _BV(ADSC);
|
37 | }
|
Ich verwende einen Timer, der sich in gewissen abständen den Inhalt des
Arrays ansieht und den Mittelwert berechnet.
Mit der obigen Methode bleibt der Wert immer gleich (anscheinend das
erste Wandelergebnis).
Verschiebe ich den Code aus SIGNAL(SIG_ADC) in den Timerhandler,
funktioniert es.
Danke für Hilfe!