Forum: Mikrocontroller und Digitale Elektronik AD Wandler liefert komische Werte


von Christian (Gast)


Lesenswert?

Hallo Gleichgesinnte,

ist glaub ich nur ein kleines Problem, aber ich komme trotzdem nicht 
weiter....
Ich les' über den internen AD Wandler von dem Mega163 eine Spannung ein 
und versuch' diese über den sprintf Befehl, den's auf ideser Seite unter 
avrgcc FAQ gibt auf meinem Grafik LCD auszugeben.

Ich denke der Fehler besteht in dem Teil des Programms wo die AD 
Register in ein int zusammengeführt werden sollen - vielleicht kann mir 
jemand sagen warum das nicht hinhaut:

lo_val = inp(ADCL);   /* read low byte first */
hi_val = inp(ADCH);
adc = hi_val;
adc = adc<<8;
adc = adc + lo_val;

Was ist daran falsch????

wenn ich jetzt das int adc in ein char adc_8bit reinlade - wird dann 
automatisch das höherwertige byte in das char adc_8bit reingeladen????

Vielen Dank für eure Unterstützung!!!!

mfg

Christian

von Christian (Gast)


Lesenswert?

Hey, das lustigste hab' ich euch ja gar nicht gesagt:

wenn ich versuche die int adc Variable in ein unsigned char adc_8bit 
reinzuladen und das am LCD anschaue kommen da teilweise zahlen raus über 
600 - wie kann eine eine 8bit Variable größer als 255 sein?????

Vielen Dank

Christian

von hubi (Gast)


Lesenswert?

Ich möchte ebenfalls Spannungen vom ADC einlesen doch ich kriege nur 3 
oder 0 bei ADCH und bei ADCL nur 0 oder 255. Vielleicht kannst Du ja mir 
helfen?????

Gruss
Rolf

von Christian (Gast)


Lesenswert?

Hallo Rolf,

hast du AREF, AGND und AVCC wie im Datenblatt beschrieben beschalten???
Nimmst du C oder Assembler???
Post halt mal deinen Code - vielleicht hilfts was.

Bist du ein kleiner Heli fan oder heißt du nur so Hubi???

mfg

Christian

von Christian (Gast)


Lesenswert?

Hallo - ich bin's schon wieder,

ich hab' zu versuchszwecken das C-Programm so umgeschrieben, dass jetzt 
eine laufender Timerwert am LCD angezeigt wird (haraleit...)
Das mit dem Timer läuft ja ganz gut, aber das mit dem Display wohl 
weniger. Zuerst wird ganz normal gezählt bis 255 und dann wird plötzlich 
unlogisch bis 900 oder so gezählt und dann zählt er wieder normal ab 100 
weiter. Liegt das vielleicht am sprintf???

Die Variblae wird, sobald sie 255 ist wieder auf null gesetzt - warum 
funktioniert das dann nicht????

Vielen Dank

Christian

PS: die LED's an Portb, die das ganze binär mitzählen laufen in Ordnung 
- da scheints zu stimmen.

von hubi (Gast)


Lesenswert?

Danke Christian
Versuche in C zu Programmieren. Bin ein echter Anfänger betreffend C und 
MC. Deshalb habe ich auch die AREF "vergessen" anzuschliessen. Dachte 
interne Referenzspannung heisst es brauche keine externen Anschlüsse 
mehr.

hubi ist ein Spitznahme, kommt von Huber

mfg
Rolf

von Dirk Kramer (Gast)


Lesenswert?

Hallo Christian,

kann es sein, dass du beim Aufruf von sprintf einen Fehler machst?

Poste doch einfach mal einen Auszug aus dem Quelltext, dann kann dir 
bestimmt besser geholfen werden.

Dirk

von Christian (Gast)


Lesenswert?

Hallo Dirk,
vielen Dank für deine Antwort - hier ist der code (ohne #include und 
variablendeklaration)


SIGNAL (SIG_OVERFLOW0)
{
//outp(~led, PORTB); /* write value of led on PORTB */
count++;
if (count==255)
count = 2;
outp(0xFE,TCNT0); /* reload counter with initial value */
}

