Problem mit if-Funktion

Gast #364096
Lesenswert?

avr-gcc (GCC) 3.4.3

Wenn die Spannung am ADC 500mV +-50mV beträgt, soll das ausgeführt
werden, was in der if-Anweisung steht.
Aber aus irgendeinem Grund klappt, die &&-Abfrage nicht.
Der Wert von ADC_mV ist auch korrekt, selbst wenn ich ihn manuell
definiere (z.B. ADC_mV=510;) funktioniert es nicht.
Ich weiß echt nicht mehr weiter.

if ((ADC_mV>450) && (ADC_mV<550))
{
//code
}
Gast #364103
Lesenswert?

Wenn man aber nur ein paar Grundkenntnisse in assembler hat.
Dann ist noch der Code für ein LC-Display, und noch die ganzen Register
des ADC im Assembler drin.
Und dann hab ich keinen Durchblick mehr.
Gast #364104
Lesenswert?

>> Wenn man aber nur ein paar Grundkenntnisse in assembler hat.
>> Dann ist noch der Code für ein LC-Display, und noch die ganzen
>> Register
>> des ADC im Assembler drin.
>> Und dann hab ich keinen Durchblick mehr.

dann änder mal den c-code, so dass ADC_mv vor der if-anweisung
ausgegeben wird....
Gast #364105
Lesenswert?

Also irgendwas ist da verflucht.
Wenn ich mir den Wert vom ADC anzeigen lasse, dann steht 0 da,
aber komischerweise funktioniert diesmal die IF-Abfrage.

ADMUX = ADC5;
ADCSRA |= (1<<ADSC); //ADC trigger
x = ADC;
itoa(ADC,buffer,10);
lcd_puts(buffer);
lcd_puts(" ADC RAW");

if ((ADC>170) && (ADC<180))
  {
  //code
        }
Gast #364107
Lesenswert?

Kann es evt. mit der Version von WinAVR zusammenhängen ?
avr-gcc (GCC) 3.4.3

Hatte schon mal ein ähnliches Problem, wo ich nicht wusste woran es
lag.

Hab zum Testen einfach den Projektordner kopiert und umbenannt, als ich
den Code dann auf den Controller geladen habe, funktionierten die
benutzerdefinierten Zeichen des LCD nicht mehr richtig, obwohl ich im
LCD-Code nichts geändert habe. Sogar die Sourcedateien fürs LCD waren
absolut die selben.

Oder könnte es evt. auch an PonyProg2000 liegen ??
Gast #364108
Lesenswert?

sorry, damit kenne ich mich nicht aus. ich benutze meistens kommerzielle
tools (codewarrior, iar etc.) für embedded kram. aber oft sitzt der
fehler vor dem bildschirm ;-). meistens hilft scharfes ansehen des
codes und es 'map'-files um sowas zu finden. auch tools zur
statischen codeanalyse (lint, splint) sind nicht verkehrt. in den
seltensten fällen liegt's am compiler...
Moderator Persönliche Seite #364109
Lesenswert?

> ADMUX = ADC5;
> ADCSRA |= (1<<ADSC); //ADC trigger
> x = ADC;

Mir dünkt, du solltest dich zuerst einmal mit den Grundlagen des
AVR vertraut machen.  Du startest eine AD-Wandlung, aber wo bitte
wartest du auf das Ergebnis?

> Wenn ich mir den Wert vom ADC anzeigen lasse, dann steht 0 da,
> aber komischerweise funktioniert diesmal die IF-Abfrage.

Klar.  Die Ausgabe auf das LCD hat so viel Zeit gebraucht, dass
mittlerweile der AD-Wandler mit der Wandlung fertig war.  Da du weder
in der if-Anweisung deine zuvor zugewiesene Variable x benutzt hast,
sondern beide Male den ADC-Wert direkt aus dem Register liest, war er
dann beim if endlich da.
Gast #364110
Lesenswert?

Danke für den Hinweis Jörg.
Hab vorher den ADC immer im free-running Mode laufen lassen, aber da
ich jetzt mehrere Kanäle messe, verwende ich die single conversion.
Hat auch bis jetzt immer geklappt, da ich vor dem auslesen des
ADC-Registers immer noch was anderes getan habe.

so gehts jetzt:
ADMUX = ADC5;
ADCSRA |= (1<<ADSC); //ADC trigger
while ( ADCSRA & (1<<ADSC) ); //wait for result
x = ADC;
if ((x>170) && (x<180))
{
}

manchmal ist die Lösung einfacher als man denkt, aber was nützt einem
das, wenn man selbst nicht drauf kommt.

danke leute
Gast #364112
Lesenswert?

Oder, wenn man eh während der Zeit nix zu tun hat, kann man in den
Noise-Reduction-Mode schalten und so genauere Ergebnisse erzielen und
nebenbei noch etwas Strom sparen. Der Interrupt weckt den
Mikrocontroller dann automatisch wieder auf.

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