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


von Patrick R. (pat711)


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:
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include "lcd-routines.h"
4
#include <util/delay.h>
5
6
7
volatile uint8_t sollwert = 7, wert = 0,counter = 0;
8
uint16_t result;
9
uint16_t sens[4];
10
11
//--------------------------------ADC abfragen-----------------------------------------------------
12
uint16_t abfragen(uint8_t mux)
13
{
14
  uint8_t i;
15
  int i2 = 60;
16
  ADMUX = mux;                      // Kanal waehlen
17
  ADMUX |= (0<<REFS1) | (0<<REFS0); // interne Referenzspannung nutzen
18
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler 
19
                      // setzen auf 8 (1) und ADC aktivieren (1)
20
     
21
      /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
22
       also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
23
      ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
24
      while ( ADCSRA & (1<<ADSC) ) {
25
       ;     // auf Abschluss der Konvertierung warten 
26
      }
27
      result = ADCW;  // ADCW muss einmal gelesen werden,
28
              // sonst wird Ergebnis der nächsten Wandlung
29
              // nicht übernommen.
30
     
31
      /* Eigentliche Messung - Mittelwert aus 60 aufeinanderfolgenden Wandlungen */
32
      result = 0; 
33
      
34
35
      for( i=0; i<i2; i++ )
36
      {
37
      ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
38
      while ( ADCSRA & (1<<ADSC) ) {
39
        ;   // auf Abschluss der Konvertierung warten
40
      }
41
      result += ADCW;        // Wandlungsergebnisse aufaddieren
42
      
43
      }
44
      ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
45
     
46
      result /= i2;                          // Summe durch Anzahl der Messungen teilen -> arithm. Mittelwert
47
  return result;
48
}
49
50
//--------------------------------main-----------------------------------------------------
51
52
int main(void)
53
{  
54
  lcd_init();
55
  lcd_clear();
56
  while (1)
57
  {
58
    set_cursor(0,2);
59
    lcd_string("Wert:");
60
    for (counter = 0; counter < 4; counter ++)
61
    {
62
      abfragen(counter);
63
      sens[counter] = result;
64
    }
65
    lcd_clear();
66
    set_cursor(0,0);
67
    lcd_string("  Ueberwachung  ");
68
    /* Nur als test */
69
    wert = sens[0];
70
    /* Test Ende */
71
    if (wert > sollwert)    
72
    {
73
        PORTD |= 0x10;
74
    }
75
    char Buffer[20];
76
    itoa(wert, Buffer, 10);
77
    set_cursor(10,2);
78
    lcd_string( Buffer );
79
  }
80
}

von MWS (Gast)


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 ?

von Patrick R. (pat711)


Lesenswert?

wenn ich an dem eingang 5V anlege wird als wert 255 angezeigt

von MWS (Gast)


Lesenswert?

Bitteschön :-)

> wert = sens[0];

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

von avion23 (Gast)


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.

von Patrick R. (pat711)


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.

von Andreas R. (rebirama)


Lesenswert?

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

Mach dir nix draus, das passiert jedem mal.

... zu spät

von spess53 (Gast)


Lesenswert?

Hi

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

Das ist externe Referenzspannung.

MfG Spess

von Patrick R. (pat711)


Lesenswert?

@spess  jojo des passt die beschriftung is no irgendwie falsch... sry ^^

von Bernd (Gast)


Lesenswert?

result = ADC; hätte gereicht.

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.