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...)
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
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);
}
}
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
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.
>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
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
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 ...