Forum: Mikrocontroller und Digitale Elektronik LCD zeigt nur die Hälfte an


von Alex L. (talli)


Lesenswert?

Hallo zusammen,
ich hab da ein kleines Problem und zwar mit einem LCD.
es handelt sich dabei um ein 16-zeichen/1-zeiliges aus dem Hause 
Reichelt(LCD161A).dieses versuche ich nun mithilfe eines ATmega8 
anzusteuern, und zwar sende ich ans LCD 12 Zechen nacheinander mit je 
5ms Pausen dazwischen.
was man dabei auf dem LCD sieht ist folgendes:es werden nur die ersten 8 
Zeichen auf der linken  Displayseite dargestellt, die rechte bleibt 
komplett leer, dabei spielt es keine Rolle ob ich es in 4- oder 8-Bit 
Modus ansteuere, das Ergebnis bleibt stets das gleiche.
und was mir noch aufgefallen ist - wenn man das LCD einfach mal an die 
versorgungsspannung anschliesst, ohne uC dann sieht man nur 8schwarze 
balken links, die rechte Displayhälfte scheint irgentwie tot zu sein.
tja, und bevor ich das gute Stück wieder zurückschicke wollte ich euch 
erstmal fragen - vielleicht hat jemand von euch sowas ähnliches schon 
mal gehabt, gibt es vielleicht da irgendein Trick oder hat das Ding 
tatsächlich ne Macke?

von Kallius (Gast)


Lesenswert?

Bin mir nicht sicher, aber so was ähnliches hatte ich auch mal: das 
Display war 16x1, aber wurde als 8x2 angesteuert - probier' das mal...

von Michael Nagler (Gast)


Lesenswert?

Schau mal da: http://www.sprut.de/electronic/lcd/#1x16

Gruß
Michael

von Alex L. (talli)


Lesenswert?

jo, jetzt gehts, danke für den guten Tipp!

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

Ich hab nun alles probiert.
Auch mein LCD mit 8x2 zu initialisiern, kein Erfolg.

Im Anhang findet ihr meine LCD.h und mein Programm.
Betrieben wird das LCD im 4Bit Modus.
Angeschlossen ist es wie im angehängten Bild, außer, dass das LCD an 
PortD angeschlossen ist und nicht PORTC wie im Bild.
Ich hoffe mir kann wer helfen.

Infos:
IDE: AVR Studio 4
Compiler: WIN AVR
µC:ATMEGA8

MFG Julian

von Thi L. (flothi)


Lesenswert?

Um welches LCD gehts denn? Ist es identisch zu obigem? Wäre wichtig zu 
wissen...

von Nn N. (jaytharevo)


Lesenswert?

Hallo,
tut mir leid.

LCD heißt: TC1602A-09, gabs bei Pollin, habe es aber wo anders her.

von Nn N. (jaytharevo)


Lesenswert?

Werd mir wohl ein neues kaufen müssen um sicher zugehen ob es an der 
Software oder Hardware liegt...

von Ingeniör (Gast)


Lesenswert?

Hast Du mal die Lötstellen auf Wackelstellen hin gecheckt? Dein Problem 
deutet zumindest auf kalte Lötstellen hin.

von Nn N. (jaytharevo)


Lesenswert?

Wurde doppelt gelötet, die Lötstellen sind sauber!
Hat ein Prof. von mir gelötet, die sind nahezu perfekt^^ :D.

von Thi L. (flothi)


Lesenswert?

Die Tatsache, dass der Prof das gelötet hat heißt noch lange nix :-D

Hast du mal unterschiedliche Startwerte für die Zeilen ausprobiert? Ich 
hatte das Problem bei nem Xilinx-Board, dass die Doku vom Board und vom 
Displayhersteller bei, sagen wir, nicht zutreffend waren.

vg

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Ich hab nun alles probiert.
> Auch mein LCD mit 8x2 zu initialisiern, kein Erfolg.
Was geht? Gar nichts? Oder kannst du wenigstens irgendwas erkennen, wenn 
du die Kontrastspannung auf 0V drehst?

> Auch mein LCD mit 8x2 zu initialisiern
> LCD heißt: TC1602A-09
Ähm, da steht beim Max: 2 Zeilen x 16 Zeichen Text... :-o


BTW: du darfst auch ruhig einen neuen Thread anlegen, dann muss sich 
nicht jeder erst mal durch eine 3 Jahre alte Frage durchwursteln... :-/

von derLars (Gast)


Lesenswert?

