www.mikrocontroller.net

Forum: Compiler & IDEs ADC geht nicht ?


Autor: Sascha Biedermann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Sascha Biedermann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Martial (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lutz Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lutz Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lutz Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.