Forum: Mikrocontroller und Digitale Elektronik Variablenwert auf LCD ausgeben


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Lokus P. (derschatten)


Lesenswert?

Wenn ich mit dem Befehl "lcd_putc" von der Peter Fleury lib den Inhalt 
einer Variable auf das LCD ausgeben möchte, muß ich den Wert dann mit 
"itoa" in einen String umwandeln, oder gibts da eine andere Lösung?

Bei mir ist die Variable mit "unsigned char" definiert.

von Karl H. (kbuchegg)


Lesenswert?

Manfred W. schrieb:
> Wenn ich mit dem Befehl "lcd_putc" von der Peter Fleury lib den Inhalt
> einer Variable auf das LCD ausgeben möchte, muß ich den Wert dann mit
> "itoa" in einen String umwandeln, oder gibts da eine andere Lösung?

was gefällt dir daran nicht?
Du kannst dir ja immer eine spezielle Funktion machen, die dir die 
Detailarbeit abnimmt.

> Bei mir ist die Variable mit "unsigned char" definiert.

Dann nimm aber besser utoa anstelle von itoa.

http://www.mikrocontroller.net/articles/FAQ#Wie_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F

von Michael (Gast)


Lesenswert?

Manfred W. schrieb:
> Wenn ich mit dem Befehl "lcd_putc" von der Peter Fleury lib den Inhalt
> einer Variable auf das LCD ausgeben möchte, muß ich den Wert dann mit
> "itoa" in einen String umwandeln, oder gibts da eine andere Lösung?

Das kommt drauf an, was der Inhalt der Variablen bedeuten soll. Wenn 
darin der ASCII-Wert eines Zeichens steht, das auf dem Display 
erscheinen soll, bist du mit lcd_putc schon gut davor, sonst mußt du dir 
erstmal einen ausgabewürdigen String erzeugen.

von Martin (Gast)


Lesenswert?

Wie sieht es mit printf aus?

von Lokus P. (derschatten)


Lesenswert?

Also der Wert in der Variable ist eigentlich eine stinknormale Zahl.
lcd_putc gibt ja in der Regel nur Strings aus.

von Karl H. (kbuchegg)


Lesenswert?

Manfred W. schrieb:
> Also der Wert in der Variable ist eigentlich eine stinknormale Zahl.

Trotzdem sollst du anfangen auf Datentypen zu achten.

singed und unsigned sind 2 paar Schuhe. Bei der Zahl 10 macht das keinen 
Unterschied. Aber bei 34587 (als 16 Bit int) macht das sehr wohl einen 
Unterschied.

itoa und 'unsigned' passen nicht zusammen.


> lcd_putc gibt ja in der Regel nur Strings aus.

lcd_putc gibt in der Regel noch nicht einmal einen String aus, sondern 
ein einzelnes Zeichen. Das 'c' in 'putc' steht nämlich für Character, 
also char.

Um Strings auszugeben, heißt die Funktion meistens lcd_puts. Wobei das 
's' in 'puts' für String steht.

Und nix und niemand hindert dich daran, dir eine Funktion lcd_puti bzw. 
lcd_putu zu schreiben, die einen signed int (lcd_puti) bzw. einen 
unsigned int (lcd_putu) ausgeben. Die einfachst Variante ist in beiden 
Fällen erst mal aus den Zahlen eine STringrepäsentierung erzeugen zu 
lassen und dann auf die bereits vorhandene Funktion lcd_puts 
zurückzugreifen, die einen String ausgeben kann (und die ihrerseits 
dafür wieder die Funktion lcd_putc benutzen wird)


http://www.mikrocontroller.net/articles/FAQ#Wie_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F

von Uwe (de0508)


Angehängte Dateien:

Lesenswert?

Hallo Manfred,

ich muss korrigieren:

(c)lcd_putc(/c) Put C wie Char also Zeichen

(c)lcd_puts(/c) Put String.

Hier noch eine fertige Routine für 16 oder 32-Bit Zahlen.

Beitrag "Formatierte Zahlenausgabe in C"

Ich verwende diese angepasste Version im Anhang.

Was auch immer hilft ist diese Lib:

"Embedded printf module for AVR"

- http://elm-chan.org/docs/avrlib/xitoa.zip

von Uwe (de0508)


Lesenswert?

Nachtrag,

Chan hat auch noch dies Programmiert:

"Embedded String Functions"

- http://elm-chan.org/fsw/strf/xprintf.html

von Lokus P. (derschatten)


Lesenswert?

Hallo Uwe,

mit ist nur nicht ganz klar wie der Syntax von der valout lautet.

von Uwe (de0508)


Lesenswert?

Hallo Manfred,

PeDa hat im original schon ein Beispiel drin, das könnte selbsterklärend 
sein ?

Die Zahl -20,00000 wird um 1 erhöht, immer und immer wieder..

Seine LCD Ausgabe ist nur etwas spezieller, (c)char lcd_mem[32](/c) ist 
ein Abbild des LCD Rams und wird per ISR in das LCD Display geschrieben.

(c)s32 val;




int main( void )

{

  val = -2000000L;

  lcd_init();

  sei();

  for(;;){

    val++;

    valout( val, 16, 5, lcd_mem + 16 );

  }

}(/c)

von Lokus P. (derschatten)


Lesenswert?

hm, damit komme ich leider überhaupt nicht zurecht.
"val" ist wohl die Variable mit der Zahl, aber der Rest sagt mir gar 
nichts.
Was geben die beiden ersten Werte an?
Wozu ein Abbild des LCD Rams?