Ich hatte das Problem auch bei einem 16er Display. Mein Problem war, 
dass das Datenblatt sehr undurchsichtig war. Ich konnte daraus nicht 
ersehen wo der zweite Teil des Displays "anfängt".

Ich habe dann einfach einen elends langen String in den Speicher 
geschrieben der Art "1234567890ABCDE......" und habe den dann immer 
wiederholt. Irgendwann erschien dann tatsächlich auch was in den letzten 
8 Stellen.

Vielleicht hilft das ja ;)

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

Hallo,
danke für eure Antworte :), gute Idee @Lars.

Ich kann schon etwas erkennen, bevor ich, das versuch zu beschreiben 
macht euch selbst ein Bild, die sagen ja bekanntlich mehr als 1000 Worte 
;).



MFG Julian

von Nn N. (jaytharevo)


Lesenswert?

Florian Th. schrieb:
> Hast du mal unterschiedliche Startwerte für die Zeilen ausprobiert? Ich
> hatte das Problem bei nem Xilinx-Board, dass die Doku vom Board und vom
> Displayhersteller bei, sagen wir, nicht zutreffend waren.

Was meinst du mit versch. Startwerten?

Lothar Miller schrieb:
> Ähm, da steht beim Max: 2 Zeilen x 16 Zeichen Text... :-o

Hab mich auch schon gewundert, diese Bezeichnung sagt der Beipackzettel, 
aber mein Display ist definitiv nur 16x1^^

von Nn N. (jaytharevo)


Lesenswert?

WOW, DANKE LARS. Super Idee.

Mein Code Schaut so aus:
1
 /* String auf Display anzeigen */
2
lcd_puts("Willkomm");
3
4
/* String auf Display anzeigen */
5
lcd_puts("Willkommen");   
6
lcd_puts("Willkommen");  
7
lcd_puts("Willkommen"); 
8
lcd_puts("Wien");

Dann steht auf dem Display wirklich "Willkommen".

Was bedeutet, dass nun für mich, wo ist meine Startadresse der 2. Zeile?

MFG Julian und VIELEN DANK!

von Thi L. (flothi)


Lesenswert?

Hallo Julian!

Schön, dass das klappt - probiers doch aber auch mal mit 
unterschiedlichen Strings, damit du weißt, welche lcd_puts()-Anweisung 
greift. Dann würde ich schauen, inwiefern die lcd_puts()-Funktion die 
Werte (der Positionen) verändert (wahrscheinlich inkrementiert) und dann 
wirst du auf einen Wert kommen.

Zur Startadresse: Die Displays (bzw. jede einzelne Position) hat feste 
Werte, so zB für jede Zeile. Einige Displays haben z.B. als Offset für 
die erste Zeile ein 0x00, für die zweite 0x40; es kann aber auch 
innerhalb einer Zeile zu Sprüngen kommen, dass also nicht von 0x00 bis 
0x0F durchgezählt wird. Das ist wiederrum vom Controller abhängig und 
wie der verschaltet ist. (vgl. http://www.sprut.de/electronic/lcd/)

VG

von jaytharevo (Gast)


Lesenswert?

Florian Th. schrieb:
> Schön, dass das klappt - probiers doch aber auch mal mit
> unterschiedlichen Strings, damit du weißt, welche lcd_puts()-Anweisung
> greift. Dann würde ich schauen, inwiefern die lcd_puts()-Funktion die
> Werte (der Positionen) verändert (wahrscheinlich inkrementiert) und dann
> wirst du auf einen Wert kommen.

Hallo,
es greift der "Wien" String. Das "en" von "Wien" gibt mir, dass "en" 
welches ich für Willkomm"en" brauche. Dh. ich muss 3 mal "Willkommen" 
ausgeben und zusätzlich noch das "Wi".

von MarioT (Gast)


Lesenswert?

>aber mein Display ist definitiv nur 16x1^^
Auf dem Bild vom
Datum: 15.03.2010 22:53
kann man am Kontrast gut erkennen das es ein "Zweizeiliges" LCD ist.

von Karl H. (kbuchegg)


Lesenswert?

Oh Mann du machst dir selbst das Leben unnötig schwer.
Gib doch einfach aus
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
dann siehst du sofort wo die Ausgabe abbricht und wo sie wieder 
einsetzt. Auch Teststrings, mit denen Sachverhalten abgeklärt werden, 
wollen überlegt gewählt werden

Also: Du gibst aus

WilkommWillkommenWillkommenWillkommenWien
       |                              |
       +------------------------------+
         der Teil ist nicht sichtbar.

Also hast du einen Versatz von (tapp, tapp, tapp, Zeichen zählen): 32 
Zeichen also Hex 0x20

Du hast also ein 2*8 LCD mit einem Zeilenversatz der 2.ten Zeile von 
0x20 Zeichen.

von jaytharevo (Gast)


Lesenswert?

Also ich suche nach einer Möglichkeit die 2. Startadresse zu ermitteln.
Das Wort "Willkommen" hat ja bekanntlich 10 Buchstaben. Also 10 * 1Byte 
und das Ganze dann 3 mal plus 2 wegen dem "Wi", stimmt, das so weit? 
Kann, mann die Startadresse eigentlich irgendwie errechnen oder ist die 
sowieso irgendwie eingestellt. Vorallem bei so einem "windigem" LCD 
könnte ich mir vorstellen, dass sie Startadresse irgendwo ist.

von Karl H. (kbuchegg)


Lesenswert?

jaytharevo schrieb:
> Also ich suche nach einer Möglichkeit die 2. Startadresse zu ermitteln.

Fingern abzählen?

> Also 10 * 1Byte und das Ganze dann 3 mal plus 2 wegen dem "Wi",
> stimmt, das so weit?

Probiers einfach aus :-)
Dein µC bzw. dein LCD zeigen dir sehr schnell ob du dich irgendwo 
verzählt hast.

