Hi Leute,
messe bei einem Fensterhebermotor den Aufnahmestrom, bzw. messe eine
Spannung an einem Shunt-Widerstand.
Da ich einen für die Fahrerseite und einen für die Beifahrerseite
benötige, muss ich zwei AD-Werte auslesen. Diese Spannungen liegen an
PINC0 und PINC1.
Habe das Problem, dass egal an welchem AD-Eingang die Spannung über den
eingestellten Wert von Binär 128 übersteigt, beide Motoren abgeschaltet
werden. Ich denke es liegt daran, dass ich für beide Spannungen das ADC
Register abrufe.
Die Kanalwahl funktioniert ja einwandfrei sobald ich jeweils den anderen
auskommentiere.
Irgendwie überschreibt ein AD-Eingang jeweils eine "wert"-Variable, weil
er ja schließlich auch das ADC-Register überschreibt.
Ich brauch schnelle Hilfe und wäre sehr dankbar dafür.
Hab das Hauptprogramm mal angehängt:
int main ()
{
DDRC=0b00000000;
DDRD=0b11001100;
ADCSRA=0b11000001;
while (bit_is_set(ADCSR,6)); // Warten bis Initialisierungsmessung
erfolgt ist
while(1)
{
ADMUX&=~(1<<MUX0);
ADCSRA|=(1<<ADSC);
while (bit_is_set(ADCSRA,6));
wert1=ADC;
ADMUX|=(1<<MUX0);
ADCSRA|=(1<<ADSC);
while (bit_is_set(ADCSRA,6));
wert2=ADC;
if (wert1<128) {endschalter_fahrerseite=1;} else
{endschalter_fahrerseite=0;}
if (wert2<128) {endschalter_beifahrerseite=1;} else
{endschalter_beifahrerseite=0;}
fenster_fahrerseite();
fenster_beifahrerseite();
}
}
Nachdem hier noch keiner geantwortet hat, probier ich es mal.
Auf Anhieb habe ich nichts gesehen, was mir verdächtig vorgekommen wäre.
Möglicherweise steckt der Fehler ganz woanders. Es wäre vielleicht
nützlich, wenn Du uns den gesamten Quellcode zeigst. Außerdem ist es
immer sinnvoll, wenn Du auch den Controllertyp angibst. Und nachdem es
offensichtlich um einen Atmel-Controller geht, sind auch die
Fuse-Einstellungen wichtig.
lukas schrieb:> ...eingestellten Wert von Binär 128...
Das sind aber dezimal 128, nicht binär.
lukas schrieb:> Ich denke es liegt daran, dass ich für beide Spannungen das ADC> Register abrufe.
Daran kann es nicht liegen, weil dazwischen ja eine neue Wandlung
vorgenommen wird.
hi,
ja sorry war dezimal 128 gemeint xD
und es handelt sich um ein atmega8.
der rest des programmes ist nicht wichtig. und fuse-einstellungen
sind alle richtig eingestellt. es geht ja nur rein um die AD-Wandlung
zweier eingänge. ich muss die zwei werte irgendwie zwischenspeichern.
es funktioniert ja auch soweit mit der kanalwahl und mit der wandlung
wenn ich es nur mit einem AD-Eingang zu tun habe. aber sobald ich die
werte zweier eingänge zwischenspeichern will, klappt es nicht, weil ja
das ergebnis der wandlung immer in das ADC-Register geschrieben wird.
man switcht ja nur zwischen den eingängen hin und her.
kann mir denn da keiner so wirklich helfen?
geht quasi nur um das hier:
while(1)
{
ADMUX&=~(1<<MUX0);
ADCSRA|=(1<<ADSC);
while (bit_is_set(ADCSRA,6));
wert1=ADC;
ADMUX|=(1<<MUX0);
ADCSRA|=(1<<ADSC);
while (bit_is_set(ADCSRA,6));
wert2=ADC;
}
muss doch eine lösung geben, wie ich die werte zweier eingänge
längerfristig speichern kann, ohne das der wert gleich vom anderen
überschrieben wird.
mfg
lukas schrieb:> muss doch eine lösung geben, wie ich die werte zweier eingänge> längerfristig speichern kann, ohne das der wert gleich vom anderen> überschrieben wird.
Das ist nicht das Problem.
So wie es aussieht(*), kommt der ADC mit der schnellen Umschaltung nicht
zurecht. Das kann zb sein, weil sich die interne Sample&Hold Stufe nicht
schnell genug auf den Spannungspegel des anderen Kanals umstellen kann.
Schneller Ad-Hoc Ansatz:
Wandle jeden Kanal 2 mal und nimm nur das 2-te Ergebnis. Dazu wäre es
natürlich vernünftig, aus der ADC Abfrage eine Funktion zu machen, damit
man nicht immer wieder den eigentlich identischen Code hat.
Das hier
ADCSRA=0b11000001;
schlüssle ich jetzt sicher nicht nach den Bits auf, um zu sehen, ob
nicht deine Wandelrate zu hoch eingestellt ist.
Schau dir im AVR-GCC-Tutorial an, wie man sowas auch lesbarer
schreiben kann. Dort findest du auch ADC-Routinen, die die ADC-Benutzung
sauber in Funktionen aufgliedern, so dass das ganze einfach benutzbar
wird.
(*) natürlich nur unter der Voraussetzung, dass der von dir nicht
gezeigte Rest des Programmes soweit in Ordnung ist. In der
Verarbeitungskette Eingabe-Verarbeitung-Ausgabe gibt es nun mal 3
Stellen, an denen sich Fehler verstecken können, auch wenn sich alle
Welt meistens nur auf den 2ten Schritt stürzt.
Ich verwende bei meinen ADC-Routinen immer das ADIF-Bit um festzustellen
wann die Wandlung fertig ist, das klappt irgendwie besser als mit dem
ADSC-Bit. Das ADIF-Bit muß nach jeder Wandlung wieder gelöscht werden.