Forum: Mikrocontroller und Digitale Elektronik LCD2004 Zeilenumbruch


von Bernd (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit einer angepassten Lib von Fleury und dem 
LCD2004. Ich habe es mit 2 verschiedenen getestet
QC2004A
http://site.gravitech.us/MicroResearch/Others/LCD-20x4B/HD44780.pdf

J204A
http://www.systronix.com/access/Systronix_20x4_lcd_brief_data.pdf
1
#define LCD_WRAP_LINES  0
2
3
LCD_START_LINE1     0x00
4
LCD_START_LINE2     0x40
5
LCD_START_LINE3     0x14
6
LCD_START_LINE4     0x54

Abweichende Adressen habe ich nicht gefunden.
Das ansteuern über lcd_gotoxy geht richtig!

1) Versuch
1
/*
2
#define LCD_WRAP_LINES  0
3
*/
4
5
  lcd_clrscr();
6
  lcd_home();
7
8
  char buf[] = "00000000000000000000\n11111111111111111111\n22222222222222222222\n33333333333333333333";
9
  char ic = 0;
10
11
    while (buf[ic] != '\0') {
12
    
13
    lcd_putc(buf[ic++]);
14
    gpioDelay(150000);
15
  }

Ausgabe auf dem Display
Beginnt in Zeile 1 und schreibt durchgehend 0, danach geht es in Zeile 
4(!) und schreibt hier durchgehend 1.
Schreibt in die 2. Zeile 2 und danach schreibt er 3 über die 0 aus Zeile 
1

2) Versuch
Ich nehme aus char buf[] jeweils eine Zahl raus, so dass es pro Zeile 19 
Zeichen sind.
Hier wird alles korrekt ausgegeben, nur dass halt das Letzte Zeichen 
jeder Zeile nichts anzeigt (logisch bei 19 Zeichen)

3) Versuch
Nun aufbauen auf Versuch 2 jedoch mit #define LCD_WRAP_LINES 1
Nun wird Zeile 1 mit 0 gefüllt und Zeile 2 mit 1 gefüllt. Alle weiteren 
Zeichen werden in Zeile 2 geschrieben

4) Versuch
Nun wie in Versuch 3 aber ohne Linefeed.
Er schreibt in die 1. Zeile 0 bis auf das letzte Zeichen, dieses ist die 
erste 1. Das läuft alle korrekt bis zu Zahl 2 in Zeile 3. Mit der Zahl 3 
springt er wieder in der ersten Zeile und überschreibt diese.


Könnte jetzt noch weitere Test ausführen, aber ich komme nicht auf einen 
guten Nenner.

Was gewünscht ist:
Wenn String länger ist als die Zeile (20 Zeichen) soll er in die nächste 
optische Zeile (nicht intern) springen und weiterschreiben.
Kommt ein \n vor, soll er ebenfalls in die nächste optische Zeile 
wechseln.

Hat jemand solche Probleme schon gehabt?

von Joachim B. (jar)


Lesenswert?

Bernd schrieb:
> Kommt ein \n vor, soll er ebenfalls in die nächste optische Zeile
> wechseln.
>
> Hat jemand solche Probleme schon gehabt?

nicht wirklich

/n ist ein nicht printzeichen und muss raus, der Rest ist deine 
Programmiersache, die 40 Zeichen richtig zu verteilen und zwar für alle 
isprint() Zeichen solange dein LCD diese Zeichen kennt, wenn nicht sind 
die untersten 07 Char frei selber welche zu definieren und entsprechend 
zu ersetzen, gerne auch mal ÄÖÜäöüß oder °

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd schrieb:
> Beginnt in Zeile 1 und schreibt durchgehend 0, danach geht es in Zeile
> 4(!) und schreibt hier durchgehend 1.

 20 mal die Null (0x00 - 0x13), nächstes Zeichen geht auf die Adresse
 0x14, das ist in Zeile 3, aber da kommt "\n" und Fleury geht in die
 nächste Zeile, und das ist die Zeile 4.

 Was wundert dich daran ?

von Bernd (Gast)


Lesenswert?

Hallo Joachim, das '\n' auf den LCDs nicht angezeigt wird, bzw nur als 
komisches Sonderzeichen, ist mir bewusst, das wird ja auch abgefangen.
1
void lcd_putc(char c) {
2
  uint8_t pos = lcd_waitbusy();   // read busy-flag and address counter
3
  if (c == '\n') {
4
    lcd_newline(pos);
5
  }
6
  else {
7
    lcd_write(c, 1);
8
  }
9
}/* lcd_putc */

Hallo Marc,
die von dir angedeutete Logik geht in diesem Funktionen aber so meiner 
Meinung nach nicht auf.


