Forum: Compiler & IDEs Problem mit if-Funktion


von Marcel (Gast)


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
}

von pittbull_nt@yahoo.com (Gast)


Lesenswert?

was hat den ADC_mV für einen typ? etwa 'char'?
dann geht's natürlich nicht

von Marcel (Gast)


Lesenswert?

nee, daran liegts nicht:
uint32_t ADC_mV;

von pittbull_nt@yahoo.com (Gast)


Lesenswert?

na, am besten du steppst mal im debugger durch den code und guckst dir
die befehle und register genau an

von Marcel (Gast)


Lesenswert?

Das hilft mir auch nicht wirklich weiter.

von pittbull_nt@yahoo.com (Gast)


Lesenswert?

>> Das hilft mir auch nicht wirklich weiter.
das glaube ich nicht. wenn du durch den assembler-code durchsteppst
siehst du bestimmt was das schiefläuft.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Welcher Wert steht denn in ADC_mv?

von Marcel (Gast)


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.

von pittbull_nt@yahoo.com (Gast)


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....

von Marcel (Gast)


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
        }

von pittbull_nt@yahoo.com (Gast)


Lesenswert?

dann hast du ein ganz anderes problem:
- stack overflow
- wild pointer
- miesen compiler/linker
- race condition
- ...
such dir was aus :-)

von Marcel (Gast)


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 ??

von pittbull_nt@yahoo.com (Gast)


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...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Marcel (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Meiner Erfahrung nach lohnt es übrigens, bei ADC den
Interrupt zu benutzen.  Wenn der triggert, liegt auch
ein Ergebnis vor, und man muss die Zwischenzeit nicht
verwarten.

von Rolf Magnus (Gast)


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.

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.