Hallo Leute! Ich versuche den ADC meines Mega32 zum laufen zu bringen. Dazu habe ich folgenden Code geschrieben: while (1) { // links ausrichten & Aktivieren sbi(ADMUX,ADLAR); sbi(ADCSRA,ADEN); unsigned char res; cbi(ADMUX,MUX0); sbi(ADMUX,MUX1); sbi(ADMUX,MUX2); sbi(ADMUX,MUX3); sbi(ADMUX,MUX4); // Los geht's sbi(ADCSRA,ADSC); loop_until_bit_is_clear(ADCSRA,ADSC); res = ADCH; lcd_gotoxy(0,3); sprintf(str,"%u",res); lcd_puts(str); } Bei dem ausgewählten Channel (Im Datenblatt steht 1,22V) müßte ja alles andere außer 255 raus kommen. Auch wenn ich einen ADC-Pin auswähle, das Ergebniss bleibt immer 255. Ist mein ADC kaputt, oder liegt's am Code ? AREF und AVCC sind mit VCC (5V) und AGND mit GND verbunden. MfG Sascha
Hmm: cbi(ADMUX,MUX0); sbi(ADMUX,MUX1); sbi(ADMUX,MUX2); sbi(ADMUX,MUX3); sbi(ADMUX,MUX4); Ein typisches Beispiel, warum cbi/sbi wirklich `deprecated' sein sollten... ADMUX = _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); wäre deutlich effektiver. Aber das nur nebenbei. Dein ADSRA hat alle Teilerbits auf 0, d. h. einen Vorteiler von 2. Sofern Dein Systemtakt nicht gerade im Bereich 100...400 kHz liegt, bist Du damit außerhalb der Specs. Normalerweise sollte der ADC allerdings auch mit höherem Takt noch laufen, nur nicht mehr so genau. Wenn Dein Systemtakt allerdings bei 14...16 MHz liegt, kann es gut sein, daß der ADC mit der Hälfte davon auch schon ganz außer Funktion ist.
ah! die sbi's sind nach und nach dazu gekommen, beim debuggen g naja ich habe ihn auf 16MHz laufen g gut, habe den prescaler auf 128 gestellt, jetzt geht's... Hab' vielen Dank! ...soviel zum Thema: Wenn ich das Datenblatt mal schnell überfliege, dann bekomme ich schon raus wie das geht g
Hallo zusammen ich habe das selbe Problem. Der prescale wurde auch verändert, doch es funktioniert immer noch nicht. Mein Code ist im File A_D angehängt. Die Ausgabe an die LED ist immer 0xFF. Gruss Martial
Hallo, bin zwar auch leider erst noch ganz am Anfang, aber folgendes glaube ich als Fehler zu erkennen (ohne mir den Rest angeschaut zu haben:) void AD_in (unsigned char mux) { ADMUX = (0<<REFS1)|(0<<REFS0)|(0<<ADLAR)|(mux<<MUX0); ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0); while ((ADCSRA & 0x10)); return ADCW; } Eine void-Funktion (ohne Rückgabe) liefert "return ADCW"? => Dann keine void-Funktion. Gruß Lutz
Hallo, mit dem Nullen-schieben ist übrigens auch quatsch bzw. bringt wahrscheinlich nicht das, was Du vorhast. Die Idee hatte ich ganz am Anfang auch, ist ja auch so schön einfach: Bitshift mit 1 = Bit setzen, Bitshift mit 0 = Bit löschen. Schade, geht aber nicht. Wurde mir zigmal erklärt, hab´s trotzdem nicht verstanden warum´s nicht geht. Einer hat´s dann geschafft mir zu erklären: Mach doch einfach mal die Shifts und Verknüpfungen zu Fuß (mit dem Prinzip fahre ich jetzt allgemein sehr gut): x = (1<<2) | (0<<3) mit 4 Bit entspricht x = 0100 ODER ("1" = 0001 zwei Stellen Bitshift nach links) 0000 ("0" = 0000 drei Stellen Bitshift nach links) -------------- = 0100 Also keine Änderung; eine ODER-Verknüpfung nur mit Nullen kann man sich sparen => einfach weglassen. Da es eine Zuweisung ist (x = ..) wird das Ergebnis der ODER-Verknüpfung x zugewiesen; der Wert von x vor der Zuweisung ist dabei egal. Wenn Du aber beabsichtigt hattest, ein ungesetztes Bit zu setzen (also nur ein spezielles Bit im Register, alle anderen Bits sollen bleiben wie sie waren), wäre x = x | (1<<3) richtig. Kürzer wäre x |= (1<<3). Mit dem Wert von Oben x = 0100 ODER 1000 ("1" = 0001 drei Stellen Bitshift nach links) ---------------- = 1100 die richtige Lösung. Um nun ein einzelnes Bit zu setzen, muß eine UND-Verknüpfung her. Um das Dritte Bit von rechts zu löschen, wäre x = x & ~(1<<3) richtig. Kürzer wäre x &= ~(1<<3). Die Tilde heißt negieren. Ergibt mit dem letzten Ergebnis x = 1100 UND 1011 (Negiertes 0100) ---------------- = 1000. So hab´ zumindest ich das verstanden. Es gibt natürlich ein Makro dafür im GCC, weil diese Shiften eben oft gebraucht wird. Nennt sich _BV(). Näheres in den FAQ der avr-libc. Zumindest ich brauche aber dieses "Step by Step für Dumme" weiter oben, um die Dinge zu verstehen. Dann weiß ich wenigstens, was das Makro macht. Gruß Lutz P.S.: Da dieses Problem hier nicht viel mit dem Ursprungs-thread zu tun hat, lieber einen neuen aufmachen bei ähnlichen Fragen. Ist dann übersichtlicher.
Oh Sch.., 2 mal vergrüßt. Hier ist richtiger: Hallo, mit dem Nullen-schieben ist übrigens auch quatsch bzw. bringt wahrscheinlich nicht das, was Du vorhast. Die Idee hatte ich ganz am Anfang auch, ist ja auch so schön einfach: Bitshift mit 1 = Bit setzen, Bitshift mit 0 = Bit löschen. Schade, geht aber nicht. Wurde mir zigmal erklärt, hab´s trotzdem nicht verstanden warum´s nicht geht. Einer hat´s dann geschafft mir zu erklären: Mach doch einfach mal die Shifts und Verknüpfungen zu Fuß (mit dem Prinzip fahre ich jetzt allgemein sehr gut): x = (1<<2) | (0<<3) mit 4 Bit entspricht x = 0100 ODER ("1" = 0001 zwei Stellen Bitshift nach links) 0000 ("0" = 0000 drei Stellen Bitshift nach links) -------------- = 0100 Also keine Änderung; eine ODER-Verknüpfung nur mit Nullen kann man sich sparen => einfach weglassen. Da es eine Zuweisung ist (x = ..) wird das Ergebnis der ODER-Verknüpfung x zugewiesen; der Wert von x vor der Zuweisung ist dabei egal. Wenn Du aber beabsichtigt hattest, ein ungesetztes Bit zu setzen (also nur ein spezielles Bit im Register, alle anderen Bits sollen bleiben wie sie waren), wäre x = x | (1<<3) richtig. Kürzer wäre x |= (1<<3). Mit dem Wert von Oben x = 0100 ODER 1000 ("1" = 0001 drei Stellen Bitshift nach links) ---------------- = 1100 die richtige Lösung. Um nun ein einzelnes Bit zu LÖSCHEN, muß eine UND-Verknüpfung her. Um das Dritte Bit von rechts zu löschen, wäre x = x & ~(1<<2) richtig. Kürzer wäre x &= ~(1<<2). Die Tilde heißt negieren. Ergibt mit dem letzten Ergebnis x = 1100 UND 1011 (Negiertes 0100 aus: 1<<2 = 0100) ---------------- = 1000. So hab´ zumindest ich das verstanden. Es gibt natürlich ein Makro dafür im GCC, weil diese Shiften eben oft gebraucht wird. Nennt sich _BV(). Näheres in den FAQ der avr-libc. Zumindest ich brauche aber dieses "Step by Step für Dumme" weiter oben, um die Dinge zu verstehen. Dann weiß ich wenigstens, was das Makro macht. Gruß Lutz P.S.: Da dieses Problem hier nicht viel mit dem Ursprungs-thread zu tun hat, lieber einen neuen aufmachen bei ähnlichen Fragen. Ist dann übersichtlicher.
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.