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