Soll Ausgabe werden, ohne dass die Zeile unterbrochen wird.
1
void lcd_putc(char c) {
2
  uint8_t pos = lcd_waitbusy();   // read busy-flag and address counter
3
  if (c == '\n') {
4
    lcd_newline(pos);
5
  }
6
  else {
7
    lcd_write(c, 1);
8
  }
9
}/* lcd_putc */
10
11
/* print string on lcd (no auto linefeed) */
12
void lcd_puts(const char *s) {
13
  while (*s != '\0') {
14
    lcd_putc(*s++);
15
  }
16
17
}/* lcd_puts */


Bei dieser Variante wird der Text in die nächste Zeile verlagert-
1
void lcd_putc_lf(char c)
2
{
3
  uint8_t pos;
4
5
  pos = lcd_waitbusy();   // read busy-flag and address counter
6
  if (c == '\n')
7
  {
8
    lcd_newline(pos);
9
  }
10
  else
11
  {
12
#if LCD_LINES==1
13
    if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) {
14
      lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0);
15
    }
16
#elif LCD_LINES==2
17
    if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) {
18
      lcd_write((1 << LCD_DDRAM) + LCD_START_LINE2, 0);
19
    }
20
    else if (pos == LCD_START_LINE2 + LCD_DISP_LENGTH){
21
      lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0);
22
    }
23
#elif LCD_LINES==4
24
    if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) {
25
      lcd_write((1 << LCD_DDRAM) + LCD_START_LINE2, 0);
26
    }
27
    else if (pos == LCD_START_LINE2 + LCD_DISP_LENGTH) {
28
      lcd_write((1 << LCD_DDRAM) + LCD_START_LINE3, 0);
29
    }
30
    else if (pos == LCD_START_LINE3 + LCD_DISP_LENGTH) {
31
      lcd_write((1 << LCD_DDRAM) + LCD_START_LINE4, 0);
32
    }
33
    else if (pos == LCD_START_LINE4 + LCD_DISP_LENGTH) {
34
      lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0);
35
    }
36
#endif
37
    lcd_waitbusy();
38
    lcd_write(c, 1);
39
  }
40
}
41
42
void lcd_puts_lf(const char *s) {
43
  while (*s != '\0') {
44
    lcd_putc_lf(*s++);
45
  }
46
} /* lcd_puts */

von Bernd (Gast)


Lesenswert?

Hab noch einmal etwas umgebaut und mit Seriellen Ausgaben überprüft, wo 
der Fehler sein kann.

1
void lcd_putc_lf(char c) {
2
  uint8_t pos = lcd_waitbusy();   // read busy-flag and address counter
3
4
  if (pos == LCD_START_LINE1 + LCD_DISP_LENGTH) {         // 0x00 ... 0x13
5
    printf("__2\t");                                    // 0 - 19
6
    lcd_write((1 << LCD_DDRAM) + LCD_START_LINE2, 0);
7
  }
8
  else if (pos == LCD_START_LINE2 + LCD_DISP_LENGTH) {    // 0x40 .. 0x53
9
    printf("__3\t");                                    // 64 - 83
10
    lcd_write((1 << LCD_DDRAM) + LCD_START_LINE3, 0);
11
  }
12
  else if (pos == LCD_START_LINE3 + LCD_DISP_LENGTH) {    // 0x14 ... 0x23
13
    printf("__4\t");                                    // 20 - 39
14
    lcd_write((1 << LCD_DDRAM) + LCD_START_LINE4, 0);
15
  }
16
  else if (pos == LCD_START_LINE4 + LCD_DISP_LENGTH) {    // 0x54 ... 0x63
17
    printf("_1\t");                                     // 84 - 103
18
    lcd_write((1 << LCD_DDRAM) + LCD_START_LINE1, 0);
19
  }
20
  printf("\t");
21
  printf("%03i", pos);
22
  printf("\n");
23
  lcd_waitbusy();
24
  lcd_write(c, 1);
25
}

eingekürtz
1
        000
2
        ...
3
        019
4
__2             020
5
        065
6
        ...
7
        083
8
__3             084
9
        021
10
        022
11
        023
12
        024
13
        025
14
        026
15
        027
16
        028
17
        029
18
        030
19
        031
20
        032
21
        033
22
        034
23
        035
24
        036
25
        037
26
        038
27
        039
28
        064
29
        065
30
        066
31
        067
32
        068
33
        069
34
        070
35
        071
36
        072
37
        073
38
        074
39
        075
40
        076
41
        077
42
        078
43
        079
44
        080
45
        081
46
        082
47
        083
48
__3             084
49
        021
50
        022
51
        023
52
        024
53
        025
54
        026
55
        027
56
        028
57
        029
58
        030
59
        031
60
        032
61
        033
62
        034
63
        035
64
        036
65
        037
Er hätte bei der Zahl 39 einen Sprung (__x) ausgeben müssen, was er aber 
NICHT macht. Die Zahl selber springt aber -.-

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.