www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik mal wieder ein LCD am Atmega8


Autor: Adi A. (mateit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

es tut mir leid, dass ich einen Thread zum Thema LCD am Atmega8 
schreiben muss, aber leider konnte mir bisher kein Thread aus dem Forum 
hier helfen.

Ich besitze ein LCD-Modul BATRON BTHQ22005VSS-13 von Pollin 
(http://www.pollin.de/shop/dt/MjgzOTc4OTk-/Baueleme...), 
auf dem Modul ist ein KS0070BP-00CC Controller.

Folgendermaßen habe ich das LCD angeschlossen:
VSS          gnd
VDD          5V
V0           an einem Poti
Ich möchte das LCD im 4bit Modus ansteuern.
Daher:
DB4          PC0
DB5          PC1
DB6          PC2
DB7          PC3
EN           PC4
RS           PC5
R/W          auf gnd gezogen

Die lcd.h und lcd.c habe ich von Peter Fleury. Die lcd.h habe ich 
folgendermaßen angepasst:
#define XTAL 125000  
           
#define LCD_CONTROLLER_KS0073 0  
#define LCD_LINES           2     
#define LCD_DISP_LENGTH    20    
#define LCD_LINE_LENGTH  0x40    
#define LCD_START_LINE1  0x00    
#define LCD_START_LINE2  0x40    
#define LCD_START_LINE3  0x14     
#define LCD_START_LINE4  0x54     
#define LCD_WRAP_LINES      0     

#define LCD_IO_MODE      1         

#if LCD_IO_MODE

#define LCD_PORT         PORTC       
#define LCD_DATA0_PORT   LCD_PORT     
#define LCD_DATA1_PORT   LCD_PORT     
#define LCD_DATA2_PORT   LCD_PORT     
#define LCD_DATA3_PORT   LCD_PORT     
#define LCD_DATA0_PIN    0            
#define LCD_DATA1_PIN    1            
#define LCD_DATA2_PIN    2           
#define LCD_DATA3_PIN    3            
#define LCD_RS_PORT      LCD_PORT     
#define LCD_RS_PIN       5            
#define LCD_RW_PORT      PORTB   
#define LCD_RW_PIN       6            
#define LCD_E_PORT       LCD_PORT      
#define LCD_E_PIN        4   

Da ich R/W auf gnd gezogen habe, habe ich hier einen Pin gewählt der 
ebenfalls auf 0V liegt.

Ich programmiere mit dem AVR Studio und als Programmer nutze ich USBProg 
mit einem vorinstalliertem AVRISP MKII Klon.


Nun zum Programm:
#include <stdlib.h>
#include <avr/io.h>
#include "lcd.h"
#include <util/delay.h>

int main(void)
{
  DDRD = 0xFF;
  PORTD = ( 1 << DDD0 | 1 << DDD1 | 1 << DDD2 | 1 << DDD3);
  
  DDRC = 0xFF;


    /* initialize display, cursor off */
    lcd_init(LCD_DISP_ON);

  _delay_ms(50);

    for (;;) {                           /* loop forever */
 
    /* loesche das LCD Display und Cursor auf 1 Zeile, 1 Spalte */
    lcd_clrscr();
        
    /* String auf Display anzeigen */
    lcd_puts("Hello world.");
             
    }
}
(An PORTD liegen LEDs - ich wollte nur sehen, ob sich überhaupt was tut)

Kombilieren funktioniert genauso wie das Flashen ohne Probleme.
Allerdings sehe ich nix auf dem LCD..

Was mache ich falsch?
Wäre schön wenn jemand über diesen Roman drüber schauen würde ;)


Danke schon im Voraus.


beste Grüße

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. Q. schrieb:
> #define XTAL 125000

sehr niedrige Frequenz!?

Autor: Adi A. (mateit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huch das ging aber schnell ;)

Ulf Rolf schrieb:
> M. Q. schrieb:
>> #define XTAL 125000
>
> sehr niedrige Frequenz!?

Habe die Frequenz mal hochgestellt.
#define XTAL 8000000
funktioniert aber dennoch nicht.

Gruß

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. Q. schrieb:

> R/W          auf gnd gezogen

Das geht mit der originalen Fleury-Lib nicht, weil die das Busy-Bit 
auswerten möchte.

Autor: Wayne Monga (vibra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin

Ich kenn die lib von fleury leider nicht :( und hab auch keine Lust mir 
das reinzuziehen ,aber ich kann dir nur den Tip geben das 
Initialisierungsschema mal mit folgendem Ablauf zu vergleichen.
LCD_init:     
;**** for the most LCD you must write 3times a dummy command before you change to 4Bit***

  
  ldi  temp, 0b00001110  ;control lines are output, rest is input
  out  DDRD, temp
  
  rcall  LCD_delay    ;first, we'll tell the LCD that we want to use it
  ldi  arg, 0x20      ;in 4-bit mode.
  rcall  LCD_command8    ;LCD is still in 8-BIT MODE while writing this command!!!

  rcall  LCD_delay
  ldi  arg, 0x20    ;NOW: 2 lines, 5*7 font, 4-BIT MODE!     ** DUMMY ***
  rcall  LCD_command    ;
  
  rcall  LCD_wait
  ldi  arg, 0x20    ;NOW: 2 lines, 5*7 font, 4-BIT MODE!     ** DUMMY ***
  rcall  LCD_command    ;

  rcall  LCD_wait
  ldi  arg, 0x28    ;NOW: 2 lines, 5*7 font, 4-BIT MODE!     ** this change to 4bit 2 lines **
  rcall  LCD_command    ;after this point you don't can change anything 'show HD44780 Datasheet'

Autor: Adi A. (mateit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo vibra,

Wayne Monga schrieb:
> moin
>
> Ich kenn die lib von fleury leider nicht :( und hab auch keine Lust mir
> das reinzuziehen

kann ich gut verstehen ;)


Ich kann zwar kein ASM, aber ich kann Kommentare lesen ;)
In Peter Fleury's lcd.c steht dazu folgendes:
 /* initial write to lcd is 8bit */
    LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);  // _BV(LCD_FUNCTION)>>4;
    LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);  // _BV(LCD_FUNCTION_8BIT)>>4;
    lcd_e_toggle();
    delay(4992);         /* delay, busy flag can't be checked here */
   
    /* repeat last command */ 
    lcd_e_toggle();      
    delay(64);           /* delay, busy flag can't be checked here */
    
    /* repeat last command a third time */
    lcd_e_toggle();      
    delay(64);           /* delay, busy flag can't be checked here */

    /* now configure for 4bit mode */
    LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);   // LCD_FUNCTION_4BIT_1LINE>>4
    lcd_e_toggle();
    delay(64);           /* some displays need this additional delay */