SIGNAL (SIG_OVERFLOW2)
{
outp(~led, PORTB); /* write value of led on PORTB */

led++;

if (led==255)

led = 0;

outp(0,TCNT2); /* reload timer with initial value */
}

void print_data(void)
{
set_cursor(0,0);  //gibt die x und y Position auf dem LCD an
sprintf(lcd_buffer, "Timerstand: %u", led);
lcd_printstring(lcd_buffer);

set_cursor(0,1);  //gibt die x und y Position auf dem LCD an
sprintf(lcd_buffer, "Counterstand: %u", count);
lcd_printstring(lcd_buffer);

}

int main( void )
{
outp(0xFE, DDRB); /* use all pins on PORTB for output */
outp((1<<TOIE2|1<<TOIE0), TIMSK); /* enables the T/C2 overflow interrupt 
in
the T/C interrupt mask register for */
outp(0, TCNT2); /* start value of T/C2 */
outp(4, TCCR2); /* prescale ck/64 das sollte bei 8Mhz alle 2,048ms einen 
interrupt geben*/
outp(0xFE, TCNT0); /* start value of counter */
outp(6, TCCR0); /* init the T/C as a counter falling edge*/
count = 0;
led = 0;
t6963c_init();
sei(); /* set global interrupt enable */
for (;;)
{
  print_data();
  Delay_10ms(10);
}
}

von Christian (Gast)


Lesenswert?

Oh - tut mir leid, jetzt hab' ich ein wenig viel müll mitgepostet - das 
Display soll jetzt den counter und den Timerwert anzeigen (machts ja 
auch bis 255) - eins von beiden hätt' wohl gereicht...

mfg

Christian

von Schmittchen (Gast)


Lesenswert?

Und wenn du die Anzeige nur langsam genug machst, dann siehst du, daß er 
von 0 bis 255 wie gewünscht zählt, danach gehts mit 055 weiter, dann 
155, dann... bis 995, erst danach stimmen die Ausgaben wieder. Gib mal 2 
Leerzeichen nach dem %u in deinem sprintf-Parameter-String aus, dadurch 
werden die übrig gebliebenen Ziffern auf dem Display der letzten Ausgabe 
gelöscht.

Ich mache den "Fehler" auch regelmäßig - Hoffnung auf Besserung habe ich 
bei mir schon aufgegeben.

@Hubi: Vergiss auch nicht den obligatorischen 100nF Keramikkondensator 
zwischen AVCC und AGND...

Schmittchen.

von Christian (Gast)


Lesenswert?

Hallo Nachtmensch,

vielen lieben Dank für deine Antwort!! - jetzt funktioniert das mit dem 
Counter einwandfrei!!!!!! Ich hab' noch ein anderes Programm bei dem ich 
mich über die LCD Anzeige geärgert habe. Es soll einen Kompasswert 
(elektronischer Kompass) einlesen und am Display ausgeben. Das hat auch 
nur Müll angezeigt - vielleicht geht's jetzt - wäre wirklich toll (hab' 
jetzt keine Lust mehr das auszuprobieren.....)
Das mit dem ADC haut leider immer noch nicht hin - man sieht jetzt 
allerdings, dass fast immer wieder die selben Zahlen rauskommen.....

Vielen Dank auf jeden Fall - du hast mich wirklich um ein großes Stück 
weitergebracht!!!!!!

Viele Grüße

Christian

PS: so wichtig wird der 100nF zwischen AVCC und GND wohl nicht sein dass 
es deswegen nicht funktioniert, oder??? - hab' nämlich keinen 
Kondensator reingemacht.....

von Christian (Gast)


Lesenswert?

Hey, jetzt funktioniert jetzt auch der AD Wandler.
Ich weiß zwar nicht so genau was ich gemacht habe, dass es jetzt läuft, 
aber es funktioniert nun einwandfrei!!!

Vielen Dank nochmal an alle (auch an die die das gelesen haben und 
mitgegrübelt haben ;-)

mfg

Christian

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.