> Kann, mann die Startadresse eigentlich irgendwie errechnen oder ist die
> sowieso irgendwie eingestellt.

Die ist fix

von Nn N. (jaytharevo)


Lesenswert?

Hallo,
1
#define LCD_LINES           2     /**< number of visible lines of the display */
2
#define LCD_DISP_LENGTH     8     /**< visibles characters per line of the display */
3
#define LCD_LINE_LENGTH  0x40     /**< internal line length of the display    */
4
#define LCD_START_LINE1  0x00     /**< DDRAM address of first char of line 1 */
5
#define LCD_START_LINE2  0x40     /**< DDRAM address of first char of line 2 */
6
#define LCD_START_LINE3  0x14     /**< DDRAM address of first char of line 3 */
7
#define LCD_START_LINE4  0x54     /**< DDRAM address of first char of line 4 */
8
#define LCD_WRAP_LINES      0     /**< 0: no wrap, 1: wrap at end of visibile line */

Was meint ihr müsste ich da nun ändern? Start of Line 2? Hab ich auch 
auf 0x60 probiert, machte keinen Unterschied.

von Karl H. (kbuchegg)


Lesenswert?

Julian Schild schrieb:

> Was meint ihr müsste ich da nun ändern? Start of Line 2? Hab ich auch
> auf 0x60 probiert, machte keinen Unterschied.

Finger durcheinander gekommen?
Gerade eben hab ich dir vorgezählt, dass deine Zeilen offenbar einen 
Versatz von 32 Zeichen haben. 32 ist hexadezimal 0x20

Und nein.
Du musst dich um die Adressierung in die nächste Zeile höchst 
wahrscheinlich selbst kümmern. Der LCD Code den du hast wird das nicht 
machen.
Du könntest höchstens probieren den Wrap mal auf 1 zu setzen

von Иван S. (ivan)


Lesenswert?

Julian Schild schrieb:
> LCD heißt: TC1602A-09

Bist Du Dir mit dieser Bezeichnung sicher? Bei Tinsharp, dem Hersteller 
des Displays kann ich nur das TC1602A-09T finden, das wäre aber ein 
16x2.

Jedergang, Tinsharp verwendet bei seinen Displays zu 90% den Controller 
SPLC780D von Sunplus. Das Datenblatt zum Controller sollte man lesen.

> aber mein Display ist definitiv nur 16x1

Physikalisch schon, aber wie man nach dem Controllerreset sieht, wird es 
als zweizeiliges LCD initialisiert (Hälfte wird dunkel). Falls ich auf 
Deinem Photo richtig sehe, handelt es sich um eine Zeichengröße von 5x8 
Punkten.

Die zweite Linie beginnt lt. Datenblatt mit Zeichenaddresse 0x40h.

Und bitte nächstes mal einen neuen Fred aufmachen, ich hatte nämlich 
schon alles für das Display LCD161A von Displaytech herausgesucht, da 
davon im OP die Rede war.

Hoffe das hilft Dir irgendwie weiter,
Iwan

von Nn N. (jaytharevo)


Lesenswert?

Naja, das Problem ist eben, dass es nicht 0x40 ist. Wie oben eingestellt 
(lcd.h) funktioniert es leider nicht.