das sollte dem obigen ASM Befehlen entsprechen.


Gruß

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wayne Monga schrieb:

> ;**** for the most LCD you must write 3times a dummy command before you
> change to 4Bit***

Es ist extrem verwunderlich, welche Blüten diese Initialisierungsroutine 
und ihre Begründung trägt. Man könnte den Eindruck gewinnen, LCDs seien 
irgendwie schwerhörig und lassen sich erst mit mehreren Tritten in den 
Hintern zu einem Interfacewechsel bewegen.

Dem ist überhaupt nicht so. Es geht hier um eine 
100%-Foolproof-Initialisierung, die auch bei beliebiger Vorgeschichte 
(zufällige Eingaben auf dem Bus) das LCD in einen definierten Zustand 
versetzt.

Ein LCD mit 4 Drähten kann zu jedem Zeitpunkt in einem der folgenden 
vier Zustände sein:

* 8BIT: Es ist im 8-Bit-Modus

* 4BIT_HI: Es ist im 4-Bit-Modus und wartet auf das Hi-Nibble

* 4BIT_LO8: Es ist im 4-Bit-Modus, wartet auf das Lo-Nibble, hat aber im 
gerade empfangenen Hi-Nibble den Umschaltbefehl auf 8-Bit-Modus erhalten

* 4BIT_LO: Es ist im 4-Bit-Modus, wartet auf das Lo-Nibble, und das 
gerade empfangene Hi-Nibble enthält nicht diesen Umschaltebefehl

Jetzt malt man einfach ein Zustandsdiagramm
Zustand    Folgezustand bei 0x02    Folgezustand bei 0x03
-----------------------------------------------------------
8BIT           4BIT_HI                  8BIT
4BIT_HI        4BIT_LO                  4BIT_LO8
4BIT_LO        4BIT_HI                  4BIT_HI
4BIT_LO8       8BIT                     8BIT

Wenn man nun nur den Befehl 0x02 (auch wiederholt) schicken würde, 
könnte man auch nach 29 Wiederholungen nicht mit Sicherheit sagen, ob 
das Display im Zustand 4BIT_LO oder 4BIT_HI ist, und eine zuverlässige 
Initialisierung ist nicht möglich.

