Forum: Mikrocontroller und Digitale Elektronik ADC & Typenwandlung


von Sascha (Gast)


Lesenswert?

So,

nachdem mein Programm soweit läuft, suche ich unterstützung, um meine
AD-Werte dezimal auf dem LCD-Display anzuzeigen. Habe schon mal gesucht
und diese Funktion "itoa" gefunden. Kann mir einer erklären, wie ich
diese anwende?

Mfg sascha

von Fritz Ganter (Gast)


Lesenswert?

so wie es in der Doku steht:
itoa(x,buffer,10);

x ist deine Integervariable
buffer ist ein char array, z.b:
char buffer[10];

10 ist für Dezimalsystem

du kannst auch sprintf nehmen:

sprintf(buffer,"%d Grad",x);

oder falls x eine Fliesskommavariable ist:
sprintf(buffer,"%.1f Grad",x);
zeigt dann mit einer Dezimalstelle an.

von Sascha (Gast)


Lesenswert?

@Fritz

Danke, hat mir geholfen. Da ich mit den AVR`s und C programmierung
gerade erst anfange, werd ich leider ab und zu hier mit fragen nerven
:-)

Mfg sascha

von Fritz Ganter (Gast)


Lesenswert?

Beachte aber, dass sprintf ca. 1300 Byte braucht (avr-libc).

von Sascha (Gast)


Lesenswert?

Hallo,

habe es mit itoa hingekriegt. Das LCD zeigt mir jetzt die ADC Werte
0-1023 an. Nun möchte ich aber die Spannung direkt anzeigen. Habe dazu
wie folgt gerechnet:

                read_adc(0);
    x=ADCW;
    x=((2510/1023)*x);
    itoa(x,buffer,10);
    lcd_gotoxy(0,1);
    lcd_puts(buffer);

Nun habe ich aber nur 2'er Schritte bis zum Wert 2046. Danach rührt
sich nichts mehr. Was habe ich da für einen Denkfehler?

Mfg Sascha

von Fritz Ganter (Gast)


Lesenswert?

du rechnest falsch.

du musst x=((2510*x)/1023); machen, weil 2510/1023 ergibt 2, und damit
wird dann x multipliziert.

von Sascha (Gast)


Lesenswert?

Hi,

dann zeigt er mir aber nur noch zwei Stellen im Display an.

Mfg Sascha

von Fritz Ganter (Gast)


Lesenswert?

Versteh ich nicht, warum es nur noch 2 Stellen sind.

Zu deinem ursprünglichen Code: das mit 2er Schritten passt schon, weil
der Wandler nur 10bit hat=1024 Werte. Mehr kann er nicht drauss machen,
wenn du mit 10 multiplizierst hast halt 10er Schritte.

von Olaf (Gast)


Lesenswert?

... wo ist denn bitte der Unterschied zwischen
x=((2510/1023)*x); und
x=((2510*x)/1023);?
Macht beim zweiten Ausdruck vielleicht das 2510*x Schwierigkeiten
(Bereichsüberschreitung?)? Fritz hat ganz recht, 2510/1023 ist ein
konstanter Ausdruck, beide Berechnungen sollten aber das selbe Ergebnis
zur Folge haben. Ich weiß ja nicht welchen Controller du benutzt,
dementsprechend solltest du dir aber die Frage stellen, ob hier immer
eine (vielleicht rechenintensive und überflüssige) Division sinnvoll
ist.
Schreib doch mal, welchen Controller du benutzt, was für ein Signal du
abtastest und welche Uref du benutzt.

Olaf

von Sascha (Gast)


Lesenswert?

Also,

ich nutze einen ATmega16, dessen int. Ref.-Spg. und gebe das ganze über
ein 10k Poti auf den ADC0.  Die 2510 ist die gemessene Ref.-Spg. mit
einem Multimeter. Normalerweiße sollte bei der Rechnung die Spannung
von 0-2510 angezeigt werden.

Mfg Sascha

von Fritz Ganter (Gast)


Lesenswert?

Sorry, war wohl müde:

nimm an, du bekommst den Wert 1000 gemessen:
1000*2510=2510000 dazu brauchst du einen 32bit integer um das zu
speichern.

Wenn du in C 2510/1023 rechnest, kommt 2 raus, wenn es richtig sein
soll, musst du 2510/1023.0 rechnen, dann kommt 2.45... raus, also
fliesskomma, damit kannst du mit x multiplizieren. Ist in C halt so,
Berechnungen in denen nur Integer vorkommt werden auch nur Ganzzahlig
gerechnet.

Fliesskomma ist halt speicherfressend und langsam.

An den 2er Schritten wirst mit einem 10bit Wandler nix ändern können.

Ich programmiere auch erst ein paar Tage MCs, muss mich auch erst von
32-bit auf 8-bit umgewöhnen.

von Sascha (Gast)


Lesenswert?

Hört sich ganz gut an. Werd es ausprobieren.
Habe sonst nur die 8051er in Assembler programmiert. Ist halt ne
Umstellung von MCS-51 nach AVR und vor allem von Assembler nach C. Aber
irgendwie find ich vieles in C einfacher.

Mfg sascha

von Sascha (Gast)


Lesenswert?

So,

habs ausprobiert. Es funktioniert einmalig. Nur wie kann ich daraus
eine Formatierte Ausgabe machen wie z.B. 0.00V?

Mfg Sascha

von Fritz Ganter (Gast)


Lesenswert?

Steht ja schon oben:

du kannst auch sprintf nehmen:

sprintf(buffer,"%d Grad",x);

oder falls x eine Fliesskommavariable ist:
sprintf(buffer,"%.1f Grad",x);
zeigt dann mit einer Dezimalstelle an.

Also, wenn du Fliesskomma hast:
sprintf(buffer,"%.2fV",x);
lcd_puts(buffer);

von Frank Simon (Gast)


Lesenswert?

Hallo,
ganz was anderes: meines Wissens musst Du zum Normieren durch die Zahl
der Stufen teilen, also durch 1024. Ich wollte es auch immer nicht
glauben, aber das kommt genau hin: du hast dann unten für den Wert
0b.00.0000.0000 ein halbes LSB und für den Maximalwert (den man
genaugenommen nicht mehr erfassen kann, denn er wäre ja
0b100.0000.0000) noch ein halbes LSB, und damit die (bis auf
Wandlungsfehler) ideale Tranferfunktion.
mfg
Frank

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.