www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zweite Zeile LCD Display


Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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_...

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

// Definitionen
#ifndef F_CPU
#define F_CPU           3686400
#endif

int i=0;

int main(void) {
    // LCD Initialisieren
    lcd_initialisieren();

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


    // Programmende 
    return 0;
}

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

// Cursor Position setzen
void lcd_set_cursor(uint8_t zeile, uint8_t spalte) {
    // 1.Zeile
    if(zeile == 1) {
        lcd_command(0x80 + (spalte-1));
    }
    // 2.Zeile
    if(zeile >= 2) {
        lcd_command(0x80 + 0x40 + (spalte-1));
    }
} 

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

    // String zur Position senden
    lcd_string(string);
} 

Autor: tt2t (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: LCD (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es kann sein das die zweite Zeile garnicht Initialisiert wird.
Dies kann durch zukurze wartezeiten passieren.

Autor: immer_das_gleiche... (Gast)
Datum:

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

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

// Reset Zeiten    
#define lcd_reset_a     5      
#define lcd_reset_b     0.1
#define lcd_reset_c     5

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

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

// LCD Initialiseren
void lcd_initialisieren(void) {
    // Kurze einschaltpause
    _delay_ms(lcd_start_time);

    // Port einstellen
    lcd_port_ddr = 0b11111100;
    lcd_port     = 0x00;

    // LCD Resetten
    lcd_port |= lcd_reset;
    lcd_enable();
    _delay_ms(lcd_reset_a);
    
    lcd_enable();
    _delay_ms(lcd_reset_b);
    
    lcd_enable();
    _delay_ms(lcd_reset_c);

    // 4Bit Modus aktivieren
    lcd_port = lcd_modus;

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

    // Eingabemodus einstellen
    lcd_command(lcd_entry);

    // Display ausschalten
    lcd_command(lcd_off);

    // Display löschen
    lcd_command(lcd_clear);

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

Werde mal nebenbei bei Sprut schauen

Autor: LCD (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
immer_das_gleiche... schrieb:
> lcd_command(lcd_funktion);
>
>     // Eingabemodus einstellen
>     lcd_command(lcd_entry);

Versuch mal zwischen diesen beiden zeilen eine Pause zumachen zb 5ms.

Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Passiert leider nichts :(

Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also bei sprut bin ich nicht fündig geworden was meine situation ändern 
könnte :(

Autor: LCD (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird die zweite Zeile denn dunkel wenn du den Kontrast voll aufdrehst?

Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: tonia (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lcd_reset_b ist zu kurz

Autor: tonia (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:"

Autor: LCD (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
// Befehl zum LCD senden
void lcd_command(uint8_t command) {
    // Obere Bits schicken
    lcd_port = (command & 0xF0);
    lcd_enable();
    
    // Untere Bits schicken
    lcd_port = (command << 4) & 0xF0;
    lcd_enable();

    // Kurze Pause
    _delay_ms(lcd_cmd_time);
}

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

Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich muss aber noch dazu sagen, dass ich den cursor und sowas ändern 
kann. also sollten ja beide nibbel komplett übertragen werden :/

Autor: usuru (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define lcd_modus       0b01000000  // 4Bit Modus --- Deine Einstellung
---------------------------^

#define lcd_modus       0b00100000  // 4Bit Modus --- gefällt mit eher
----------------------------^

Autor: immer_das_gleiche... (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: usuru (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: immer_das_gleiche... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat jemand denn jemand einen anderen ansatz für die initialisierung? 
evtl. eine checkliste die ich durchgehen kann?

Autor: su (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
immer_das_gleiche... schrieb:
> 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.

lg

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

Aber nicht bei dem o.g. Display (S.10):
http://www.myavr.info/download/produkte/lcd/techb_...

MfG Spess

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber nicht bei dem o.g. Display (S.10):
> http://www.myavr.info/download/produkte/lcd/techb_...

das scheint mir ein Fehler in diesem Datenblatt zu sein. So einen
Controller habe ich noch nie gesehen.
Die mir bekannten Controller können alle 80 Zeichen verwalten, weshalb
die 2. Zeile bei 40 anfängt. Die 0x40 halte schlicht für falsch.

Thomas

Autor: Rene K. (draconix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht 0x40 sondern 0x28 was int 40 entspricht ;)

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Nicht 0x40 sondern 0x28 was int 40 entspricht ;)

ich bin ja deiner Meinung und hatte das auch so geschrieben nur im 
zitierten Datenblatt steht eben 40h.

Thomas

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Die 0x40 halte schlicht für falsch.

Stimmt aber für fast alle Displays, die ich kenne.

Sieh dir mal S.5 an:

http://www.lcd-module.de/pdf/doma/2_20.pdf

MfG Spess

Autor: immer_das_gleiche (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
void lcd_display_reset(unsigned int time) {
    lcd_port = lcd_reset;
    lcd_enable();
    _delay_ms(time);
}

// LCD Initialiseren
void lcd_initialisieren(void) {
    // Kurze einschaltpause
    _delay_ms(lcd_start_time);
    
    // Port einstellen
    lcd_port_config();

    // LCD Resetten
    lcd_display_reset(lcd_reset_a);
    lcd_display_reset(lcd_reset_b);
    lcd_display_reset(lcd_reset_c);

    // 4Bit Modus aktivieren
    lcd_command(lcd_modus);
    _delay_ms(lcd_modus_time);

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

    // Display ausschalten
    lcd_command(lcd_off);

    // Display löschen
    lcd_display_clear();

    // Eingabemodus einstellen
    lcd_command(lcd_entry);

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

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?

Autor: Serieller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja. Steht in der FAQ bzw. in der Doku der Delay-Funktionen der avr-libc. 
Man darf nur eine Konstante als Argument übergeben, keine Variablen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.