Zweite Zeile LCD Display

Gast #2066077
Lesenswert?

Hallo Leute,
bin seit geraumer Zeit mit dem AVR GCC Tutorial beschäftigt und dabei 
eine Library für mein LCD zu schreiben.
Ich möchte keine fertige nehmen, der Lerneffekt ist beim selber machen 
größer :)

Problem ist nun das ich keine Buchstaben in die zweite Zeile bekomme ... 
sobald ich die Adresse auf 0x40 setze kommt nichts. Ich muss aber dazu 
sagen, dass es ohne Probleme Funktioniert, einen String an eine 
bestimmten Stelle in der 1.Zeile zu schreiben.

Ja habe die Forensuche benutzt und bin auf keine passende Antwort 
gestoßen :(

Ich benutze das myAVR Board LPT mit dem Display Add-on.
http://www.myavr.info/download/produkte/lcd/techb_lcd_de_en.pdf

Hier ist mal ein Ausschnitt aus dem Code:
Hauptprogramm:
1
// Bibliotheken
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <stdint.h>
5
#include "myavr_lcd.h"
6

7
// Definitionen
8
#ifndef F_CPU
9
#define F_CPU           3686400
10
#endif
11

12
int i=0;
13

14
int main(void) {
15
    // LCD Initialisieren
16
    lcd_initialisieren();
17

18
    // LCD Ausgabe
19
    lcd_set_string(2,1,"blub");
20

21

22
    // Programmende 
23
    return 0;
24
}

Auschnitt aus der Library:
1
// String zur aktuellen Cursor Position senden
2
void lcd_string(const char *string) {
3
    // String zerlegen und schicken
4
    while(*string != '\0')
5
        lcd_data(*string++);
6
}
7

8
// Cursor Position setzen
9
void lcd_set_cursor(uint8_t zeile, uint8_t spalte) {
10
    // 1.Zeile
11
    if(zeile == 1) {
12
        lcd_command(0x80 + (spalte-1));
13
    }
14
    // 2.Zeile
15
    if(zeile >= 2) {
16
        lcd_command(0x80 + 0x40 + (spalte-1));
17
    }
18
} 
19

20
// String zu einer definierten Position schicken
21
void lcd_set_string(uint8_t zeile, uint8_t spalte, const char *string) {
22
    // Cursor Position festlegen
23
    lcd_set_cursor(zeile,spalte);
24

25
    // String zur Position senden
26
    lcd_string(string);
27
}
Gast #2066113
Lesenswert?

Also dann scheinen meine Unterprogramme ok zu sein.
Habe die Wartezeiten mal erhöht aber der Effekt ändert nichts.

Wartezeiten
1
/////////////////////////////////////////////////////////////////////
2
/*                    LCD PAUSEN ZEITEN (in ms)                    */
3
/////////////////////////////////////////////////////////////////////
4
#define lcd_en_time     6           // Enable Zeit
5
#define lcd_start_time  50          // Hochfahrzeit
6
#define lcd_cmd_time    2           // Befehlszeit
7
#define lcd_data_time   0.5         // Datenzeit
8

9
// Reset Zeiten    
10
#define lcd_reset_a     5      
11
#define lcd_reset_b     0.1
12
#define lcd_reset_c     5

Initialisierung & Befehle
1
/////////////////////////////////////////////////////////////////////
2
/*                          LCD BEFEHLE                            */
3
/////////////////////////////////////////////////////////////////////
4
#define lcd_reset       0b00110000  // Software Reset
5
#define lcd_modus       0b01000000  // 4Bit Modus
6
#define lcd_funktion    0b00101000  // 4Bit Modus, 2Zeile, 5x7Dots
7
#define lcd_entry       0b00000110  // Cursor increase, Display not shifted
8
#define lcd_off         0b00001000  // Display aus
9
#define lcd_on          0b00001100  // Display ein, Cursor aus, Cursor blink aus
10
#define lcd_clear       0b00000001  // Display löschen
11

12
#define lcd_ddram       0x80  // Benötigt um DDRAM Adresse zu setzen
13
#define lcd_ddram_2     0x40  // Adresse der zweiten Zeile
14

15
// LCD Initialiseren
16
void lcd_initialisieren(void) {
17
    // Kurze einschaltpause
18
    _delay_ms(lcd_start_time);
19

20
    // Port einstellen
21
    lcd_port_ddr = 0b11111100;
22
    lcd_port     = 0x00;
23

24
    // LCD Resetten
25
    lcd_port |= lcd_reset;
26
    lcd_enable();
27
    _delay_ms(lcd_reset_a);
28
    
29
    lcd_enable();
30
    _delay_ms(lcd_reset_b);
31
    
32
    lcd_enable();
33
    _delay_ms(lcd_reset_c);
34

35
    // 4Bit Modus aktivieren
36
    lcd_port = lcd_modus;
37

38
    // Display einstellen (2 Zeilen, 5x7 Dots, 4Bit Modus)
39
    lcd_command(lcd_funktion);
40

41
    // Eingabemodus einstellen
42
    lcd_command(lcd_entry);
43

44
    // Display ausschalten
45
    lcd_command(lcd_off);
46

47
    // Display löschen
48
    lcd_command(lcd_clear);
49

50
    // Display einschalten und Cursor einstellen
51
    lcd_command(lcd_on);  
52
}

Werde mal nebenbei bei Sprut schauen
Gast #2066175
Lesenswert?

also sollange etwas in der ersten zeile dargestellt wird und ich dann am 
kontrast regler spiele. wird nur die erste zeile dunkel.

sieht wohl so aus als ob da was falsch initialisiert wird... oder irre 
ich mich?
Gast #2066188
Lesenswert?

wenn Du im 4-bit-Modus bist, musst Du immer 2x4 Bit (HI-LO) übertragen, 
damit der Befehl komplett ist. Du übeträgst nur 1x 4 Bit.

Steht alles bei sprut unter "Beispiel für eine Initialisierung mit 4-Bit 
Interface:"
Gast #2066189
Lesenswert?

Wenn das LCD richtig Initialisiert ist werden beide Zeilen dunkel wenn 
man mehr Kontrast reingibt. So wie das bei dir ausieht kann es durchaus 
an der Initialisierung liegen zB das die delays zu kurz sind.
Gast #2066208
Lesenswert?

Danke schonmal soweit, habe die Zeiten mal geändert und es hat sich 
soweit auch nichts geändert.

Das einzigste was ich noch vermuten könnte ist das meine lcd_command(); 
funktion nicht ganz richtig ist.
1
// Befehl zum LCD senden
2
void lcd_command(uint8_t command) {
3
    // Obere Bits schicken
4
    lcd_port = (command & 0xF0);
5
    lcd_enable();
6
    
7
    // Untere Bits schicken
8
    lcd_port = (command << 4) & 0xF0;
9
    lcd_enable();
10

11
    // Kurze Pause
12
    _delay_ms(lcd_cmd_time);
13
}

Wobei ich mich frage, wenn das LCD doch nicht richtig initialisiert ist, 
dann sollte es doch gar nichts darstellen oder?
Gast #2066245
Lesenswert?

usuru schrieb:
> #define lcd_modus       0b01000000  // 4Bit Modus --- Deine Einstellung
>
> ---------------------------^
>
>
>
> #define lcd_modus       0b00100000  // 4Bit Modus --- gefällt mit eher
>
> ----------------------------^

danke, habe es geändert. leider funzt das auch nicht :(

habe aber nochmal den kompletten code angehangen. die reset zeiten habe 
ich mal an die aus dem LCD Tutorial angepasst.
Angehängte Dateien:
Gast #2066266
Lesenswert?

#define lcd_reset_a     5
#define lcd_reset_b     1
#define lcd_reset_c     1

viele Displays brauchen längere Delays (manche aus kürzere). Mach das 
alles mal mindestens 10 msec lang. LCD-Displays sind keine Ferraris, 
sondern eher Fussgänger ...

Probier mal folgende Muster, damit initialisiere ich immer:

b'00110000'  ; 8-bit-interface
b'00110000'  ; 8-bit-interface
b'00110000'  ; 8-bit-interface
b'00100000'  ; 4-bit-interface
b'00101000'  ; 4-bit  2-zeilig  5x8
b'00000110'  ; cursor increase, display shifted
b'00001100'  ; display on
b'00000001'  ; löschen, cursor home
Gast #2066283
Lesenswert?

mit den 10ms klappt es auch nicht :(
also laut der myavr anleitung sind die pausenzeiten
1. 5ms
2. 100us
3. 5ms
habe die anleitung auch schon 1 zu 1 gemacht aber es ist immer nur die 
1. zeile aktiv.
kaputt ist das display auch nicht, das test programm läuft.

deine reihenfolge ändert auch nichts an dem sachverhalt.
langsam verzweifel ich
Gast #2092651
Lesenswert?

>> Problem ist nun das ich keine Buchstaben in die zweite Zeile bekomme ...
>>
>> sobald ich die Adresse auf 0x40 setze kommt nichts.

> ich verwende die Adresse für zweite Zeile 0x20, und erste Zeile 0x00.

richtige Spur aber flasche Zahl: Die 2. Zeile wird mit 0x28 erreicht was
dez der pos 40 entspricht


Thomas
Gast #2095831
Lesenswert?

so da bin ich wieder :D

also bei dem display ist die adresse 0x40.
das problem mit der zweiten zeile habe ich gelöst, in der 
initialisierung musste einfach hinter dem befehl lcd_command(lcd_modus); 
noch eine kurze wartezeit von 5ms ergänzt werden.

nun habe ich aber noch ein anderes problem, um den code übersichtlicher 
zu machen habe ich eine unterfunktion ergänzt
1
void lcd_display_reset(unsigned int time) {
2
    lcd_port = lcd_reset;
3
    lcd_enable();
4
    _delay_ms(time);
5
}
6

7
// LCD Initialiseren
8
void lcd_initialisieren(void) {
9
    // Kurze einschaltpause
10
    _delay_ms(lcd_start_time);
11
    
12
    // Port einstellen
13
    lcd_port_config();
14

15
    // LCD Resetten
16
    lcd_display_reset(lcd_reset_a);
17
    lcd_display_reset(lcd_reset_b);
18
    lcd_display_reset(lcd_reset_c);
19

20
    // 4Bit Modus aktivieren
21
    lcd_command(lcd_modus);
22
    _delay_ms(lcd_modus_time);
23

24
    // Display einstellen (2 Zeilen, 5x7 Dots, 4Bit Modus)
25
    lcd_command(lcd_funktion);
26

27
    // Display ausschalten
28
    lcd_command(lcd_off);
29

30
    // Display löschen
31
    lcd_display_clear();
32

33
    // Eingabemodus einstellen
34
    lcd_command(lcd_entry);
35

36
    // Display einschalten und Cursor einstellen
37
    lcd_command(lcd_on);  
38
}

sollange die funktion lcd_display_reset(); eingebaut ist, ist der code 
bei knapp 50% speichergröße des mega8.
die größe steigt erst von 5% auf 50%, sobald man in das _delay_ms(); die 
variable "time" einfügt.
gibt es dafür einen bestimmen grund?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren