Hallo Leute,
seit einigen Wochen beschäftige ich mit dem Thema LCD am
Mikrocontroller.
Nach einigen einsamen Stunden am Rechner ist es mir auch gelungen texte
an dem LCD auszugeben.
Zum Problem: Um einen ganzen String an das LCD zu senden, habe ich
mittels Pointer gearbeitet.
Zualler erst mal hast du dir die Basisfunktion ungeschickt geschrieben.
Das du eine Funktion hast, die 2 Strings auf einmal ausgeben kann, ist
gut. Aber du hast nicht gesehen, dass da 2 mal die noch primitivere
Basisfunktion "gib 1 String aus" drinnen steckt.
Noch hat sich nichts verändert.
Aber die Dinge ändern sich. Denn um
1
lcd_text("Temperatur",temp);
das hier zu tun, ist die Funktion lcd_text unbrauchbar. Die kann ja 2
Strings ausgeben. Aber nicht einen String und einen int. Einen String
könntest du (dank lcd_string) ausgeben, aber um den int auszugeben
brauchst du eine weitere Hilfsfunktion, die genau das (und nicht mehr)
kann: einen int ausgeben.
FAQ
(gleich der erste Punkt)
und der Rest ist wieder ein Kinderspiel. Du hast eine Funktion, die
einen String ausgeben kann - du hast eine Funktion die einen int
ausgeben kann - was also ist naheliegender, als mit diesen beiden
Hilfsfunktionen (und den entsprechenden lcd_line Funktionen) eine
weitere Funktion zu bauen
1
voidlcd_wert(constchar*label,intwert)
2
{
3
lcd_line1();
4
lcd_string(label);
5
6
lcd_line2();
7
lcd_int(wert);
8
}
und damit kannst du dann im Hauptprogramm das hier machen
1
...
2
lcd_text("Vielen Dank!","Schon mal!");
3
lcd_wert("Temperatur",temp);
4
...
Die Kunst besteht momentan auf dieser Ebene noch darin, sich selbst
einen kleinen universell einsetzbaren Baukasten an Basisfunktionen zu
machen, aus dem sich dann komplexere Sachen zusammensetzen lassen.
Deine 'Basisfunktion' war noch nicht primtiv genug, daher sind da keine
Bausteine für andere Basisfunktionen abgefallen. Mit dem lcd_string und
der noch von dir zu schreibenden lcd_int hat sich das geändert.
Naja, lcd_text erwartet einen String (char *), also kannst du keinen
char übergeben, und auch keinen int oder sonstwas.
(Ich würd übrigens das unsigned weglassen, hier gehts ja um Text)
Du musst also aus deinem "char temp" irgendwie einen String formen.
Ein Tipp: schau dir mal die Standard-Funktion itoa() an.
Zusätzlich musst du dir Speicher reservieren, den du dan an atoi()
übergibst damit diese hineinschreiben kann.
Simon T schrieb:> Jetzt habe ich aber noch folgendes Problem:
Bei dem Code hast du zwei Probleme ;)
Das andere wirst du erkennen, wenn dein Code mal compiliert, und dann
das Programm abstürzt, oder zumindest nur Blödsinn anzeigt.
Oliver
Oliver schrieb:> Bei dem Code hast du zwei Probleme ;)
Drei...
Simon T schrieb:> Jetzt habe ich aber noch folgendes Problem:> int lcd_int(int wert)> {> int buffer[10];
Wenn du einen String willst, sollte das ein Array aus char sein, nicht
int.
> itoa(wert,buffer,10);> return(buffer);
Autsch! Du gibst hier einen Zeiger zurück auf einen Puffer, der bei
Rückkehr auf die Funktion freigegeben wird und daher im Aufrufer
tunlichst nicht zu verwenden ist.
> }>> So sollte ja die lcd_int aussehen, allerdings kennt Ride7 trotz include> von stdlib, die itoa nicht??
Dann wird "Ride7" (was immer das sein mag) die nicht unterstützen. Es
ist keine Standard-Funktion.
Rolf Magnus schrieb:> Dann wird "Ride7" (was immer das sein mag) die nicht unterstützen. Es> ist keine Standard-Funktion.
Schon richtig, ist keine Standardfunktion.
Sie könnte auch _itoa heissen. Dann wäre sogar die Namensgebung ganz
korrekt. Wenn auch das nicht, dann wird man wohl zum aussersten greifen
müssen und die Ride7 Doku zur Rate ziehen. Oder man schreibt sie sich
selber. Ist ja nicht schwer (und da dieses so ist, wundert es mich, dass
es nichts gleichwertiges in Ride7 [was immer dieses Ride7 auch sein
soll] gibt)
@Simon
> So sollte ja die lcd_int aussehen
Nein. Eigentlich nicht.
Sinn der Funktion lcd_int ist es, etwas auf das LCD auszugeben! In
völliger Analogie zu den anderen lcd_.... Funktionen.
Deine Funktion gibt aber nichts aus! Scheinbar hast du den Link in die
FAQ entweder nicht gesehen oder nicht gelesen.
1
voidlcd_int(intwert)
2
{
3
charbuffer[10];
4
5
itoa(wert,buffer,10);
6
lcd_string(buffer);
7
}
(bzw. dann eben die Funktion, die du als Ersatz für itoa hernimmst.)
in deinem Baukasten:
1
lcd_string gibt einen String auf das LCD aus
2
lcd_int gibt einen int auf das LCD aus
mit der besonderen Betonung auf 'gibt ... aus'. Und wenn diese
Konvention in deinem Baukasten gilt, dann sollen die Funktionen dann
auch genau das tun. Und zwar möglichst einheitlich, damit man sich das
auch merken kann.
Simon T schrieb:> so Probleme beseitigt, bis auf eins. Wie soll ich den Wert zurück geben?
das geht nun mal nicht. Aus dem Grund gibt auch itoa keinen String
zurück.
Ok, sprintf ist natürlich die Holzhammermethode.
Nicht dass ich davon abraten würde, das musst du wissen ob du die
Resourcen hast. Ich selbst benutz es mittlerweile auch, weils mir zu
blöd ist jeweils 10 verschiedene Interfaces für Lcd und UART zu haben,
je nachdem was ich ausgeben will.
Mit der printf-Familie hast du ein einziges Interface und kannst dem
alles übergeben.
Aaaaaber: wenn du anscheinend vor hast, sprintf zu nutzen dann ist die
Funktion lcd_int obsolet.
Wenn das printf-Zeugs dazugelinkt wird hast du nicht mehr das Problem,
verschiedene Funktionen für verschiedene Datentypen schreiben zu müssen.
Dann brauchst du keine lcd_text() oder lcd_wert() mehr.
Du kannst dir eine Funktion anlegen die alles ausgeben kann.
Aber der dritte Weg ist, eine itoa() selber zu schreiben. Das ist kein
Hexenwerk und könnt dich weiterbringen.
Simon T schrieb:> void lcd_int(int wert) //Funktion zum umwandeln von Int in
String
> Jetzt ist Feierabend für heute!
das ist wieder ein schönen Problem mit sinnlosen Kommentaren, jetzt
passt der Kommentar nicht mehr zur Funktion
Simon T schrieb:
Nicht das ich ein Problem damit habe, aber
> char buffer[16]; //String mit 16 Stellen
erstens sind es nur 15 Stellen.
Aber. Wieso 15? Wie gross ist denn ein int auf deinem System?
Wenn der, was auf einem AVR üblich ist, 2 Bytes groß ist (also 16 Bit),
dann hat der einen Wertebereich von -32768 bis 32767. Das sind als
maximal 5 Stellen für die Ziffern und noch 1 Stelle für ein mögliches
negatives Vorzeichen. Macht in Summe 6 benötigte Stellen, also ist ein
Array der Länge 7 ausreichend.
Wie gesagt, es wird nicht viel ausmachen, da ein paar Bytes zuviel
anzulegen und wenn man die Ausgabe etwas freier macht, dann schadet das
auch nicht. Aber mit einem 16-Bit int ist es in DIESER Funktion
technisch nicht möglich, mehr als 6 druckbare Zeichen zu erhalten.
Karl Heinz schrieb:> Wenn der, was auf einem AVR üblich ist,
Ah!
Merke gerade, dass an keiner Stelle im ganzen Thread von einem AVR die
Rede ist.
Vergiss bitte das vorhergehende Posting.