Man muss also zwingend zwischenzeitlich in den 8BIT-Modus schalten. 
Damit dies sicher passiert, muss dreimal 0x03 geschickt werden: Falls 
das Display zufällig im Zustand 4BIT_LO war, durchläuft es dabei die 
Zustände 4BIT_HI, 4BIT_LO8 und erreicht schließlich 8BIT. In allen 
anderen Fällen wird der Zustand 8BIT schon früher erreicht und bei 0x03 
dann beibehalten.

Nun ist man also definitiv im Zustand 8BIT und kann mit 0x02 in den 
4-Bit-Modus wechseln.

Wenn man der Stromversorgung traut, dann kann man sich den ganzen Kram 
auch sparen, weil das Display von selbst in den 8-Bit-Modus hochfährt.

Autor: Adi A. (mateit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ulf Rolf schrieb:
> M. Q. schrieb:
>
>> R/W          auf gnd gezogen
>
> Das geht mit der originalen Fleury-Lib nicht, weil die das Busy-Bit
> auswerten möchte.


Entschuldige Ulf. Das habe ich gerade eben erst entdeckt.
Welche Alternative/n kann ich nutzen?

Danke bis hier hin schon mal!


Gruß

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. Q. schrieb:

> Entschuldige Ulf. Das habe ich gerade eben erst entdeckt.
> Welche Alternative/n kann ich nutzen?

RW anschließen.

Oder andere Lib verwenden.

Oder selber schreiben.

Oder aber für ein erstes Weiterkommen "Speichern als..." > "mqlcd.c" und 
beherzt geändert. Die Routine, welche das Busy-Bit auswertet, kann auch 
einfach 60us warten. Es gibt nur zwei Befehle, die deutlich längere 
maximale Verarbeitungszeit (2ms) haben: CLEAR und HOME; dafür musst Du 
halt auch noch ein Delay einbasteln.

Autor: Hubert G. (hubertg)
Datum:
Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
Es macht nicht sehr viel Sinn, R/W auf einen Pin zu legen der 0V hat. Es 
wäre es besser diesen gleich zu aktivieren.
Ich lege R/W immer auf GND, der Geschwindigkeitsunterschied ist nicht 
erkennbar und ich spare diesen Pin für anderes.
Du solltest auch #define LCD_CONTROLLER_KS0073 0  auf 1 geben.
In der lib im Anhang kannst du einstellen ob mit oder ohne R/W.

Autor: Adi A. (mateit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hubert G. schrieb:
> Es macht nicht sehr viel Sinn, R/W auf einen Pin zu legen der 0V hat. Es
> wäre es besser diesen gleich zu aktivieren.
> Ich lege R/W immer auf GND, der Geschwindigkeitsunterschied ist nicht
> erkennbar und ich spare diesen Pin für anderes.
> Du solltest auch #define LCD_CONTROLLER_KS0073 0  auf 1 geben.
> In der lib im Anhang kannst du einstellen ob mit oder ohne R/W.

Hallo Hubert,

genauso mache ich es auch! Ich lege R/W auf meiner Platine direkt auf 
GND.
Da ich in der alten lcd.h allerdings einen Pin angeben musste, an dem 
R/W liegt, habe ich einen ausgewählt, der auf 0V liegt.

Ich muss feststellen, dass das "Hello World." auf dem Display sehr gut 
aussieht! Soll heißen: ES FUNKTIONIERT.

Vielen Dank an alle, die mir meinem Nachmittag doch noch gerettet haben!



Mit besten Grüßen

mateit

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab mal gerade den Display angeschlossen. Sehe ich das Richtig:

Bezogen auf: lcd_new.c & lcd_new.h

VSS          gnd
VDD          5V
V0           Poti

DB0          NC
DB1          NC
DB2          NC
DB3          NC

DB4          PC2
DB5          PC3
DB6          PC4
DB7          PC5
EN           PC0
RS           PC1
R/W          GND

#define F_CPU 8000000L

#define LCD_CONTROLLER_KS0073  1
#define LCD_LINES              2
#define LCD_DISP_LENGTH       20

int main(void)
{
    DDRC = 0xFF;


    lcd_init(LCD_DISP_ON);

    _delay_ms(50);

    for (;;) {

    lcd_clrscr();
    lcd_puts("Hello");

    }
}


Ich bekomme nur einen weißen Balken in der ersten Zeile.

Was mach ich Falsch / Was habe ich vergessen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Paul schrieb:

> #define F_CPU 8000000L
>
> #define LCD_CONTROLLER_KS0073  1
> #define LCD_LINES              2
> #define LCD_DISP_LENGTH       20


Was hast du mit
LCD_READ_REQUIRED
gemacht?

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist auch auf 0 gesetzt.

Autor: Hubert G. (hubertg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hast du für einen Kontroller und wie ist die ganze Beschaltung. 
Vielleicht kannst du die ganze Schaltung posten.

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ist ein Atemga8 auf einem STK500. Die beschalteten Pins stehen im 
Beitrag oben. Mehr ist da an sich nicht.

Die +5V und GND kommen von einer externen Quelle, die durch einen 
5V-Spannungsregler geregelt wird.

Kann es vielleicht was damit zu tun haben, dass ich die +5V von STK500 
holen muss?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Nein, aber die Masse.

MfG Spess

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte mal jemand einen funktionierenden bsp. Code und ein Schaltplan 
posten.

Ich weiß echt nicht mehr weiter. Beschaltung müsste stimmen, und am Code 
muss man doch nur paar Zeilen ändern und die Main Funktion einfügen.

Meine lautet zurzeit:

int main(void)
{
  DDRC = 0xFF;


    /* initialize display, cursor off */
    lcd_init(LCD_DISP_ON_CURSOR);

    //_delay_ms(50);



    for (;;) {                           /* loop forever */

    /* loesche das LCD Display und Cursor auf 1 Zeile, 1 Spalte */
    //lcd_clrscr();

    /* String auf Display anzeigen */
    lcd_puts("Hello");

    }
}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>#define LCD_CONTROLLER_KS0073  1
>#define LCD_LINES              2
>#define LCD_DISP_LENGTH       20

Ich glaube kaum das ein 2x20 Display einen KS0073 hat.

#define LCD_CONTROLLER_KS0073  0

Was für ein Diplay benutzt du?

Autor: Timo S. (kaffeetas)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
mal so nebenbei, bei dem Display stimmt (zumindest bei meinen 
Exemplaren) der angegebene Typ nicht mit dem bei Pollin verfügbaren 
Datenblatt überein!

Auf meinen Displays werkelt ein ‘NOVATEK’ NT3881DH-02/AI Controller. Man 
muss sich nur mal die Zeichen über 128 ansehen, dann merkt man schnell 
dass es kein KS0070BP-00CC ist sondern was anderes.

Bei mir funktioniern die Displays mit den Routinen von Peter Dannegger 
ohne Probleme.

Grüße
 Timo

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann vielleicht jemand die Routinen hier rein stellen oder verlinken?

Autor: Hubert G. (hubertg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du schreibst so schnell in das Display das es sein kann das du nichts 
siehst. Füge mal ein _delay_ms(200); ein.
Oder besser, schreibe dein Hello gleich nach der Initialisierung.

Autor: Karsten (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

ich habe auch das BTHQ Display von Pollin mit 2x20Zeichen. Benutze auch 
die oben gepostete lcd-new library, lese aber das busy-flag aus. Ich 
habe das Display auch bereits in Betrieb gehabt, auf einer 
Streifenrasterplatine, aber die neu geätzte Platine ist genauso und das 
Display zeigt nichts mehr an. Nach der Initialisierung ist das Display 
einfach dunkel und ich kann keine Zeichen anzeigen lassen. Die 
Beschaltung ist:

DB0-DB7 : PC0-PC3
RS : PD6
E  : PD7
RW : PB2

Wie gesagt, vorher hat es wunderbar funktioniert, aber seit dem Aufbau 
auf eine neue Platine nicht mehr. Habe alle Verbindungen durchgemessen, 
keine Kurzschlüsse und kalte Lötstellen. Habe auch ein anderes Display 
angeschlossen, das zeigt nur einen Balken an. Irgendwas ist in der 
Initialisierung nicht vollständig, aber ich weiß nicht was.

Ich hoffe auf eure Unterstützung.
Viele Grüße,
Karsten
PS: Ich benutze AVR-gcc und AVR-Studio.

Autor: Hubert G. (hubertg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es schon mal funktioniert hat, dann sollte die SW in Ordnung sein.
Wohin geht der Kontrast, sieht man in der Schaltung nicht. Wenn beide 
Zeilen dunkel sind, ist das wohl eher der Fehler.

Autor: Karsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hubert,

danke, habe das Display auf meiner Streifenraster wieder in Betrieb 
nehmen können. Werde jetzt nach Leiterbahnenfehlern suchen müssen. 
Software scheint wirklich i.O. zu sein.

Kontrast ist soweit ok, kann man normal über ein Potentiometer 
einstellen, fehlt nur im Plan, ist rechts oben das übrig gebliebene 
R8... :)

Danke schonmal für die Antwort.

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.