Forum: Compiler & IDEs AD Wandler funktioniert nicht.


von Lukas H. (Gast)


Lesenswert?

Ich versuche jetzt schon ein weilchen, den AD Wandler anzusprechen, aber 
ich schaffs einfach nicht.
Zur Hardware, ein Mega8 (16 Mhz) und am PortC Pin1 hängt ein analoger 
Sharp Abstandssensor (0 - 3 V). Am Port D hängen alles LED's (leuchten 
bei Low). Irgendwie habe ich das Gefühl, das Problem liegt nicht bei der 
Hardware ...
Hier mal mein Code, habe ich übrigens aus dem C Tutorial.

#include <io.h>
int main( void )
{
long x;     // Ich weiss wär nicht unbedingt nötig, aber lieber zu 
gross
long x2;
long wert;
outp(0xff,DDRD);
outp ((1<<ADEN) & 7,ADCSR); // Ad Wandler starten mit Vorteiler 128.
while(1)
        {
        outp ((1<<PINC1),ADMUX); // Pin 1 an Port C auswählen
        outp((1<<ADSC),ADCSR);
        while (bit_is_set (ADCSR, ADSC)){};
        x = inp(ADCL);
        x2 = inp(ADCH);
        x2 = x2*256;
        wert = x + x2;
        if (wert<150) outp(0x00, PORTD);
        else outp(0xff,PORTD);
        }
}


Kompiliert wird das ganze Fehlerfrei, aber der AD Wandler gibt immer 0 
zurück. (Oder sonst ein sehr kleiner Wert...)

von Notker (Gast)


Lesenswert?

Soweit ich das sehe, solltest du ADIF nach dem Setzen von ADSC abfragen, 
wenn du den ADC im single-conversion mode betreibst um zu sehen, wenn 
die wandlung fertig ist.
Oder du betreibst ihn im free-running mode, dann musst du ADFR im ADCSR 
setzen.

Notker

von Lukas H. (Gast)


Lesenswert?

Ok, also ich hab jetzt
while (bit_is_set (ADCSR, ADSC)){};
durch
while ((ADCSR, ADIF)== 0){};

Leider funktionierts immer noch nicht.
Übrigens ist mir ein kleines Missgeschick passiert, ich habe Beim 
überprüfen Vcc direkt mit einem Pin verbunden. Überlebt das der AD 
Wandler ?

Der Code sieht jetzt übrigens so aus:

#include <io.h>
int main( void )
{
long x; // Ich weiss wär nicht unbedingt nötig, aber lieber zu gross
long x2;
long wert;
outp(0xff,DDRD);
outp ((1<<ADEN) & 7,ADCSR); // Ad Wandler starten mit Vorteiler 128.
while(1)
        {
        outp ((1<<PINC1),ADMUX); // Pin 1 an Port C auswählen
        outp((1<<ADSC),ADCSR);
        while ((ADCSR, ADIF)== 0){};
        x = inp(ADCL);
        x2 = inp(ADCH);
        x2 = x2*256;
        wert = x + x2;
        if (wert<150) outp(0x00, PORTD);
        else outp(0xff,PORTD);
        }
}

von Notker (Gast)


Lesenswert?

Also ich habe das obige Programm nun mangels Zeit nicht testen können, 
sondern nur mal "optisch" geprüft. Das müsste so eigentlich 
funktionieren. Ich würde empfehlen, dass du den Code mal im AVR-Studio 
testest. Ich bin mir nun zwar nicht 100% sicher, aber ich glaube, man 
kann den analogen Eingang des ADC im AVR-Studio irgendwie simulieren, 
also irgendwie einen bestimmten Wert vorgeben und dann sehen, was der 
Code daraus macht.

> Übrigens ist mir ein kleines Missgeschick passiert, ich habe Beim überprüfen Vcc 
direkt mit einem Pin verbunden. Überlebt das der AD Wandler ?

Gute Frage, nächste Frage!

Ich glaube, darauf wird dir niemand eine sichere Antwort geben können. 
Im Zweifelsfall sollte man immer einen Ersatz zur Hand haben, den man im 
Austausch mal testen kann.

Notker

von Markus Adameck (Gast)


Lesenswert?

komischerweise funktioniert bei mir der ADWandler bei Prüfung auf ADIF 
auch nicht richtig. Ich erhalte viel zu hohe Werte. Wenn ich einfach 
eine genügend lange Warteschleife einfüge (wie lange steht im Datenblatt 
des AVR) gehts.

von Hermann Kraus (Gast)


Lesenswert?

>Ok, also ich hab jetzt
>while (bit_is_set (ADCSR, ADSC)){};
>durch
>while ((ADCSR, ADIF)== 0){};
Ich bin zwar was C angeht nicht unbedingt ein Profi, aber wird hier 
nicht einfach der Wert von ADCSR ingoriert und dann überprüft ob ADIF 
null ist?
Zum Nachvollziehen:
  1.) Ausdruck=(ADCSR, ADIF)
     a) Kommaoperator bedeutet den Teilausdruck vor dem Komma
        einfach nicht ins Ergebnis einbeziegen.
     b) D.h. ADIF bleibt übrig
     c) In iom8.h steht #define ADIF  4
     d) Das Ergebnis dieses Ausdrucks ist 4
  2.) Prüfen ob 1.) gleich Null ist. Da 4!=0 wird daraus ne
      Endlosschleife
Was meint ihr dazu?

Hermann

von Notker (Gast)


Lesenswert?

Stimmt, er hat beim zweiten Entwurf das bit_is_set vor der Klammer 
vergessen. Ist mir auch jetzt erst aufgefallen. Also das mit dem 
Komma-Operator ist eine interessante Theorie, war aber wohl so bestimmt 
nicht beabsichtigt ;-)

frohes Fest

Notker

von Lukas H. (Gast)


Lesenswert?

Hmm, also das wegen dem Komma, das hab ich einfach vom C Tutorial 
übernommen.
Dort steht :
while (bit_is_set (ADCSR, ADSC))

Beim 2. Versuch hab ich ja ADSC mit ADIF ersetzt, dazu steht im C Tut:

ADIF
ADC Interrupt Flag
Dieses Bit wird vom ADC gesetzt wenn eine Umwandlung erfolgt und das 
ADC Data Register aktualisiert ist.

dann muss ich ja nicht warte während es gesetzt ist, sondern solange es 
nicht gesetzt ist !

Das mit der Warteschleife hab ich auch probiert, funktioniert leider 
auch nicht ...

von Hermann Kraus (Gast)


Lesenswert?

>dann muss ich ja nicht warte während es gesetzt ist, sondern
>solange es nicht gesetzt ist !
Dann nimm halt "loop_until_bit_is_set".

Hermann

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.