ATMega8 interner ADC

Gast #6804969
Lesenswert?

Hallo alle miteinander!

Ich möchte mit meinem ATMega8 Spannungen einlesen und diese dann mittels 
LED Anzeige ausgeben lassen (also bitweise Darstellung).

Hier ist schonmal mein Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
volatile uint16_t c = 0;
5

6
void out (volatile uint16_t value);
7

8
int main(void)
9
{
10
  DDRB |= (1 << PB0);
11
  DDRC |= 0x3E;
12
  DDRD |= 0xF0;
13
  
14
  ADMUX = 0x0000;
15
  ADCSRA |= (1<<ADFR) | (1<<ADEN) |  (1<<ADPS2);  
16
  ADCSRA |= (1<<ADIE);              
17
  sei();
18
  
19
  ADCSRA |= (1<<ADSC);              
20
  while (ADCSRA & (1<<ADSC))            
21
  {
22
  }
23
  
24
    while (1) 
25
    {
26
    ADCSRA |= (1<<ADSC);
27
    
28
    while (ADCSRA & (1<<ADSC))
29
    {
30
    }
31

32
    c = ADCL;
33
    c += (ADCH << 8);
34
    }
35
  
36
}
37

38
ISR (ADC_vect)
39
 {
40
    out(c);
41
  PORTB |= (1<<PB1);  //Zur Kontrolle, ob er ins ISR geht
42
  ADCSRA |= (1<<ADSC);
43
 }
44

45
void out (volatile uint16_t value)
46
{
47
  PORTB ^= (1<<PB0);
48
  PORTD &= ~0xF0;
49
  PORTC &= ~0x3E;
50
  
51
  PORTD |= (uint8_t)((value >> 2) & 0xF0);
52
  PORTC |= (uint8_t)(value & 0x3E);  
53
}

Das ganze will jetzt aber leider nicht so wie ich will. Anscheinend geht 
er nicht ins ISR, da die Kontroll LED nie angesprochen wird.
Liegt das jetzt an meiner Konfiguration? Obwohl da ja nur angeprochen 
wird, oder ist etwas mit meiner Ausgabe nicht in Ordnung?

Für Hilfe wäre ich sehr dankbar :)
Moderator (Firma: Titel) Persönliche Seite #6804980
Lesenswert?

Tomato schrieb:
> Anscheinend geht er nicht ins ISR
Wofür brauchst du für diese simple Aufgabe einen Interrupt?
Ich würde die erst mal mit Polling lösen. Und ich sehe grade, dass du 
das auch tust. Zusätzlich zum Interupt...

Was passiert denn, wenn du das machst:
1
:
2
:
3
    ADCSRA |= (1<<ADSC);
4
    while (ADCSRA & (1<<ADSC))
5
    {
6
    }
7
    PORTB |= (1<<PB1);  //Zur Kontrolle, ob er überhaupt mal fertig wird
8

9
    while (1) 
10
:
11
:
12
ISR (ADC_vect)
13
{
14
   out(c);
15
//   PORTB |= (1<<PB1);  //Zur Kontrolle, ob er ins ISR geht
16
   ADCSRA |= (1<<ADSC);
17
}
18
:
19
:

BTW: dir ist schon klar, dass du den ADC nicht unbedingt selber in 2 
Zugriffen auslesen musst. Das macht der Compiler schon richtig, wenn du 
schreibst c = ADC;
Gast #6804982
Lesenswert?

Oh nein ... so ein dummer Fehler ... Danke ^^
Jetzt weiß ich zumindest schonmal, dass er ins ISR reingeht.
Aber meine Ausgabe ist leider noch immer nicht ganz korrekt. Es leuchten 
permanent alle LEDs, obwohl ja nur die einzelnen Bits leuchten sollten.

Lothar M. schrieb:
> Was passiert denn, wenn du das machst:

Die Kontoll-LED leuchtet nicht
Gast #6805045
Lesenswert?

Ich habe meinen Fehler gefunden.
Ich dachte, da ich meine "unbekannte" Spannung einlese benötige ich kein 
AREF. Das war aber eine falsche Annahme ^^'

Vielen Dank für die Antworten.
Solche Schusselfehler sollten jetzt nicht mehr vorkommen.
Gast #6805170
Lesenswert?

Wozu verwendest du hier den ADC-Interrupt?
Nach meinem bisherigen Verständnis ist der hauptsächlich dann sinnvoll, 
wenn man mit SLEEP_MODE_ADC den Noise Reduction Mode des ADC verwenden 
oder parallel zur AD-Wandlung was anderes tun will. Beides sehe ich in 
deinem Code nicht.
Vielleicht fehlt mir aber auch ein wenig Wissen über weitere Optionen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren