Forum: Mikrocontroller und Digitale Elektronik LCD und berrechnungen


von Jan (Gast)


Lesenswert?

Hay habe heute die ansteuerung zu meinem Textdisplay mit einem hd44780 
controller und 2*16 zeichen im 4Bit modus fertig gestellt.
jetzt wollte ich gerne  das es leichter berrechnungen ausgiebt,
heißt:

int main(void)
{
int i;
i=4;

  lcd_init();
  lcd_setcursor( 0, 1 );
  lcd_string("Hello World!");

  while(1)
  {
  i=i+5;
  lcd_setcursor( 0, 2 );
  lcd_string("Betrag: %d,i");
  }

  return 0;
}

doch anstatt wenigstens 5 neben dem Betrag auszugeben und hoch zu 
addieren gibt er es mit so aus wie es dort steht, dachte es würde so wie 
bei der printf funktion klappen, tut es aber nicht wie stelle ich so nun 
an?
MfG

von Uwe (de0508)


Lesenswert?

Hallo Jan,

ohne deinen LCD-Code zu kennen, kann man dir nur beschränkt helfen !

nun man kann das so Programmieren wie sprintf, wenn man weiß wie das 
geht.

Sonst nimm halt itoa oder ltoa.

ok ?

von Cyblord -. (cyblord)


Lesenswert?

Nimm doch sprintf. Damit kannst du so formatieren wie du es von printf 
gewöhnt bist und das Ergebniss in einen String rausschreiben. Den String 
bekommt deine lcd routine.
Die Annahme, die LCD Print Routine (welche auch immer das ist), könnte 
dies schon von sich aus, ist natürlich Quatsch.

@Uwe:
itao und co. bringen dir wenig, wenn du z.B. führende Nullen usw. haben 
möchstest. Dafür ist das printf geraffel ja da.

gruß cyblord

von Jan (Gast)


Lesenswert?

also füge ich einfach die stdio.h hinzu und mache das dann über printf? 
habe ich dich richtig vertanden?
itoa und ltoa sagen mir bisher nichts werde mal schauen was ich dazu 
finde besten dank schon mal :)


hier die lcd routine, ist die selbe wie die aus dem tut.

// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
// 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
//

#ifndef LCD_ROUTINES_H
#define LCD_ROUTINES_H

//////////////////////////////////////////////////////////////////////// 
////////
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!

#ifndef F_CPU
#define F_CPU 3686400
#endif

//////////////////////////////////////////////////////////////////////// 
////////
// Pinbelegung für das LCD, an verwendete Pins anpassen
// Alle LCD Pins müssen an einem Port angeschlossen sein und die 4
// Datenleitungen müssen auf aufeinanderfolgenden Pins liegen

//  LCD DB4-DB7 <-->  PORTD Bit PD0-PD3
#define LCD_PORT      PORTD
#define LCD_DDR       DDRD
#define LCD_DB        PD0

//  LCD RS      <-->  PORTD Bit PD4     (RS: 1=Data, 0=Command)
#define LCD_RS        PD4

//  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
#define LCD_EN        PD5

//////////////////////////////////////////////////////////////////////// 
////////
// LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)

#define LCD_BOOTUP_MS           15
#define LCD_ENABLE_US           20
#define LCD_WRITEDATA_US        46
#define LCD_COMMAND_US          42

#define LCD_SOFT_RESET_MS1      5
#define LCD_SOFT_RESET_MS2      1
#define LCD_SOFT_RESET_MS3      1
#define LCD_SET_4BITMODE_MS     5

#define LCD_CLEAR_DISPLAY_MS    2
#define LCD_CURSOR_HOME_MS      2

//////////////////////////////////////////////////////////////////////// 
////////
// Zeilendefinitionen des verwendeten LCD
// Die Einträge hier sollten für ein LCD mit einer Zeilenlänge von 16 
Zeichen passen
// Bei anderen Zeilenlängen müssen diese Einträge angepasst werden

#define LCD_DDADR_LINE1         0x00
#define LCD_DDADR_LINE2         0x40
#define LCD_DDADR_LINE3         0x10
#define LCD_DDADR_LINE4         0x50

//////////////////////////////////////////////////////////////////////// 
////////
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
void lcd_init( void );

//////////////////////////////////////////////////////////////////////// 
////////
// LCD löschen
void lcd_clear( void );

//////////////////////////////////////////////////////////////////////// 
////////
// Cursor in die 1. Zeile, 0-te Spalte
void lcd_home( void );

//////////////////////////////////////////////////////////////////////// 
////////
// Cursor an eine beliebige Position
void lcd_setcursor( uint8_t spalte, uint8_t zeile );

//////////////////////////////////////////////////////////////////////// 
////////
// Ausgabe eines einzelnen Zeichens an der aktuellen Cursorposition
void lcd_data( uint8_t data );

//////////////////////////////////////////////////////////////////////// 
////////
// Ausgabe eines Strings an der aktuellen Cursorposition
void lcd_string( const char *data );

//////////////////////////////////////////////////////////////////////// 
////////
// Definition eines benutzerdefinierten Sonderzeichens.
// data muss auf ein Array[5] mit den Spaltencodes des zu definierenden 
Zeichens
// zeigen
void lcd_generatechar( uint8_t code, const uint8_t *data );

//////////////////////////////////////////////////////////////////////// 
////////
// Ausgabe eines Kommandos an das LCD.
void lcd_command( uint8_t data );


//////////////////////////////////////////////////////////////////////// 
////////
// LCD Befehle und Argumente.
// Zur Verwendung in lcd_command

// Clear Display -------------- 0b00000001
#define LCD_CLEAR_DISPLAY       0x01

// Cursor Home ---------------- 0b0000001x
#define LCD_CURSOR_HOME         0x02

// Set Entry Mode ------------- 0b000001xx
#define LCD_SET_ENTRY           0x04

#define LCD_ENTRY_DECREASE      0x00
#define LCD_ENTRY_INCREASE      0x02
#define LCD_ENTRY_NOSHIFT       0x00
#define LCD_ENTRY_SHIFT         0x01

// Set Display ---------------- 0b00001xxx
#define LCD_SET_DISPLAY         0x08

#define LCD_DISPLAY_OFF         0x00
#define LCD_DISPLAY_ON          0x04
#define LCD_CURSOR_OFF          0x00
#define LCD_CURSOR_ON           0x02
#define LCD_BLINKING_OFF        0x00
#define LCD_BLINKING_ON         0x01

// Set Shift ------------------ 0b0001xxxx
#define LCD_SET_SHIFT           0x10

#define LCD_CURSOR_MOVE         0x00
#define LCD_DISPLAY_SHIFT       0x08
#define LCD_SHIFT_LEFT          0x00
#define LCD_SHIFT_RIGHT         0x04

// Set Function --------------- 0b001xxxxx
#define LCD_SET_FUNCTION        0x20

#define LCD_FUNCTION_4BIT       0x00
#define LCD_FUNCTION_8BIT       0x10
#define LCD_FUNCTION_1LINE      0x00
#define LCD_FUNCTION_2LINE      0x08
#define LCD_FUNCTION_5X7        0x00
#define LCD_FUNCTION_5X10       0x04

#define LCD_SOFT_RESET          0x30

// Set CG RAM Address --------- 0b01xxxxxx  (Character Generator RAM)
#define LCD_SET_CGADR           0x40

#define LCD_GC_CHAR0            0
#define LCD_GC_CHAR1            1
#define LCD_GC_CHAR2            2
#define LCD_GC_CHAR3            3
#define LCD_GC_CHAR4            4
#define LCD_GC_CHAR5            5
#define LCD_GC_CHAR6            6
#define LCD_GC_CHAR7            7

// Set DD RAM Address --------- 0b1xxxxxxx  (Display Data RAM)
#define LCD_SET_DDADR           0x80

#endif

von Uwe (de0508)


Angehängte Dateien:

Lesenswert?

@cyblord,

ja ist klar, wollte auch nur die Basics darstellen. Ich verwende 
entweder die elm chan, die von PeDa oder eine selbst geschriebene 
Routine.

Hier mal die ersten in der Anlage.

von Cyblord -. (cyblord)


Lesenswert?

sprintf, nicht printf.

schau dir einfach mal den syntax an.

Wie gesagt, du gibst deinen Format-String und deine Variablen rein (wie 
bei printf) und das Ergebniss wird in einen String geschrieben.

Was ist daran unverständlich?

PS: Die Header Datei zu posten ist echt genial!

von Uwe (de0508)


Lesenswert?


von Cyblord -. (cyblord)


Lesenswert?

Also gut ich kaue mal vor:
1
char text[16];
2
sprintf(text,"Betrag: %d",i);
3
lcd_string(text);

von Jan (Gast)


Lesenswert?

ah okay in welcher header datei finde ich den sprintf? in der stdio.h?

also schreibe ich dann einfach, ist das richtig?

int main(void)
{
int i;
i=4;

  lcd_init();
  lcd_setcursor( 0, 1 );
  lcd_string("Hello World!");

  while(1)
  {
  i=i+5;
  lcd_setcursor( 0, 2 );
  sprintf(filename,"Betrag: %d",i);
  }

  return 0;
}

vielen dank für eure unterstützung :)

von Jan (Gast)


Lesenswert?

ahh okay danke verstehe :)
die 16 steht für die breite ist das richtig?

int main(void)
{
char text[16];
int i;
i=4;

  lcd_init();
  lcd_setcursor( 0, 1 );
  lcd_string("Hello World!");

  while(1)
  {
  i=i+5;
  lcd_setcursor( 0, 2 );
  sprintf(text,"Betrag: %d",i);
  lcd_string(text);
  }

  return 0;
}

so sollte es jetzt richtig sein oder? :)
Vielen dank es ist manchmal echt schwer sich durch so viele fachbegriffe 
zu kämpfen wenn man noch nicht so viel weiß :)
aber man lernt ja durch die Übung :)

von Cyblord -. (cyblord)


Lesenswert?

Jan schrieb:
> ahh okay danke verstehe :)
> die 16 steht für die breite ist das richtig?

Nunja, die sagt halt aus dass du ein Array mit 16 chars anlegst. D.h. du 
kannst in deiner text Variable max. 16 Zeichen speichern. Und ja, die 16 
deshalb weil du eben ein 16 Zeichen Display hast und man selten mehr als 
eine Zeile aufeinmal im Speicher halten muss.

> so sollte es jetzt richtig sein oder? :)

Soweit ich sehe ja.

Auch wenn deine Schleife da wahrscheinlich so schnell läuft, dass du auf 
dem Display nicht viel sehen wirst. Eventuell noch ein delay einfügen.

von Jan (Gast)


Lesenswert?

ja funktioniert :D
habe noch nen delay eingefügt :)
so super :=
dann fange ich mal an mit tastern zu arbeiten :)
 und versuche die if funktion einzubeziehen:)
besten Dank an euch allen :)

von Uwe (de0508)


Lesenswert?

Hallo,

cyblord ---- schrieb:
>> die 16 steht für die breite ist das richtig?
>
> Nunja, die sagt halt aus dass du ein Array mit 16 chars anlegst. D.h. du
> kannst in deiner text Variable max. 16 Zeichen speichern. Und ja, die 16
> deshalb weil du eben ein 16 Zeichen Display hast und man selten mehr als
> eine Zeile aufeinmal im Speicher halten muss.

Hier muss man etwas genauer sein. Platz für 16 Byte ja, aber ein String 
mit der Länge 0 benötigt schon 1 Byte! Bei 16 Zeichenlänge eines Strings 
sind das nun 17 Byte im array of char.

von Peter D. (peda)


Lesenswert?

Die Länge des LCD ist unwichtig.
Man muß schon die maximale Länge des Strings ermitteln, da 
Speicherüberläufe sehr schwer zu debuggen sind.

Text: 8 Byte
Integer-Zahl: 6 Byte
Null: 1 Byte
= 15 Byte.
Man muß also mindestens 15 Byte reservieren.


Peter

von Jan (Gast)


Lesenswert?

ah okay :) glaube ich habe es grob verstanden also muss ich maximal 
17byte  reservieren 16 für day display und 1 wenn der text 0 ist.

aber wieso reservierst du 6byte für die integer? dafür das der integer i 
mal über den wert 99999 geht?

und der text 8byte bezieht sich auf "Betrag: " sehe ichdas so richtig?
MfG und besten Dank :)

von Karl H. (kbuchegg)


Lesenswert?

Jan schrieb:
> ah okay :) glaube ich habe es grob verstanden also muss ich maximal
> 17byte  reservieren 16 für day display und 1 wenn der text 0 ist.
>
> aber wieso reservierst du 6byte für die integer? dafür das der integer i
> mal über den wert 99999 geht?

ein INteger (16 Bit) hat einen Zahlenbereich von

-32768 bis 32767

Zähl nach, wieviele Zeichen du im negativen Fall brauchen wirst um die 
kleinst mögliche Zahl in Textform darzustellen

von Cyblord -. (cyblord)


Lesenswert?

Uwe S. schrieb:

> Hier muss man etwas genauer sein. Platz für 16 Byte ja, aber ein String
> mit der Länge 0 benötigt schon 1 Byte! Bei 16 Zeichenlänge eines Strings
> sind das nun 17 Byte im array of char.

ja da hast du recht, das hab ich übersehen.

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.