www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit A/D-Wandlung


Autor: Michael M. (robertt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an alle!

Ich versuche mich gerade neu am Microcontroller programmieren.
Mein Ziel ist es, eine Spannung, abgegriffen über ein Potentiometer
(o-5V), in ein digitales Signal umzuwandeln, und je nach dem, wie hoch
die Spannung ist, möchte ich, dasss erst keine, dann eine, dann zwei und
schließlich 3 LEDs leuchten.
Ich habe ein Atmega8 (myAVR Board USB2.0), dabei habe ich das
Potentiometer an PortC.0 angeschlossen, dies entspricht dem Channel0 im
A/D-Wandler. Als Ausgabe dienen normal die Ports B.0 bis B.2.

Hier mein kleines Programm:

#define F_CPU 3686400
#include <avr\io.h>
#include <avr/interrupt.h>
#include <inttypes.h>


ISR (ADC_vect)
{
  int wert;
  wert = ADC;                             //Konvertierte Zahl wird in
ADC gechrieben

  if (0b0000000000 < wert <= 0b0100000000)//0V - 1,25V
    PORTB = 0b00000000;
  if (0b0100000000 < wert <= 0b1000000000)//1,25V - 2,5V
    PORTB = 0b00000001;
  if (0b1000000000 < wert <= 0b1100000000)//2,5V - 3,75V
    PORTB = 0b00000011;
  if (0b1100000000 < wert <= 0b1111111111)//3,75V - 5V
    PORTB = 0b00000111;

  sbi (ADCSRA,6);

}

void initADC()
{
  ADMUX  = 0;                             // Kanal 0
  ADCSRA = 0xDD;                          //enable, free run,
intterrupt, runtergetaktet(da adu langsamer als CPU)
}

int main (void)
{

  DDRB = 0xFF;                            // Port B = Ausgang
  PORTB= 0xFF;
  initADC();
  sei ();                                 // Interupts erlauben
  do { } while(true);

}


Ich habe die 5V in 4 Bereiche eingeteilt und diese dann in etwa ins
binäre 10Bit umgerechnet, da laut Datenblatt 0V 0000000000b entsprechen
und 5V 1111111111b. Wie man sieht ist ein 10bit AD-Umwandler vorhanden.

Mein Problem ist nun, dass immer alle 3 LED leuchten, egal wie ich das
Potentiometer drehe. Könnte es vllt. Probleme mit der 10bit gewandelten
Zahl geben?

Vielen Dank für eure Hilfe
Viele Grüße

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AREF nicht angeschlossen?

Autor: Michael M. (robertt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da nimmt er die boardspannung, müsste ich denke ich nicht extra 
anschließen, laut datenblatt;

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael M. schrieb:
> da nimmt er die boardspannung, müsste ich denke ich nicht extra
> anschließen, laut datenblatt;

nö, du stellst doch auf AREF, und wenn da nix anliegt, ist dein Wandler 
doch immer auf Maximalwert...

Autor: Michael M. (robertt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ich hab gerade noch mal geschaut, aref ist mit dem potentiometer 
verbunden

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael M. schrieb:
> also ich hab gerade noch mal geschaut, aref ist mit dem potentiometer
> verbunden

AREF geht über einen Kondensator an GND laut Schaltplan...

Autor: Michael M. (robertt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und das heißt jetzt für mich? ( wenn ich die leiteruüge an der 
boarunterseite weiter verfolge, komme ich zum potentiometer :()

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael M. schrieb:
> ( wenn ich die leiteruüge an der
> boarunterseite weiter verfolge, komme ich zum potentiometer :()

ein Blick in den Schaltplan wäre sinnvoller...

und wenn ich mal davon ausgehe, dass du einen Poti auf dem Board 
benutzt, bei denen eh schon VCC anliegt, wäre es irgendwie praktisch, 
die Spannung auch als Referenz zu wählen...

übrigens wäre es auch nett von dir, wenn du Schaltpläne etc und was du 
wie angeschlossen hast von Anfang an preisgibst und dir nicht alles aus 
der Nase ziehen lässt...irgendwie geht jeder zweite Fragesteller hier 
davon aus, dass alle anderen Kristallkugeln zu Hause haben...

Autor: Michael M. (robertt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es tut mir leid, dass ich mich hier noch nicht so auskenne. Ich versuche 
mich gerade in die Thematik tiefer einzusteigen.

Verbunden ist es, keine Änderung. Ich denke, dass es am Programm liegt.

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

Bewertung
0 lesenswert
nicht lesenswert
Michael M. schrieb:
> also ich hab gerade noch mal geschaut, aref ist mit dem potentiometer
> verbunden

Und? Hängt da sonst noch was an AREF?

So wie du ADMUX programmiert hast, musst du eine externe Spannung an 
AREF anschliessen.

Man kann über ADMUX den AREF Pin auch so programmieren, dass sich der µC 
selbst eine Referenzspannung erzeugt.

>  ADCSRA = 0xDD;                          //enable, free run,

Mach das nicht.
Kein Mensch hat Lust dazu, 0xDD im Kopf in eine binäre Darstellung 
umzuwandeln um mit dem Datenblatt zu recherchieren, welche Bits du da 
gesetzt hast.
0xDD = 0b11011101
Das ist ADEN, ADSC, ADIF, ADIE, ADPS2, ADPS0 gesetzt.

Schreib das auch im Code so!

   ADCSRA = ( 1 << ADEN ) | ( 1 << ADSC ) |
            ( 1 << ADIF ) | ( 1 << ADIE ) |
            ( 1 << ADPS2 ) | ( 1 << ADPS0 );

Damit sieht man auch im Code zumindest mal, welche Bits im Control 
Register gesetzt werden und muss nicht mühsam eine Hex-Zahl 
auseinanderpfriemeln.

Ich seh nirgends, wo du ADATE setzt um den Free Running Mode zu 
aktivieren.

Das hier
  if (0b0000000000 < wert <= 0b0100000000)//0V - 1,25V
    PORTB = 0b00000000;
  if (0b0100000000 < wert <= 0b1000000000)//1,25V - 2,5V
    PORTB = 0b00000001;
  if (0b1000000000 < wert <= 0b1100000000)//2,5V - 3,75V
    PORTB = 0b00000011;
  if (0b1100000000 < wert <= 0b1111111111)//3,75V - 5V
    PORTB = 0b00000111;

ist falsch. Du kannst Vergleiche nicht so kaskadieren, wie du dir das 
vorstellst. Ein Vergleichsoperator hat im Regelfall immer links von sich 
einen Wert und rechts von sich einen Wert. Mehrere Vergleiche werden mit 
&& bzw. || miteinander verknüpft. Das was du da geschrieben hast, ist 
zwar nach den C-Regeln durchaus erlaubt und syntaktisch korrekt, macht 
aber ganz was Anderes als du vermutest. Auch gibt es nun wirklich keinen 
Grund da Binärzahlen für die Werte zu verwenden. Dein ADC liefert Werte 
von 0 bis 1023. Die Binärdarstellung interessiert normalerweise 
niemanden. Interessant ist praktisch immer das Verhältnis des ADC Wertes 
zu 1023, da es eine Aussage darüber erlaubt in welchem Verhältnis die 
gemessene Spannung zu AREF steht. AREF kennt man und daher kann man 
zurückrechnen, welche Spannung am Messeingang anliegt. Das sind aber 
alles Berechnungen. Da interessieren Zahlen und keine einzelnen Bits. 
Wenn du zum setzen der Portbits für die Anzeige Binärdarstellung 
benutzt, dann geht das in Ordnung (auch wenn es da eine bessere 
Schreibweise gibt): Dort ist jedes einzelne Bit wichtig, weil jedes Bit 
für eine LED steht. Und in einer Binärdarstellung sieht man wiederrum 
besser welches Bit gesetzt wird und welches nicht - vulgo: welche LED 
eingeschaltet wird und welche nicht. Die Wahl der Darstellung einer 
Zahl, dezimal hex oder binär, passt man dem Verwendungszweck an und 
welcher Aspekt davon wichtig ist.

besser so:
  unsigned int wert;     // wert kann per Definition nicht negativ sein
  wert = ADCW;           // Konvertierte Zahl wird in

  if ( wert <= 256 )     // 0V - 1,25V
    PORTB = 0b00000000;

  else if ( wert <= 512 ) // 1,25V - 2,5V
    PORTB = 0b00000001;

  else if ( wert <= 768 ) // 2,5V - 3,75V
    PORTB = 0b00000011;

  else
    PORTB = 0b00000111;

PS: Warum verwendest du für deine ersten Versuche nicht die 
funktionierende ADC Routine aus dem Tutorial?

Autor: Michael M. (robertt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab vielen Dank, jetzt funktioniert es, super ;). Mir war nich bewusst, 
dass mein Vergleich mit dem Wert so nicht geht. Ich dachte, dass meine 
Syntax funktioniert.

Hab auch vielen Dank für deine konstruktive Kritik, ich wusste auch 
nicht, dass ich ADCSRA auf deinem Weg initialisieren kann. So erscheint 
es natürlich logischer und nachvollziehbarer.
Ich werde bei meinem nächsten Problem versuchen, es verständlicher zu 
machen. Ich dachte eben, dass ich solche Kniffe von Profis hier lerne 
und nicht schon wissen muss und nicht als Neuling (auch im Forum) gleich 
angeraunt werde.

Vielen Grüße

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.