Forum: Compiler & IDEs Poti an A/D Wandler (C Code AVR)


von Markus (Gast)


Lesenswert?

Hi.
Ich versuche seid 2 Tagen verzweifelt an meinem ATMega8 ein Drehpoti
anzuschließen und dann mit hilfe des A/D Konverters die Stellung des
Potis rauszukriegen.
Meine Schaltung ist folgendermaßen aufgebaut:

GND an 0V
VCC an +5 V
POTI zwischen VCC und AD0
AREF an +5 V

Nur krieg ich von meinem A/D Wandler immer eine 0 zurück (dadurch
leuchtet meine LED unten im Code)
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
5
uint16_t ReadChannel(uint8_t mux)
6
{
7
  uint8_t i;
8
  uint32_t result = 0;
9
10
  ADCSRA = (1<<ADEN) | (1<<ADPS2) |(1<<ADPS1) | (1<<ADPS0);   
11
//Frequenzvorteiler
12
13
  ADMUX = mux;                      // Kanal waehlen
14
  ADMUX |= (0<<REFS1) | (0<<REFS0); // interne Referenzspannung nutzen
15
16
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
17
18
  while ( ADCSRA & (1<<ADIF) );     // auf Abschluss der Konvertierung
19
  ADCSRA = (1<<ADIF);          //ADIF wieder löschen
20
21
22
  for(i=0;i<4;i++)
23
  {
24
    ADCSRA |= (1<<ADSC);
25
    while ( ADCSRA & (1<<ADIF) );
26
    result += ADCW;
27
  ADCSRA = (1<<ADIF);        //ADIF wieder löschhen
28
  }
29
30
  ADCSRA &= ~(1<<ADEN);
31
  result /= 4;
32
  return result;
33
}
34
35
36
int main(void)
37
{
38
  DDRB = 0xFF;
39
  //PORTB = 0xFF;
40
  //PORTB = 0x00;
41
42
  uint16_t analogwert;
43
44
45
  while(1)
46
  {
47
    analogwert = ReadChannel(0);
48
49
    if (analogwert == 0)
50
      PORTB = 0xFF;  
51
    else
52
      PORTB = 0x00;
53
54
  }
55
  
56
57
}

von Markus (Gast)


Lesenswert?

PS:
Was mache ich falsch?

von Stefan K. (_sk_)


Lesenswert?

> POTI zwischen VCC und AD0

Poti nicht an GND angeschlossen??
Versuch mal:
POTI oben          -> VCC
POTI Mittelabgriff -> AD0
POTI unten         -> GND

> if (analogwert == 0)

Schlecht bei Analogwerten. Die sind meistens nie ganz NULL. Besser:
  #define MINIMUM 10
  if (analogwert < MINIMUM)


> Nur krieg ich von meinem A/D Wandler immer eine 0 zurück (dadurch
> leuchtet meine LED unten im Code)

Wie ist Deine LED an PORTB angschlossen? PORTB+GND oder PORTB+VCC?

Stefan

von Markus (Gast)


Lesenswert?

Also das mit dem == 0 hab ich deswegen gemacht weil ich es einfach
komisch finde das ich immer eine 0 zurückbekomme, das bei einem
Analogwert ... mir ist klar das ich normalerweise mit kleiner und
größer das abfangen soll aber warum krieg ich immer 0 raus?

Die LED is schon korrekt von PortB nach GND angeschlossen mit
Wiederstand.

Hab das natürlich am Poti auch so angeschlossen sorry hatte ich
vergessen also poti oben an VCC mitte an AD0 und unten and GND.

Stimmt mein Code wenigstens?

Der Poti hat 10K Ohm wenn das was hilft.


Danke für deine Antwort.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hast du dir mal das "largedemo" angeguckt?

http://www.nongnu.org/avr-libc/user-manual/group__largedemo.html

Da wird ein Poti in gleicher Weise benutzt.

Ich denke übrigens nicht, dass du zum Aufsummieren von 4
10-Bit-Werten wirklich eine 32-bit-Variable brauchst...

von Markus (Gast)


Lesenswert?