Auch wenn ich es um die 32 Zeichen versetze. 0x40+0x20=0x60

Wrap blendet mir sowieso die erste Zeile komplett aus.

Иван S. schrieb:
> Physikalisch schon, aber wie man nach dem Controllerreset sieht, wird es
> als zweizeiliges LCD initialisiert (Hälfte wird dunkel). Falls ich auf
> Deinem Photo richtig sehe, handelt es sich um eine Zeichengröße von 5x8
> Punkten.

Das kommt daher weil das LCD eben als 8x2 konfiguriert ist.

von spess53 (Gast)


Lesenswert?

Hi

>Auch wenn ich es um die 32 Zeichen versetze. 0x40+0x20=0x60

Das sind nicht 32, sondern 96.

MfG Spess

von Nn N. (jaytharevo)


Lesenswert?

Darf ich fragen wie du auf die Zahl kommst?

von spess53 (Gast)


Lesenswert?

Hi

0x60 = 96D. Eigentlich sollte ich fragen, wie du auf diese Rechnung 
kommst. Der Offset der zweiten Zeile errechnet sich zur Adresse des 
ersten Zeichen der ersten Zeile. Und die ist normalerweise Null.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Julian Schild schrieb:
> Naja, das Problem ist eben, dass es nicht 0x40 ist. Wie oben eingestellt
> (lcd.h) funktioniert es leider nicht.
>
>
> Auch wenn ich es um die 32 Zeichen versetze. 0x40+0x20=0x60

Wenn in deinem jetztigen Header File 0x40 als Start der zweiten Zeile 
eingetragen ist, und du als Start aber 32 Zeichen festgestellt hast, 
dann trägst du natürlich auch nur 32 (oder eben 0x20) ein.

Das ist doch nicht so schwer
1
#define LCD_LINES           2     /**< number of visible lines of the display */
2
#define LCD_DISP_LENGTH     8     /**< visibles characters per line of the display */
3
#define LCD_LINE_LENGTH  0x20     /**< internal line length of the display    */
4
#define LCD_START_LINE1  0x00     /**< DDRAM address of first char of line 1 */
5
#define LCD_START_LINE2  0x20     /**< DDRAM address of first char of line 2 */
6
#define LCD_START_LINE3  0x14     /**< DDRAM address of first char of line 3 */
7
#define LCD_START_LINE4  0x54     /**< DDRAM address of first char of line 4 */
8
#define LCD_WRAP_LINES      0     /**< 0: no wrap, 1: wrap at end of visibile line */

LINE3 und LINE4 lass ich unangetastet, da sie nicht gebraucht werden.

von Nn N. (jaytharevo)


Lesenswert?

Hab deinen Code kopiert Heinz, macht absolut keinen Unterschied.
Aber eigentlich ist es ja nicht so tragisch, ich will jetzt keine 
Stunden deswegen investieren, dachte, dass es ein kleiner Denkfehler von 
mir war.

0x20 hatte ich natürlich auch schon probiert ;).

spess53 schrieb:
> 0x60 = 96D. Eigentlich sollte ich fragen, wie du auf diese Rechnung
> kommst. Der Offset der zweiten Zeile errechnet sich zur Adresse des
> ersten Zeichen der ersten Zeile. Und die ist normalerweise Null.

Auf die bin ich gekommen, da ich gedacht habe, das die Startadresse für 
die 2. Zeile zu gering ist. Der Versatz war 32 Zeichen (32=0x20) und, 
das hab ich dann einfach der Startadresse hinzu addiert.

von Karl H. (kbuchegg)


Lesenswert?

Julian Schild schrieb:
> Hab deinen Code kopiert Heinz, macht absolut keinen Unterschied.
> Aber eigentlich ist es ja nicht so tragisch, ich will jetzt keine
> Stunden deswegen investieren, dachte, dass es ein kleiner Denkfehler von
> mir war.

Dann hast du dich entweder irgendwo verzählt oder dein Testprogramm zur 
Feststellun des Offsets hat nicht so ganz geklappt.
Mit einem vernünftigen Teststring wäre es sooo viel einfacher gewesen.

Aber, wie stellst du eigentlich jetzt fest, dass es nicht klappt? 
(Progamm?)

Hast du im LCD Code nachgesehen, ob du dich um die Weiterschaltung in 
die 2.te Zeile kümmern musst, oder ob das die LCD-Lib macht, die du 
benutzt.

von Nn N. (jaytharevo)


Lesenswert?

