mikrocontroller.net

Forum: Compiler & IDEs ADC-Wert immer gleich


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
N'abend,
ich hab ein Problem bei einem Programm, wo ich den ADC verwende, auf 
einem ATMEGA32.
Hier erstmal das Programm:
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>

#include "uart-routines.h"

//ADC
uint16_t ADC_Read(uint8_t channel)
{
  uint8_t i;
  uint16_t result=0;

  ADMUX  = channel;

  ADCSRA |= ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));  //ADC aktivieren; Teilungsfaktor: 128 (ADPS*)
  
  ADCSRA |= (1<<ADSC);                      //ADC einmal starten um Dummy zu lesen, sonst passiert nix
  
  result = ADCW;                          //ADCW einmal lesen sonst beim naechsten mal keine Uebernahme
  
  result = 0;
  
  for(i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);                    //single conversion
    while( ADCSRA & (1<<ADSC) )
    {
      ;                            //Warten auf Konvertierung
    }
    result += ADCW;                        //Wandlungsergebnis aufaddieren
  }
  
  ADCSRA &= ~(1<<ADEN);                      //ADC deaktivieren
  
  result = result/4;                        //Wandlungsergebnis durch Anzahl Messungen
  
  return result;
}

int main (void)
{   
  uint16_t bat_mess_wert;
  char string[20];
  sei();
  uart_init(UART_BAUD_SELECT(9600,F_CPU));

  bat_mess_wert = ADC_Read(0);
  itoa(bat_mess_wert,string,10);
  uart_puts(string);
  uart_puts_P("\r\n");
        return (0);

}
Ich will damit die Spannung eines Akkus messen, zur Zeit haengt er auf 
5V mit einem Spannungsteiler 2*10k.
Externe Referenzspannung ist 3,3V.
Jetzt sollte mir ueber UART theoretisch nach Formel: 
ADC=(U_in*1024)/U_Ref=(2,5*1024)/3,3=775 angezeigt werden, aber ich 
bekomme nur 460+/-5 angezeigt.
Hab ich jetzt einen Denkfehler oder stimmt was mit dem ADC nicht?
Vielen Danke
Daniel

Autor: John Small (linux_80)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird der ADC-Eingang auch auf Eingang gestellt, oder hab ich das 
übersehen ?

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kay, herzlichen danke,
hab jetzt mit:
DDRA = 0x00;
PORTA = 0x1;
den Eingangs-Pull-Up aktiviert und krieg jetzt 1023+/-1 angezeigt, das 
sieht schon besser aus.
Leider hab ich den Akku nicht da, kann also nicht testen ob bei 
Spannungsverringerung dich der Adc wert ändert, aber das sollte jetzt ja 
passen oder?

Autor: John Small (linux_80)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Pullup kommt der max. Wert raus, könnte passen, ohne Pullup sollte 
dann gegen 0 gehen.
Wenn die Ref aber nur 3.3V hat, der Pullup aber 5V liefert, weiss ich 
nicht ob das so gut für den ADC ist.

Testen kannst Du mit einem Poti, oder einfach 2 Widerständen.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Daniel:

Ein fehlendes "DDRA=" ist sicher nicht das Problem, denn da du den Pin 
nirgendwo auf Ausgang stellst, ist er bereits ein Eingang.

So nebenbei:
Deine Dummy-Messung geht als erste Messung mit in das Ergebnis ein, weil 
du nicht auf das Ende dieser Messung wartest.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass das mit dem dummy-lesen einfach weg. Das steht zwar so im Tutorial, 
ist aber nur erforderlich, wenn auch der allererste Wert nach 
Power-On-Reset schon fehlerfrei sein muß.

Oliver

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt bin ich ein bisschen verwirrt, also die Routine ist der im 
GCC-Tutorial nachempfunden, da steht das so drin, deswegen verwundert 
mich das die Dummy-Abfrage so nicht funktionieren soll.
Also muss ich auch nicht den PULL-UP aktivieren?
Wie gesagt, wenn ich den Pull-up deaktiviere komm ich auf einen Wert von 
460.
Meine Anwendung soll sein, ich werd einen Lithium-Ionen Akku 
anschliessen der hat voll aufgeladen 3,7V, jetzt will ich mit dem ADC 
feststellen wie weit der entladen ist. Die Spannung greif ich ueber 
einen Spannungsteiler 2*10k ab, so das ich als abgegriffene Spannung 
3,7V/2 haben sollte.
Da ich den Akku bis jetzt noch nicht da hab, hab ich 5V Versorgung 
genommen, auch uebers Spannungsteiler 2*10k, sollten 2,5V rauskommen, 
kommen auch, das mit der ADC Formel: ADC=2,5*1024/3,3=775 sollten 
angezeigt werden.
Wie gesagt wird aber nicht?

