www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega 8 ADC nur 8 bit Auflösung


Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe folgendes Problem:

ich will einen Spannungswert von 0 - 5V am ADC einlesen. Rauskommen soll 
ein 16 - Bit wert (also 0 - 1023). nun bekomme ich allerdings nur eine 8 
- Bit auflösung. Kann mir jemand weiterhelfen?

die ADC - eingänge sind 0 - 3 vorerst wird aber nur 0 angezeigt. Die 
refe´renzspannung an AREF beträgt 5V.

Hier nun mein Code:
#include <avr/io.h>
#include <stdlib.h>
#include "lcd-routines.h"
#include <util/delay.h>


volatile uint8_t sollwert = 7, wert = 0,counter = 0;
uint16_t result;
uint16_t sens[4];

//--------------------------------ADC abfragen-----------------------------------------------------
uint16_t abfragen(uint8_t mux)
{
  uint8_t i;
  int i2 = 60;
  ADMUX = mux;                      // Kanal waehlen
  ADMUX |= (0<<REFS1) | (0<<REFS0); // interne Referenzspannung nutzen
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler 
                      // setzen auf 8 (1) und ADC aktivieren (1)
     
      /* 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 
      }
      result = ADCW;  // ADCW muss einmal gelesen werden,
              // sonst wird Ergebnis der nächsten Wandlung
              // nicht übernommen.
     
      /* Eigentliche Messung - Mittelwert aus 60 aufeinanderfolgenden Wandlungen */
      result = 0; 
      

      for( i=0; i<i2; 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 /= i2;                          // Summe durch Anzahl der Messungen teilen -> arithm. Mittelwert
  return result;
}

//--------------------------------main-----------------------------------------------------

int main(void)
{  
  lcd_init();
  lcd_clear();
  while (1)
  {
    set_cursor(0,2);
    lcd_string("Wert:");
    for (counter = 0; counter < 4; counter ++)
    {
      abfragen(counter);
      sens[counter] = result;
    }
    lcd_clear();
    set_cursor(0,0);
    lcd_string("  Ueberwachung  ");
    /* Nur als test */
    wert = sens[0];
    /* Test Ende */
    if (wert > sollwert)    
    {
        PORTD |= 0x10;
    }
    char Buffer[20];
    itoa(wert, Buffer, 10);
    set_cursor(10,2);
    lcd_string( Buffer );
  }
}

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Rauskommen soll ein 16 - Bit wert (also 0 - 1023)

1023 ist ein 10 Bit Wert und kein 16 Bit Wert. Wie äußert sich die "8 
Bit Auflösung" ? Welches Ergebnis wird angezeigt ?

Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn ich an dem eingang 5V anlege wird als wert 255 angezeigt

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitteschön :-)

> wert = sens[0];

Zuweisung eines uint16 an einen uint8, hat da der Compiler nicht 
gemeckert ?

Autor: avion23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass die Mittelwertbildung testweise weg.

Ersetz zum Test das ADCW durch ADCL | ADCh <<8

Bei mir im source code habe ich noch gefunden
//ADMUX_temp |= (1 << ADLAR);   // Sets right adjustment for ADC Results 
(default)
Also überprüf, ob das Bit richtig gesetzt ist.

Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
öh nö, thx

oh mann und ich dachte ich hätte alle variablentypen nochmal überprüft 
bevor ich nen Thread aufmach.(kopf gegen Wand)

thx


thx @avion23. Das ausbessern des Variablentyps hat das Problem bereits 
vollkommen behoben, trotzdem thx.

Autor: Andreas R. (rebirama)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mal als Tip: "wert" ist uint8,
Aber über den ADC meckern, tztztz...

Mach dir nix draus, das passiert jedem mal.

... zu spät

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>ADMUX |= (0<<REFS1) | (0<<REFS0); // interne Referenzspannung nutzen

Das ist externe Referenzspannung.

MfG Spess

Autor: Patrick R. (pat711)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@spess  jojo des passt die beschriftung is no irgendwie falsch... sry ^^

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
result = ADC; hätte gereicht.

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.