In dem ich in der Ausgabe für die 2. Zeile immer noch 32 Zeichen 
einfügen muss bevor am Display, das aufscheint was ich eig haben will.

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

Programm.

Heinz, ich glaub du kennst mein Programm bald besser als ich :P.

von spess53 (Gast)


Lesenswert?

Hi

Wenn ich das richtig verstanden habe, hast du gestern schon Zeichen auf 
den rechten Teil der Zeile gehabt (Datum: 15.03.2010 23:04).
Warum hast du die nachfolgenden Ratschläge nicht befolgt?

Beschreibe einfach mal mit:

lcd_puts("00000000");
lcd_puts("11111111");
lcd_puts("22222222");
....
lcd_puts("99999999");

Aus dem, was dann in der rechten Hälfte steht kann man dann den Offset 
berechnen.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Julian Schild schrieb:
> Programm.
>
> Heinz, ich glaub du kennst mein Programm bald besser als ich :P.

Das ist die Fleury Lib.

Schalte den Wrap ein und die Library kümmert sich um den Umbruch 'in die 
nächste Zeile' (wenn die Abfrage vom LCD funktioniert, aber davon gehe 
ich mal aus)
1
#define LCD_WRAP_LINES      1     /**< 0: no wrap, 1: wrap at end of visibile line */


Hier ...
1
/*************************************************************************
2
Display character at current cursor position 
3
Input:    character to be displayed                                       
4
Returns:  none
5
*************************************************************************/
6
void lcd_putc(char c)
7
{
8
    uint8_t pos;
9
10
11
    pos = lcd_waitbusy();   // read busy-flag and address counter
12
    if (c=='\n')
13
    {
14
        lcd_newline(pos);
15
    }
16
    else
17
    {
18
#if LCD_WRAP_LINES==1
19
#if LCD_LINES==1
20
        if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
21
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
22
        }
23
#elif LCD_LINES==2
24
        if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
25
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);    
26
        }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ){
27
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
28
        }
29
#elif LCD_LINES==4
30
        if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
31
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);    
32
        }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ) {
33
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE3,0);
34
        }else if ( pos == LCD_START_LINE3+LCD_DISP_LENGTH ) {
35
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE4,0);
36
        }else if ( pos == LCD_START_LINE4+LCD_DISP_LENGTH ) {
37
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
38
        }
39
#endif
40
        lcd_waitbusy();
41
#endif
42
        lcd_write(c, 1);
43
    }
44
45
}/* lcd_putc */
... sind die entsprechenden Abfragen enthalten. Sie sind aber nur dann 
aktiv, wenn LCD_WRAP_LINES auf 1 steht

von Gasd (Gast)


Lesenswert?

Julian Schild schrieb:
> In dem ich in der Ausgabe für die 2. Zeile immer noch 32 Zeichen
> einfügen muss bevor am Display, das aufscheint was ich eig haben will.

So kann man das dann auch machen... ;-)

von Nn N. (jaytharevo)


Lesenswert?

1
#define LCD_LINES           2     /**< number of visible lines of the display */
2
#define LCD_DISP_LENGTH     8     /**< visibles characters per line of the display */
3
#define LCD_LINE_LENGTH  0x40     /**< internal line length of the display    */
4
#define LCD_START_LINE1  0x00     /**< DDRAM address of first char of line 1 */
5
#define LCD_START_LINE2  0x40     /**< DDRAM address of first char of line 2 */
6
#define LCD_START_LINE3  0x14     /**< DDRAM address of first char of line 3 */
7
#define LCD_START_LINE4  0x54     /**< DDRAM address of first char of line 4 */
8
#define LCD_WRAP_LINES      1     /**< 0: no wrap, 1: wrap at end of visibile line */
9
10
11
/* String auf Display anzeigen */
12
lcd_puts("Willkommen");
13
14
15
16
//Typkonvertierung für "lcd_puts"- Funktion
17
sprintf(cPuffer,"Verbrauch:%2d.%dW",usiPuffer1,usiPuffer2);
18
19
// Ausgabe am LCD
20
lcd_clrscr();        // LC-Display löschen und Kursor auf Pos. 1
21
lcd_puts(cPuffer);      // String am Display ausgeben



So, Wrap hat funktioniert, danke. Mit den obigen Einstellung 
funktioniert alles so wie es soll :).

spess53 schrieb:
> Warum hast du die nachfolgenden Ratschläge nicht befolgt?

Hatte ich doch, aber ob ich nun Zahlen oder mehrere "Willkommen" nehme 
ist im Prinzip egal ;).

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.