Warum ist das so kompliziert eine stinknormale Variable am LCD 
auszugeben?

von Karl H. (kbuchegg)


Lesenswert?

Manfred W. schrieb:

> Warum ist das so kompliziert eine stinknormale Variable am LCD
> auszugeben?

ist es auch nicht.

http://www.mikrocontroller.net/articles/FAQ#Wie_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F
Warum liest du das nicht?


(Sorry Uwe. Aber hier muss ich eingreifen. Du überforderst Manfred mit 
deiner super duper Funktion).

Manfred schreib dir 2 Funktionen, eine für normale int, eine für 
unsigned int.
1
void lcd_puti( int number )
2
{
3
  char buffer[10];
4
5
  itoa( number, buffer, 10 );
6
  lcd_puts( buffer );
7
}
8
9
void lcd_putu( unsigned int number )
10
{
11
  char buffer[10];
12
13
  utoa( number, buffer, 10 );
14
  lcd_puts( buffer );
15
}

fertig. Und genau deswegen hab ich dir den Link gepostet. Denn das ist 
so einfach wie einem Baby den Schnuller klauen. Du musst nur 2 Konzepte 
zusammenführen: aus einer Zahl einen String machen UND den String danach 
ausgeben.

verwendet
1
  ....
2
3
  int8_t i = 5;
4
  int16_t j = 8;
5
6
  lcd_puti( 8 );
7
  lcd_puti( i );
8
  lcd_puti( j );
9
10
  uint8_t k = 12;
11
  lcd_putu( k );

lcd_puti für alle signed Werte. lcd_putu für alle unsigned.

Und studiere den verd#&%"?en Link in die FAQ. Genau deshalb haben wir 
das nämlich geschrieben.

von Lokus P. (derschatten)


Lesenswert?

Danke erstmal,
Komme trotzdem nicht auf einen grünen Zweig.

Die Funktion habe ich zwar jetzt eingebaut nur haut das mit meiner 
Variable nicht hin.
Er meint:
1
../main.c:362: warning: implicit declaration of function 'dogm_putu'

Die Funktion bei mir heißt:
1
void dogm_putu(unsigned int number)
2
{
3
  char buffer[10];
4
5
  utoa(number,buffer,10);
6
  dogm_puts(buffer);
7
}

Die Variable wird als unsigned char nKonfig declariert.
Aber auch ein unsigned int nKonfig ändert nichts daran.

Und zugewiesen wird sie unter anderem so:
1
      if(pgm_read_byte(&menu[menu_index].ActionCode) == DEF_KEY_ACTION)      // Untermenüpunkt von TASTENZUORDNUNG gewählt
2
      {
3
        nKonfig = pgm_read_word(&menu[menu_index].ActionValue);
4
        indexTasten = menu_index;
5
      }

von Karl H. (kbuchegg)


Lesenswert?

Manfred W. schrieb:
> Danke erstmal,
> Komme trotzdem nicht auf einen grünen Zweig.

Dein Name kommt mir bekannt vor. Eventuell tue ich dir unrecht aber ich 
habe jemandem mit dem Namen Manfred W schon vor über einem halben Jahr 
gesagt, dass er ohne C-Buch nicht weiter kommt.

>
> Die Funktion habe ich zwar jetzt eingebaut nur haut das mit meiner
> Variable nicht hin.
> Er meint:
>
1
> ../main.c:362: warning: implicit declaration of function 'dogm_putu'
2
>

Das hat nichts mit der Variablen zu tun, sonder damit, dass du eine 
Funktion benutzt, die der Compiler (zu diesem Zeitpunkt) noch nicht 
kennt.

Du kannst so was machen
1
void foo( uint8_t i )
2
{
3
   ...
4
}
5
6
int main()
7
{
8
  ....
9
  foo( 8 );
10
}

dann kennt der Compiler die Funktion bereits, wenn er in main den Aufruf 
machen soll. Einfach deswegen weil der Compiler den Quelltext von oben 
nach unten liest.

Du kannst auch einen Protoyp vor die erste Verwendung setzen und die 
eigentliche Implementierung der Funktion dann erst danach machen.
1
void foo( uint8_t i );
2
3
int main()
4
{
5
  ...
6
  foo( 8 );
7
}
8
9
void foo( uint8_t i )
10
{
11
  ...
12
}

Aber du kannst nicht das hier machen
1
int main()
2
{
3
  ...
4
  foo( 8 );
5
}
6
7
void foo( uint8_t i )
8
{
9
  ...
10
}

denn hier gibst du die Informationen darüber wie die Funktion foo 
aussieht erst nach der ersten Verwendung preis. Genauer gesagt kannst du 
das schon machen, nur treten dann Standardannahmen in Kraft, sprich der 
Compiler saugt sich bei
1
int main()
2
{
3
  ...
4
  foo( 8 );
5
}
aus den Fingern (nach bestimmten Regeln), wie die Argumentliste von foo 
wohl aussehen wird. Und siehe da, diese Regeln führen zu Annahmen, die 
dann später mit dem hier
1
void foo( uint8_t i )
2
{
3
  ...
4
}
nicht zusammen passen.

von Lokus P. (derschatten)


Lesenswert?

Sorry, da hab ich früher um Hilfe geschrien als nachzudenken.
Ist natürlich logisch.

Muß die Funktion in der Header-Datei ebenfalls eintragen und schon passt 
es.

Bin schon still :)

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.