Gruß
Daniel

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel wrote:
> Jetzt bin ich ein bisschen verwirrt, also die Routine ist der im
> GCC-Tutorial nachempfunden, da steht das so drin,

Nein, dort wird auf die Dummy-Messung gewartet.

Du solltest als erstes mal nachmessen, welche Spannungen du denn 
tatsächlich an Vref und am ADC-Eingang hast.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hab ich jetzt einen Denkfehler oder stimmt was mit dem ADC nicht?

Ich habe schonmal einen Mega32 mit zerschossenenm ADC-Eingang, der 
direkt an 5V 200mA gezogen hat. Der würde dir natürlich die 
Eingangspannung vom Spannungsteiler in den Keller ziehen. Das sollte 
sich aber schnell nachmessen lassen.

Der ADC selber hat dabei immer noch richtig gemessen, ohne Vorwiderstand 
stimmte alles. Nur der Stromverbrauch war dann etwas hoch :-)

Oliver

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Jetzt bin ich ein bisschen verwirrt, also die Routine ist der im
> GCC-Tutorial nachempfunden, da steht das so drin,

Wie schon geschrieben wurde, steht da was anderes.
Der Kommentar in deiner Version
//ADC einmal starten um Dummy zu lesen, sonst passiert nix
ist auf jeden Fall verkehrt. Der dummy-read ist ein ganz normlaes 
Auslesen des ADC's, es kann nur vorkommen, daß der erste gelesene Wert 
nach einer bestimmten Aktion fehlerhaft ist. Insofern musst du da auch 
ganz normal auf das Ende der Konversion warten.
Welche Aktionen zu fehlerhaften Werten führen, steht im Datenblatt. Ob 
gewollt oder nicht, unterscheiden sich die Datenblätter der 
verschiedenen AVR's da etwas. Das des Mega32 lese ich so, daß in deinem 
Fall kein dummy-Read erforderlich ist. Solange kein 
timimg-Problemcauftritt, schadet der dummy-read natürlich nicht.

Oliver

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also danke das mit dem dummy-Read hab ich verbessert,
so hab dann mal an Vref und ADC-Eingang gemessen:
Vref=3,29V
Vadc=2,49V
sollten nach Formel: 779 geben, krieg aber jetzt 450 ohne Pullup.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum gibst Du überhaupt die Interrupts frei? Wenn Du keine Interrupts 
nutzt, lass das sei() weg!

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BTW: AVCC korrekt angeschlossen?

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sei() brauch ich fuer den uart und AVCC hat 3,29V mit nem 100nF gegen 
Masse.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du betreibst den AVR mit 3,3 V? Warum dann die externe Referenz? AVCC 
kann man auch intern als Referenz wählen...

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jo betreib ihn mit 3,3V, hab mal umgestellt:
  ADMUX |= (1<<REFS0);                            //AVCC als 
Spannungsreferenz
jetzt wieder 450 als Ausgabe.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm

Wie sieht dein Programm jetzt aus?

Kannst du mal ein Poti an den ADC Eingang hängen, den ADC kontinuierlich 
in einer Schleife auslesen (und natürlich den Wert anzeigen) und mal 
nachsehen, ob sich der Wert mit Drehen am Poti verändern lässt?

Autor: Michael 93 (michael93) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Li-Ion Akku hat voll aufgeladen eine Spannung von 4,2 V pro Zelle. 
Und an AVCC muss die selbe Spannung liegen wie an den restichen VCC 
pins.

Michael

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry Leute, ich muss mich entschuldigen, ich bin manchmal so ein Depp, 
ich hab es leider voll verrissen, Es war der falsche Pin^^ Ich hin gar 
nicht an PORTA.0 sondern an 7. Bin da auch nicht draufgekommen weil an 
der A.0 auch was hing, na gut danke fuer die zahlreichen Tipps und sorry 
bezueglich meiner Bloedheit
Gruß
Daniel

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.