Hy, habe das Programm in AVR Studio geschrieben und ist für den Mega8 bestimmt. Auf der Platine habe ich alles nachgemessen und das stimmt soweit. Das Programm soll Bits setzen wenn der ADC1 und der ADC2 unterschiedliche Werte haben. Leider werden die Bits nicht gesetzt. Kann mir vielleicht jemand weiterhelfe? Wäre super. #include <avr/io.h> void reset(); int main (void) { reset(); int adclow; int vertikallinks; int vertikalrechts; while(1) { ADMUX= 1; ADCSRA = (1<<ADSC); //Start der Wandlung while ( ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten { } adclow=ADCL; vertikallinks=ADCH; ADMUX=2; ADCSRA = (1<<ADSC); //Start der Wandlung while ( ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten { } adclow=ADCL; vertikalrechts=ADCH; int ergebnis=vertikallinks-vertikalrechts; if(-1>ergebnis||1<ergebnis) { if(-1>ergebnis) { PORTB = (1<<PB2) | (0<<PB3); } else { PORTB = (0<<PB2) | (1<<PB3); } } else { PORTB=(0<<PB2)|(0<<PB3); } } main(); return 0; } void reset(){ DDRD= 0xff; DDRB= 0x00; ADMUX= (0<<REFS1)|(1<<REFS0)|(1<<ADLAR); ADCSRA= (1<<ADEN)|(1<<ADPS2)|(ADPS1)|(ADPS0); }
Du vergleichst ja nur die oberen 8 Bit (ADCH) und verwirfst die unteren 8 Bit (ADCL). Dementsprechend hast du nur eine Chance, wenn wenn sich die digitalisierten Werte genügend unterscheiden. Wie wäre es mit einer Nutzung der vollen Digitalisierungswerte? adclow = ADCL; vertikallinks = ADCH; vertikallinks = (vertikallinks << 8) | adclow; ... adclow = ADCL; vertikalrechts = ADCH; vertikalrechts = (vertikalrechts << 8) | adclow; ...
Was mir auf die Schnelle auffällt: Du konfigurierst hier ADCSRA= (1<<ADEN)|(1<<ADPS2)|(ADPS1)|(ADPS0); den ADC. Leider zerstörst du dir hier ADCSRA = (1<<ADSC); //Start der Wandlung die Konfiguration. Wenn du dem Register ADCSRA etwas zuweist, wird das komplette Register neu beschrieben, nicht nur das ADSC Bit ADCSRA |= ( 1 << ADSC ); Mit ADMUX machst du genau den gleichen Fehler. Eine extrem gute Idee ist es auch, sich einfach nur den eingelesenen Wert einmal ausgeben zu lassen. Zuerst mit dem einen Kanal und erst dann mit dem anderen. In der Programmkette Eingabe Verarbeitung Ausgabe kann man in jeder Stufe Fehler machen. Es hat keinen Sinn daran zu glauben, dass man selbst jede Stufe hinkriegt. Wenn das Gesamtsystem nicht funktioniert, dann muss jede Stufe überprüft werden. Sinnvollerweise fängt man mal damit an, ob die Eingabe überhaupt klappt. In deinem Fall heist das: Welche Werte kommen den eigentlich vom ADC?
Ich habe halt dadurch nur ein 8-Bit Wandler. Beim Vergleichen ist das doch eigentlich egal, oder?
@ Karl heinz Buchegger Ei klaro, da hab ich ja gar nicht dran gedacht. Hab es geändert und es funktioniert. Falls es interresiert, hier noch mal das Programm: #include <avr/io.h> void reset(); int main (void) { reset(); int adclow; int vertikallinks; int vertikalrechts; while(1) { ADMUX= (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(1<<MUX0)|(0<<MUX1); ADCSRA= (1<<ADEN)|(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADSC); while ( ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten { } adclow=ADCL; vertikallinks=ADCH; ADMUX= (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX0)|(1<<MUX1); ADCSRA= (1<<ADEN)|(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADSC); while ( ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten { } adclow=ADCL; vertikalrechts=ADCH; int ergebnis=vertikallinks-vertikalrechts; if(-1>ergebnis||1<ergebnis) { if(-1>ergebnis) { PORTB = (1<<PB2) | (0<<PB3); } else { PORTB = (0<<PB2) | (1<<PB3); } } else { PORTB=(0<<PB2)|(0<<PB3); } } main(); return 0; } void reset(){ DDRD= 0xff; DDRB= 0x00; }
Aber dann nimm zum Vergleich die unteren 8 Bit. Im Moment wird ein Unterschied nur erkannt (Einwand von Karl heinz beachten!), wenn sich die Werte um mindestens 256 (8 Bit) unterscheiden. Es ist die Frage, ob du so grosse Änderungen anlegst. Eine weitere Sache: Du holst dauernd frische Werte und du reagierst nur auf Änderungen von eben nach jetzt. Wenn sich nix ändert, werden die Bits von dir zurückgesetzt. Denk daran so ein µC ist sau schnell. Wenn die Bits z.B. eine LED steuern - du wirst das kurze Aufflackern nicht sehen!
> wenn sich die Werte um mindestens 256 (8 Bit) unterscheiden.
Er hat ADLAR gesetzt.
@Stefan Danke für die Tips. War mein erstes C-Programm und mein erster AD-Wandler Einsatz (soll kein Ausrede sein;) ). Aber der obere Absatz verstehe ich nicht ganz. Es sollen einfach Spannungen von ca. 0V bis ca. 3V gegeneinander verglichen werden. Und das mit einer Hysterese.
Ich denke Stefan hat das ADLAR Bit übersehen. Wenn es dir nichts ausmacht die untersten 2 Bits nicht zu berücksichtigen, dann passt das schon.
> Er hat ADLAR gesetzt.
Das habe ich nicht gesehen. Dann werden ja nur die zwei der
niedrigwertigsten Bits weggeworfen.
x/X sind die 10 relevanten Bits für 0V..3V
ADCH ADCL
xxxxxxxx XX000000
Mit voller 10-Bit Auflösung hätte man 3V / 2^10 = 2,93 mV
Digitalisierauflösung. Ohne die Bits X hat man dann eine vierfach (2^2)
gröbere Auflösung (11,72 mV).
Ich dachte es werden 8 Bits in ADCL weggeworfen. Das wäre eine
Verminderung der Digitalisierauflösung um den Faktor 256 (2^8), d.h. ein
Wert zum nächsten müsste sich um die 256er Stufe unterscheiden, um als
anderer Wert erkannt zu werden.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.