Hi danke ich bin gerade am Durchstöbern deines Links nur finde ich da
meinen Fehler immer noch nicht.

Wäre super wenn mir jemand sagen könnte ob meine Schaltung wenigstens
richtig angeschlossen ist oder ob der Code falsch ist.
Das mit der 32bit Variable ist nur deswegen da ich das aus einem Code
raus hab der das nicht mit 4 Werten sonder mit einer größerer Anzahl
macht wobei ich das im Moment erst mal so einfach wie möglich haben
möchte.

von Markus (Gast)


Lesenswert?

Jetzt hab ich zum testen die Zeile

ADCSRA = (1<<ADIF);        //ADIF wieder löschhen

entfernt und es funktioniert.


Steht wohl a bissal a schmarn im Tutorial !

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, damit bügelst du ja die komplette ADCSRA-Konfiguration.

Nach meinen Erfahrungen kann man übrigens den AD-Wandler am
einfachsten per Interrupt bedienen.

von mthomas (Gast)


Lesenswert?

> Steht wohl a bissal a schmarn im Tutorial !
Aha. Bitte erlaeutern. Welches Tutorial ist gemeint? Der gezeigt Code
weicht von dem im avr-gcc-Tutorial in wiki dieser Seite ab. Den
Unterschied zwischen ADIF und ADSC verstanden?

Martin Thomas

von Markus N. (Gast)


Lesenswert?

Hi Martin.
Also ich habe das teilweise aus dem AVR GCC tutorial.
Eest hab ich das komplett so wie im Tutorial abgeschrieben und dann
ging garnix. Und seid dem ich das eben geändert hab geht das jetzt
endlich gescheit.

Ne der Unterschied zwischen den beiden ADIF und ADSC ist mir noch nicht
ganz klar.

von Ingo (Gast)


Lesenswert?

Also im GCC Tutorial dieser Site steht nichts dergleichen von ADIF etc.
Direkt aus dem Tutorial kopiert:
1
uint16_t ReadChannel(uint8_t mux)
2
{
3
  uint8_t i;
4
  uint16_t result = 0;         //Initialisieren wichtig, da lokale
5
Variablen
6
                               //nicht automatisch initialisiert werden
7
und
8
                               //zufällige Werte haben. Sonst kann
9
Quatsch rauskommen
10
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler
11
12
                               // setzen auf 8 (1) und ADC aktivieren
13
(1)
14
15
  ADMUX = mux;                      // Kanal waehlen
16
  ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
17
18
19
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man
20
liest
21
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu
22
lassen" */
23
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
24
  while ( ADCSRA & (1<<ADSC) );     // auf Abschluss der Konvertierung
25
warten 
26
27
  /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden
28
Wandlungen */
29
  for(i=0;i<4;i++)
30
  {
31
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single
32
conversion"
33
    while ( ADCSRA & (1<<ADSC) );   // auf Abschluss der Konvertierung
34
warten
35
    result += ADCW;        // Wandlungsergebnisse aufaddieren
36
  }
37
  ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
38
39
  result /= 4;                     // Summe durch vier teilen = arithm.
40
Mittelwert
41
42
  return result;
43
}

Also bevor Ihr das nächste Mal auf die Autoren des Tutorials
einschlagt: Richtig RTFM'men :)

von Markus (Gast)


Lesenswert?

Also in meinem Code (ich habe das PDF File)
Steht das nun mal so da:

while(!(ADCSRA & (1<<ADIF)));

und dann

ADCSRA = (1<<ADIF);

von Walter (Gast)


Lesenswert?

ich habe auch den PDF-File, bei mir steht

for(i=0;i<4;i++)
{
  ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
  while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung
warten
  result += ADCW; // Wandlungsergebnisse aufaddieren
}
ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)

von Markus (Gast)


Lesenswert?

Ah ich habe mir gerade das neueste PDF angesehen und da ist es wirklich
weg.
Meine PDF Version habe ich mir runtergeladen als ich mit dem
Programmieren von µCs begonnen hab und das war vor einem Monat.

Also kommt mein altes Dokument mal weg.
Aber danke das du nachgeschaut hast.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.