www.mikrocontroller.net

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


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

#include <avr/io.h>
#include <stdint.h>


uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint32_t result = 0;

  ADCSRA = (1<<ADEN) | (1<<ADPS2) |(1<<ADPS1) | (1<<ADPS0);   
//Frequenzvorteiler

  ADMUX = mux;                      // Kanal waehlen
  ADMUX |= (0<<REFS1) | (0<<REFS0); // interne Referenzspannung nutzen

  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 

  while ( ADCSRA & (1<<ADIF) );     // auf Abschluss der Konvertierung
  ADCSRA = (1<<ADIF);          //ADIF wieder löschen


  for(i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);
    while ( ADCSRA & (1<<ADIF) );
    result += ADCW;
  ADCSRA = (1<<ADIF);        //ADIF wieder löschhen
  }

  ADCSRA &= ~(1<<ADEN);
  result /= 4;
  return result;
}


int main(void)
{
  DDRB = 0xFF;
  //PORTB = 0xFF;
  //PORTB = 0x00;

  uint16_t analogwert;


  while(1)
  {
    analogwert = ReadChannel(0);

    if (analogwert == 0)
      PORTB = 0xFF;  
    else
      PORTB = 0x00;

  }
  

}

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS:
Was mache ich falsch?

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du dir mal das "largedemo" angeguckt?

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

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...

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 !

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Markus N. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also im GCC Tutorial dieser Site steht nichts dergleichen von ADIF etc.
Direkt aus dem Tutorial kopiert:
uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint16_t result = 0;         //Initialisieren wichtig, da lokale
Variablen
                               //nicht automatisch initialisiert werden
und
                               //zufällige Werte haben. Sonst kann
Quatsch rauskommen
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler

                               // setzen auf 8 (1) und ADC aktivieren
(1)

  ADMUX = mux;                      // Kanal waehlen
  ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen


  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man
liest
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu
lassen" */
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
  while ( ADCSRA & (1<<ADSC) );     // auf Abschluss der Konvertierung
warten 

  /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden
Wandlungen */
  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)

  result /= 4;                     // Summe durch vier teilen = arithm.
Mittelwert

  return result;
}

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

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.