Mehrere AD-Werte auslesen

Gast #2293418
Lesenswert?

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();
  }
}
#2294433
Lesenswert?

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.
Gast #2294642
Lesenswert?

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
#2294654
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren