PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD intialisierung



crazy-josef
12.10.2008, 11:28
Hallo zusammen,
Ich habe gestern und vorgestern vergeblich versucht mein Pollin 4x16 LCD zum funktionieren zu bewegen. (http://www.pollin.de/shop/downloads/D120573D.PDF)

Ich habe schon diverse Ansteuerungsmethoden ausprobiert und keine hat funktioniert (auser der von Bascom, um zu testen ob das Disply möglicherweise defekt ist =P~ ).

Das Beste ergebnis unter C erbrachte die LCD-Lib von Ulrich Radig, bei der immerhin zu erst in der 1. und 3. Zeile ein schwarzer stich auftauchte und dann nach ca. 15s sich das Display mit " ' ''DU5B "' ''DU5B ", was in der 2. Zeile stand meldete. :-s

Kann mir jemand helfen? [-o<

McJenso
12.10.2008, 12:17
Hallo,

vermutlich kann dir jemand helfen. 8)

Am besten postest du den Code, der das beste Ergebnis gezeigt hast. Dann erklärst du, was du an dem Ergebnis anderes erwartet hast.
Wichtig währe noch, dass du schreibst du, ob du das Display mit 4 oder 8 Leitungen ansteuerst und ob du Bussy-Bit auswerten möchtest, usw. Mit anderen Worten wie du das Display angeschlossen hast.

Gruß

Jens

crazy-josef
12.10.2008, 13:08
Hallo,
ich habe im Anhang den Code gespeichert.

Anschluss: Alles an PortB

Rs: 4
R/W: 5
E: 6
Datenleitungen 4-7: 0-3

µC: Mega48; ohne Quarz (=Standardtakt)

McJenso
12.10.2008, 17:20
Hallo,

nach dem ersten Überfliegen, konnte ich nichts finden. Bitte hilf mir noch etwas. Wenn du das Display gar nicht ansprichst sollten zwei schwarze Streifen zu sehen sein, okay? Dann schreib vor die Endlosschleife mal folgende Zeilen


lcd_init();
lcd_write (2,0);
//lcd_write (65,1);


Danach löscht du // und schreibst, was auf dem Display in beiden Fällen zu sehen war.

Gruß

Jens

crazy-josef
12.10.2008, 18:18
also wenn ich den Code von oben einfüge kommen erst die 2 Schwarzen Zeilen, dann kommt wieder DU5B " DU5B

wenn ich die Kommentierung aufhebe, erscheinen erst die 2 zeilen und dann nach einiger weit wieder das mit DU5B nur noch je ein Punkt vor DU5B

wenn ich die 2. Zeile Kommentiere kommen 2 schwarze Streifen und dann wieder die obrige Ausgabe

McJenso
13.10.2008, 19:14
Hallo,

auf die Ausgabe DU5B kann ich mir keinen Reim machen. Ich habe den Code mal mit meinem verglichen. Vielleicht hilft, dir diese init Routine ja weiter.



void InitLCD ()
{
uint8_t i;
LCD_RS_PORT &=~(1<<LCD_RS_PIN);
LCD_RW_PORT &=~(1<<LCD_RW_PIN);
for (i=0;i<3;i++)
{
SetData (0x03);
EnablePuls();
_delay_loop_2 (0xFFFF);
}
CheckBusy ();
SetData (2);
EnablePuls();
CheckBusy ();
WriteData (1,0x28);
WriteData (1,0x06);
}

SetData ersetzt du durch lcd_write (Data,0);

Enablepuls ist bei dir
LCD_Port_Write |= (1<<LCD_E);
WAIT();
LCD_Port_Write &=~ (1<<LCD_E);

_delay_loop_2 (0xFFFF); Die Zeit ist übertrieben lang, bin ich aber immer gut mit gefahren.

Für CheckBusy();
while ((lcd_read(0)&(1<<BUSYBIT)) > 0 && timeout++ < 500) {};

Es gibt dann aber noch den Unterschied, dass ich mit SetData nur die verbundenen 4Bits anspreche.Zu dem Zeitpunkt ist die Interfacebreite ja noch nicht eingestellt.
Mit WriteData schreibe ich, wie in deinem Programm, dann erst die oberen 4 und dann die unteren 4Bits.Da könnte es auch noch ein Problem geben. Aber versuchs erst einmal wie oben beschrieben.

Gruß

Jens

crazy-josef
13.10.2008, 20:34
Hallo Jens,
kannst du mir viellericht deinen ganzen Code geben, da dein und mein Code scheinbar etwas verschieden sind und ich zich Fehler/Warnmeldungen beim Kompilieren bekomme, wegen undeklarierten Funktionen und Variablen :D

Gruss Josef

McJenso
13.10.2008, 21:15
Hallo,

poste ich hier morgen.

Du musstest schon die Funktionen ersetzen. Hier mal das was du bis morgen probieren kannst



for (i=0;i<3;i++){
lcd_write (0x03,0);
LCD_Port_Write |= (1<<LCD_E);
WAIT();
LCD_Port_Write &=~ (1<<LCD_E);
WAIT();
}
lcd_write (0x02,0);
LCD_Port_Write |= (1<<LCD_E);
WAIT();
LCD_Port_Write &=~ (1<<LCD_E);
timeout = 0;
while ((lcd_read(0)&(1<<BUSYBIT)) > 0 && timeout++ < 500) {};
lcd_write (0x28,0);
LCD_Port_Write |= (1<<LCD_E);
WAIT();
LCD_Port_Write &=~ (1<<LCD_E);
timeout = 0;
while ((lcd_read(0)&(1<<BUSYBIT)) > 0 && timeout++ < 500) {};
lcd_write (0x06,0);


Danach sollte das Display leer und bereit zum Empfang von Daten sein.


Gruß

Jens

McJenso
14.10.2008, 16:14
Hallo,

hier der Code der bei mir läuft.
In der lcdportdef.h passt du den Anschluß des LCD's an.
Musst mal schauen, das nop im global.h schreibst du vielleicht in einen schon vorhandene Headerdatei. Aber so ein bisschen sollst du ja auch noch zu tun haben.

Fragen oder Kritik immer man her.

Gruß

Jens

crazy-josef
14.10.2008, 22:08
McJenso, danke für die ganze mühe, aber ich kann mir aus dem Code leider kein Beispielpreogramm deuten :X köntest du hier bitte ein posten (hauptsache, das lcd kommt irgendwie darin vor :D )

Gruss Josef

McJenso
14.10.2008, 22:49
Hallo,

als erstes musst du die lcdportdef.h anpassen. Du musst halt die Ports, Pins usw so eintragen wie es bei dir der Fall ist. Wenn du also Bit 0 (Datenleitung4)an PB0 angeschlossen hast,

#define LCD_DATA0_PORT PORTB /**< port for 4bit data bit 0 */
#define LCD_DATA0_DDR DDRB /**< port direction for 4bit data bit 0 */
#define LCD_DATA0_PINS PINB /**< port for 4bit data bit 0 */

#define LCD_DATA0_PIN 0 /**< pin for 4bit data bit 0 */


Wobei ich gerade sehe das du diesen Teil


#define LCD_BRIGHTNESS_PORT PORTB /**< port for Brightness */
#define LCD_BRIGHTNESS_DDR DDRB /**< port direction for Brightness */
#define LCD_BRIGHTNESS_PIN PB4 /**< pin for Brightness */
#define LCD_CONTRAST_PORT PORTB /**< port for CONTRAST */
#define LCD_CONTRAST_DDR DDRB /**< port direction for CONTRAST */
#define LCD_CONTRAST_PIN PB5 /**< Pin for CONTRAST */
#define LCD_ON_PORT PORTC
#define LCD_ON_DDR DDRC
#define LCD_ON_PIN 6


aus der Datei löschen kannst.

Am besten du erzeugst dir dann noch eine lcd.h in der die benötigten Funktionen deklariert werden.



void InitLCD ();
void WriteData (uint8_t , uint8_t);


Jetzt schreibst du ein kleines Programm


...
#include "lcd.h"
#include "global.h"

int main (void){

InitLCD ();
while (1) {}

return 0;
}

Jetzt muss das Display nach dem Einschalten leer sein.
Es dürfen nicht mehr die Balken da sein! Vorher brauchst du nichts weiter probieren.
Wenn das soweit geht, fügst du ein
WriteData (0,65);
hinter InitLCD(); ein. Dann sollte nach dem Einschalten ein A zu erkennen sein.
Funktionen wie z.B. PrintString, PrintChar, werden hierfür nicht benötigt. Die kannst du dann ja später ergründen.

Noch etwas, wenn du den Controller geflasht hast, ziehe für die ersten Versuche den ISP ab und schalte die Versorgung aus und wieder ein.
Nicht das es da zu Konflikten kommt.

Gruß

Jens

crazy-josef
16.10.2008, 15:32
Hallo Jens,
vielen Dank für die ganze Hilfe, das "A" wird angezeigt, nur habe ich jetzt ein anderes Problem, wie bekomme ich jetzt z.B. die Funktion PrintString in die Headerdatei, ich habe schon versucht die Variablennamen (also x und y) wegzulassen und dann einige Teile nach des Kommas, aber immer kommen Fehlermeldungen.

Gruss Josef

McJenso
16.10.2008, 18:39
Hallo,

void PrintString (uint8_t,uint8_t,char *);

Bitte beachte, dass der String nullterminiert sein muss. Das heißt das letzte Zeichen des Strings muss eine Null sein. Die Funktion gibt sonst lustige Dinge aus.

Gruß

Jens

thewulf00
19.10.2008, 14:50
Und mit "Null" meint er nicht '0' (das lesbare Ascii-zeichen), sondern das nullte Zeichen der Ascii-Tabelle: char Nullzeichen = 0x00.

crazy-josef
21.10.2008, 17:41
Hallo zusammen,
entschuldigung, dass ich jetzt erst wieder antworte, ich hatte aber in den letzten Tagen so viel um die Ohren, dass ich einfach keine Zeit zum basteln hatte.
Wie "nullterminiere" ich einen String?

Gruss
Josef

DerMaddin
21.10.2008, 18:20
Häng '\0' an den string an.

McJenso
21.10.2008, 19:06
Hallo,

wichtig ist erst einmal das dein Puffer groß genug ist.

char buffer[5] = "Hallo";
ist ganz böse und falsch, immer. Hallo hat zwar nur 5 Buchstaben, aber für die Null ist kein Platz mehr.

char *Buchstabe = 'a';
nicht falsch, für PrintString aber auch böse.

char buffer[15] = "Hallo";
ist okay, in Anführungszeichen wird \0 automatisch angefügt.

Aufpassen musst du auch, wenn du dir aus Zeichen Strings zusammenbasteles oder z.B. bei strncpy.

char buffer[6] = "Hallo";
char test [15] = "ABCDEFGHIJ";

strncpy(test,buffer,3);
test[3] = 0;

ohne test [3] = 0; würde der Ausgabestring HalDEFGHIJ sein.

okay?

Ich benutze die Null, um das Ende des Strings zu erkennen. In der Annahme das ich weiß was ich tue, ist das für mich auch okay. Der Quellcode war nicht zur Veröffentlichung gedacht und auf meine Anwendung zurecht geschnitten. Bisher nicht einmal optimiert*. Darum musst du selber darauf achten, dass eine Null da ist. Denkbar ist, dass man die Funktion spätestens nach erreichen der Zeichen pro Zeile abbricht. Damit kann man zwar keinen Mist bei der Ausgabe vermeiden, zumindest wird die Funktion aber definiert abgebrochen.


Gruß

Jens


* ohne Leidensdruck kann das auch noch seeehr lange dauern :-)

crazy-josef
21.10.2008, 19:34
Hi,
also den Sinn hab ich jetzt verstanden, nur die Umsetzung nicht :X
So'n klitze kleiner Beispielcode hilft mir weiter =)

Gruß Josef

thewulf00
21.10.2008, 19:41
Oder nutze einfach einen Buffer, der größer ist, als Dein geschriebenes und mach eine Schleife, die jedem Zeichen 0x00 zuweist. Dann kannst Du bequem Deinen String hineinschreiben und hinten ist garantiert ne null.

Die Ausgabe von itoa macht die null selber.

McJenso
22.10.2008, 17:54
Hallo,

ich befürchte fast, du siehst das zu kompliziert.

Wenn du z.B. den String so initalisierst
char MyString [10] = "Hallo";
ist der automatisch Nullterminiert. Du musst mindestens immer ein Byte mehr Platz haben als Zeichen.
sprich
char MyString [5] = "Hallo"; //falsch
char MyString [6] = "Hallo"; //richtig
Zum echten Problem wird das ganze, wenn du dir deine Strings aus Zeichen oder Teilstrings zusammensetzt. Da können wir dir aber kein Beispiel geben, weil wir nicht wissen, wie du das machst. Nach dem letzten 'Nutz'-Zeichen musst du gegeben falls noch eine Null schreiben.
z.B.
MyString [0] = 'H';
MyString [1] = 'a';
...
MyString [5] = 0;
oder
MyString [5] = '\0';

Gruß

Jens