Forum: Mikrocontroller und Digitale Elektronik Init Problem mit KS0066 (Conrad)


von LCD genervter (Gast)


Angehängte Dateien:

Lesenswert?

Aus irgendeinem unerfindlichen Grund lässt sich mein LCD(2x20) nicht am 
ATmega8 initialisieren. Ich benutze eine 8-Bitübertragung da ich genug 
Pins übrig habe. Verbauter Controller auf dem LCD ist ein KS0066 von 
Conrad. Im Anhang das Datenblatt, auf Seite 27 steht der Initvorgang.

Das Script ist selbst geschrieben, aber das Script im AVR-GCC Tutorial 
wurde als grobe Vorlage benutzt.

Ich möchte auch auf den Thread verweisen wo die Initalisierung relativ 
gut erklärt ist. Nur mit der Umsetzung geht das nicht richtig.
--> Beitrag "LCD (Ks0066) initialisieren"

Pinbelegung:
µC      -      LCD
PD0 - PD7    Pin 7 - Pin 14
PB6           RS
PB7           E

Mein bisheriger Code (sicher nicht perfekt):
Mit ist klar dass noch alles fehlt zum Text anzeigen, ich will jetzt nur 
mal die Init schaffen.
S_ Steht für Steuer; Also Steuerport, usw.
1
#define F_CPU    8000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
#define LCD_PORT  PORTD
7
#define LCD_DDR   DDRD
8
#define S_PORT    PORTB
9
#define S_DDR     DDRB
10
#define PIN_RS    PB6
11
#define PIN_E     PB7
12
13
14
15
void lcd_ein (void) {
16
  S_PORT |= (1<<PIN_E);
17
  _delay_us (10);
18
  S_PORT &= ~(1<<PIN_E);
19
}
20
21
void lcd_befehl(unsigned char wert)
22
{
23
24
   S_PORT &= ~(1<<PIN_RS);        // RS auf 0 setzen
25
   LCD_PORT = wert;
26
   _delay_ms(1000);
27
   LCD_PORT = 0x00;
28
   lcd_ein();
29
   _delay_us(1000);
30
31
   }
32
33
void lcd_init (void) {
34
35
   _delay_ms (200);
36
   LCD_DDR = LCD_DDR | 0xFF;
37
   S_DDR = (1<<PIN_RS) | (1<<PIN_E);
38
   S_PORT &= ~(1<<PIN_RS);      // RS auf 0
39
  _delay_ms (200);
40
  lcd_befehl (0x3F);
41
  _delay_ms (100);
42
  lcd_befehl (0x0F);
43
  _delay_ms (100);
44
  lcd_befehl (0x01);
45
  _delay_ms (100);
46
lcd_befehl (0x06);
47
}
48
49
50
void main(void) {
51
52
lcd_init();
53
54
while (1) {
55
}
56
57
}

von LCD genervter (Gast)


Lesenswert?

Hat den keiner auch nur eine kleine Idee was da falsch ist? Wäre schade 
:-(

von holger (Gast)


Lesenswert?

>void lcd_befehl(unsigned char wert)
>{
>   S_PORT &= ~(1<<PIN_RS);        // RS auf 0 setzen
>   LCD_PORT = wert;
>   _delay_ms(1000);

   LCD_PORT = 0x00; // Absolut klasse Idee !!!!
                    // wert löschen bevor man ihn ins Display schreibt

>   lcd_ein();
>   _delay_us(1000);
>   }

von Andreas Knauser (Gast)


Lesenswert?

>_delay_ms(1000);
> _delay_ms(1000);

Das kannste vergessen. So lange delay-Zeiten funktionieren nicht. Siehe 
dazu delay.h im WINAVR-Verzeichnis.

von LCD genervter (Gast)


Lesenswert?

@holger Lol, war wohl ein kleiner Fehler ;) Und das Init funktioniert 
jetzt schon relativ gut. Erst die schwarze Reihe oben, dann werden beide 
Schwarz und dann geht er wieder auf eine schwarze.

@Andreas Das ist/war nur solange damit auch sicher alles mit den Zeiten 
geht und nichts zu kurz ist. Hätte das später sowieso mal verkürzt, aber 
wenn es bei so großen Werten nicht mehr geht, habe ich es jetzt auf 100 
runter gesetzt. Funktioniert genauso.

von Andreas Knauser (Gast)


Lesenswert?

na dann...

von LCD genervter (Gast)


Angehängte Dateien:

Lesenswert?

Es will einfach nicht fertig werden.

Wie vorhin gesagt passiert folgendes:

- LCD ein, 1 schwarze Zeile
- Init beginnt, 2. Zeile wird auch schwarz
- 2. Zeile wird wieder leer und 1. bleibt schwarz
- nichts mehr, ob jetzt das LCD zum leeren nicht geht, oder beim 
sonstigen Init ein Problem hat weiß ich nicht

Im Anhang ein direkter Screen vom Initvorgang im Datenblatt

Zum leeren-->
1
   void lcd_leeren(void) {
2
   lcd_befehl(0x01); // 01 da nur der erste Pin (PD0) geschaltet wird
3
   _delay_ms (20);
4
}

von Simon S. (Gast)


Lesenswert?

Hi,

also ich habe mir auch für den ks0066u eine kleine lib für meine debug 
ausgaben geschrieben.

Meine init sieht so aus:
1
void display_init() {
2
  //Set the used Port as output
3
  DISP_PORT_DDR = 0xFF;
4
  DISP_CTRL_DDR = (1 << DISP_CTRL_E)|(1 << DISP_CTRL_RW)|(1<<DISP_CTRL_RS);
5
  _delay_ms(31);     //wait at least 30ms
6
    
7
  //Function set block
8
  DISP_PORT_OUT = 0x3C;    //Send: 00111100 = 0x3C
9
  DISP_CTRL_OUT &= 0xF0;     //0 for the whole init
10
  display_enable();
11
  _delay_us(40);     //wait for more than 39 mys
12
   
13
  //Display ON/OFF CONTROL block
14
  DISP_PORT_OUT = 0x0C | (DISP_OPT_CURSOR << 1) | (DISP_OPT_CURSOR_BLK << 0);
15
  display_enable();
16
  _delay_us(40);     //wait for more than 39 mys
17
   
18
  //Display Clear block
19
  DISP_PORT_OUT = 0x01;     //Send: 00000001 = 0x01
20
  display_enable();
21
  _delay_ms(3);     //wait for more than 1.53 ms
22
23
  //Entry Mode Set block
24
  DISP_PORT_OUT = 0x06;    //Send: 00000110 = 0x06
25
  display_enable();
26
}

Das hier sind die defines die man braucht um den code zu verstehen:
1
///@brief Defines for "gluing" The Portname and the approprite Register Name together
2
//@{
3
#define GLUE(a, b)     a##b
4
#define PORTG(x)        GLUE(PORT, x)
5
#define DDRG(x)         GLUE(DDR, x)
6
//@}
7
8
/**@name Setup specific defines
9
    @warning These defines are setup specific and therefore they need to be adjusted!
10
*/
11
//@{
12
/// @brief The Charakters per Line
13
#define DISP_CHARS       16
14
/// @brief The number display lines
15
///  @todo hat keine auswirkung: init muss angepasst werden
16
#define DISP_LINES       2
17
/// @brief The display port register to be used
18
#define DISP_PORT      D
19
// @brief The port register of the controllines to be used 
20
#define DISP_CTRL_PORT    B
21
/// @brief Pin Number of E on DISP_CTRL_PORT 
22
#define DISP_CTRL_E      0
23
/// @brief Pin Number of RW on DISP_CTRL_PORT 
24
#define DISP_CTRL_RW    1
25
/// @brief Pin Number of RS on DISP_CTRL_PORT 
26
#define DISP_CTRL_RS    2
27
//@}
28
29
30
//gluing the portnames together
31
#define DISP_PORT_OUT        PORTG(DISP_PORT)
32
#define DISP_PORT_DDR      DDRG(DISP_PORT)
33
#define DISP_CTRL_OUT        PORTG(DISP_CTRL_PORT)
34
#define DISP_CTRL_DDR      DDRG(DISP_CTRL_PORT)
35
36
/**@name Options
37
    These are options for the display init
38
*/
39
//@{
40
///@brief Option: Should there be a cursor?  
41
#define DISP_OPT_CURSOR    0
42
///@brief Option: Should the cursor blink?  
43
#define DISP_OPT_CURSOR_BLK  0
44
//@}

Wenn du willst kannst du dir meine lib mal hier runterladen: 
svn://fobg.de/ks0066u_lib. Grundlegend funktioniert alles - nur nicht 
besonders komfortabel :) (brauchst einen subversion client)

von LCD genervter (Gast)


Angehängte Dateien:

Lesenswert?

@Simon Thx, zum lernen nutze ich es gerne. Aber ich will es trotzdem 
schaffen dass meine Initialisierung richtig funktioniert.

Aktueller Code im Anhang. Wie ich mit ein paar Debug-LEDs jetzt sehe, 
wird Init niemals fertig. Leider weiß ich nicht ob der µC hängen bleibt 
oder eine Funktion so Probleme macht.

von LCD genervter (Gast)


Lesenswert?

Ich weiß jetzt dass er nur den 1. Befehl sendet und danach nichts mehr 
macht.
Der restliche Code steht im vorherigen Post, falls benötigt. Überlastet 
ihn das senden oder was könnte es sein?
1
void lcd_init (void) {
2
3
  _delay_us (200);
4
  lcd_befehl (0x38); // wird gesendet; danach nichts mehr
5
  _delay_us (100);
6
  lcd_befehl (0x08);
7
  _delay_us (100);
8
  lcd_befehl (0x01);
9
  _delay_ms (100);
10
  lcd_befehl (0x06);
11
}

von Michael H* (Gast)


Lesenswert?

mein tipp wäre, dass _delay_ms(1000) in lcd_befehl() probleme macht.
aus der delay.h:
The maximal possible delay is 262.14 ms / F_CPU in MHz.
   When the user request delay which exceed the maximum possible one,
   _delay_ms() provides a decreased resolution functionality. In this
   mode _delay_ms() will work with a resolution of 1/10 ms, providing
   delays up to 6.5535 seconds (independent from CPU frequency).  The
   user will not be informed about decreased resolution.

setz doch deine leds mal innerhalb der lcd_befehl() funktion.

von LCD genervter (Gast)


Lesenswert?

_delay_ms(1000) habe ich seit dem Hinweis von Andreas erst verkürzt und 
dann ganz entfernt. Das E_Pin wird normal geschalten und auch lcd_befehl 
läuft bis zum Ende durch. Beides durch eine LED Funktion getestet. Aber 
sobald er wieder ins lcd_init() zurück soll, und den nächsten Befehl 
ausführen, passiert nichts mehr. Da dürfte auch der Grund sein warum 
sich das LCD nicht fertig initialisieren lässt. Könnte es vielleicht ein 
Speicherproblem sein: überschriebener Speicher? Oder ein Problem beim 
beenden der Unterfunktion?

von Simon S. (herrbert)


Lesenswert?

Verkürze auch mal die anderen Wartezeiten ehr in Richtung dem was im 
Datenblatt angegeben ist. Du wartest ja schon seeehhrrr lange im 
vergleich dazu.

EDIT: Sorry haste ja schon annährend gemacht - hab ich übersehen.

von Niels H. (monarch35)


Lesenswert?

Simon S. wrote:
> Verkürze auch mal die anderen Wartezeiten ehr in Richtung dem was im
> Datenblatt angegeben ist. Du wartest ja schon seeehhrrr lange im
> vergleich dazu.

Es gibt keine zu langen Wartezeiten...nur zu kurze verursachen Fehler!

von Michael H* (Gast)


Lesenswert?

Niels Hüsken wrote:
> Es gibt keine zu langen Wartezeiten...nur zu kurze verursachen Fehler!
das is einfach falsch

von Niels H. (monarch35)


Lesenswert?

Michael H* wrote:
> Niels Hüsken wrote:
>> Es gibt keine zu langen Wartezeiten...nur zu kurze verursachen Fehler!
> das is einfach falsch

Nein, ist es nicht...
(mal sehen, wohin uns diese Argumentationsebene bringt)

von Michael H* (Gast)


Angehängte Dateien:

Lesenswert?

within 5ms

von Niels H. (monarch35)


Lesenswert?

Michael H* wrote:
> within 5ms

Das ist nicht dein Ernst!?

von Michael H* (Gast)


Lesenswert?

steht so im datenblatt.

von Uwe (Gast)


Lesenswert?

Hi!
Ich kann das mit dem Timeout bestätigen, hatte mal ein 16 Zeichen aus
2x8 Zeichen, da wollten die 2.8 Zeichen nicht anspringen bis ich gemerkt 
habe das meine 1.Inittime zu hoch war. Auf Datenblattwert gestellt und 
alles war gut. War aber irgendein komischer Kontroller drauf, HD44780 
kompatibel, aber scheinbar doch nicht so ganz.

Viel Erfolg, Uwe

von LCD genervter (Gast)


Lesenswert?

Also: Wenn es nur falsche Zeiten wäre, müsste er aber doch die 
restlichen Befehle trotzdem ausführen, oder? Ob das LCD die annimmt oder 
nicht, ist dabei ja egal. Aber beim LED Test blinken die nur 1x(also 1x 
wurde lcd_ein() und 1x wurde lcd_befehl() ausgeführt) und das wars.

Ich habe es jetzt mal mit fast genau den Angaben im Datenblatt gemacht, 
nur winzige Abweichungen, brachte keine Besserung.

Testweise wurde das ganze jetzt an einen ATmega32 angeschloßen, aber 
nicht mit viel mehr Erfolg. Wenn Init anfängt, wird kurz die 2. Zeile 
auch schwarz(1. Initbefehl wird also erfolgreich gesendet) und danach 
wieder leer. Die 1. bleibt dauerhaft schwarz. Aber mit den anderen 
Zeiten passiert das ganze jetzt schneller.

von LCD genervter (Gast)


Lesenswert?

Mal kleines Info Update: Habe es jetzt mit folgendem noch versucht:
- verschiedene Zeiten
- zu schaltende Pins einzeln angeben --> PORTD |= (1<<PD2);
- sämtlichen benötigten Code in die main () geschrieben

Außer einem kurzen aufleuchten der 2. Zeile passiert wie immer noch 
nichts.

von Michael H* (Gast)


Lesenswert?

läuft dein code anständig durch, wenn das lcd nicht am controller 
steckt?

von LCD genervter (Gast)


Lesenswert?

Nein. Nur der 1. Befehl im Init wird ausgeführt.

-->  lcd_befehl (0x38);
Ab dann leuchten die LEDs nicht mehr wieder auf.

von Michael H* (Gast)


Lesenswert?

stell doch bitte den kompletten aktuellen code rein (anhang!). schon mal 
den avr-studio simulator probiert?

von LCD genervter (Gast)


Angehängte Dateien:

Lesenswert?

Hier der aktuelle Code.

von Michael H* (Gast)


Lesenswert?

void led (unsigned char wert) {
  PORTC|= _BV(wert);
  _delay_ms (100);
  PORTC|= _BV(wert);
}

einschalten, warten, uuuund: einschalten ^^

ich hab das ganze grad am simulator und da zappelt der PIN_E recht brav.
nach ner zeit bleibt er dann aus.

von LCD genervter (Gast)


Lesenswert?

void led (unsigned char led) {
  PORTC |= _BV(led);
  _delay_ms (100);
  PORTC &= ~_BV(led);
}

Ich habe es jetzt korrigiert, dass die LED direkt wieder aus geht. 
Leider blinkt sie trotzdem nur 1x. Versucht habe ich jetzt auch schon 
die Variablen für jede Funktion anders zu benennen und am Ende der 
Funktion mit "" und 0 zu leeren, brachte aber auch nichts :-(

von Michael H* (Gast)


Lesenswert?

hmm, also bei mir im simulator läuft dein prog recht schön durch.
hast du überall brav stützkodensatoren? vielleicht zieht dein lcd beim 
einschalten n bisschen strom, dein regler is 5m weg und schon verreckt 
der atmel. hat er nen kondensator am reset?

von LCD genervter (Gast)


Lesenswert?

Die Sachen sind auf einem Steckbrett aufgebaut, alles nur ein paar 
Zentimeter von einander entfernt. Der Resetpin ist gar nicht beschalten. 
Kondensatoren sind da eigentlich eher weniger verbaut, liegt wohl daran 
dass es bisher auch so funktioniert hat. Ich weiß nicht immer sehr gut 
;) Was müsste ich da noch alles einbauen?

von Michael H* (Gast)


Angehängte Dateien:

Lesenswert?

also erst mal einen pullup an den reset. 10k oder so. einen 100nF gegen 
masse dazu. 100n auch zwischen V_cc und gnd nah am atmel. auch beim 
AV_cc.
und was nie schaden kann, is ein dicker elko um die 10µF zwischen V_cc 
und gnd.

edit: was mir auch grad noch in den sinn kommt: probier die schaltung 
doch mal ohne isp. wenn er abgesteckt is, einfach kurz den reset-pin auf 
masse ziehn.

im anhang siehst du, was dein atmel tut.
gelb: reset
blau: pc4
rot: pc5
grün: pb7

und auf den datenleitungen zappelts auch recht brav

von LCD genervter (Gast)


Lesenswert?

nF habe ich leider nicht. Dauert noch bis Ende des Monats dass ich mir 
welche holen kann. Gehen auch welche im µF Bereich? Da hätte ich bis 1 
µF zur Verfügung. Bisher hat sich an dem Problem noch nichts geändert. 
Ich glaube ich lass es für heute und mach dann später weiter.

Aber mal ein großes THX für die Hilfe bisher.

von Michael H* (Gast)


Lesenswert?

ja, 1µF tut auch. für den reset bestimmt zu viel, aber mein simulator 
sagt, dass er damit keine probleme hat. ich gönn mir noch ne halbe, 
hoffentlich hilft die ^^

von LCD genervter (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt mal einen Schaltplan vom derzeitigen Aufbau erstellt. Im 
Bild ist Vss gerade auf GND. Versuche es aber immer genauso mit einem 
Poti.

Ist nicht alles perfekt gezeichnet, da es mit einer Art Paint Programm 
gemacht wurde.

von LCD genervter (Gast)


Lesenswert?

Nicht immer nur alle Downloaden! Auch mal einer antworten.

Update: Habe mal wieder auch den Poti in den Kontrast eingebaut. Jetzt 
wird das LCD kurz geleert, und danach erscheint wieder der obere 
schwarze Balken. LED blinkt wie bisher nur 1x.

von LCD genervter (Gast)


Lesenswert?

Hat den jetzt gar keiner mehr Ideen? Irgendwie muss das Ding doch 
funktionieren, oder ist es ein magischer Zauberkasten?

von Michael H* (Gast)


Lesenswert?

#define LCD_PORT  PORTD
#define LCD_DDR   DDRD
#define S_PORT    PORTB
#define S_DDR     DDRB
#define PIN_RS    PB6
#define PIN_E     PB7

das stimmt alles nicht mit dem schaltplan überein

von LCD genervter (Gast)


Lesenswert?

Der Code wurde natürlich angepasst auf den anderen µC. Beim ATmega8 
stimmt die Belegung. Beim 32 wird die im Schaltplan verwendet.

von LCD genervter (Gast)


Lesenswert?

Update: Etwas ziemlich komisches. Der µC hat ahnscheinend massive 
Probleme mit den _delay Funktionen. Jetzt habe ich mal eine eigene 
benutzt und schon blinkt die LED so oft wie sie soll. Das LCD ist zwar 
immer noch nicht initialisiert, das dürfte jetzt aber nur noch ein 
Timing Problem sein. Aber was das mit den _delay auf sich hat ist sehr 
komisch.

Code:
1
void delay_ms(unsigned short ms)
2
/* delay for a minimum of <ms> */
3
/* with a 1Mhz clock, the resolution is 1 ms */
4
{
5
        // Note: this function is faulty, see avrm8ledtest-0.2.tar.gz for
6
        //       updated code.
7
        unsigned short outer1, outer2;
8
             outer1 = 50; 
9
10
            while (outer1) {
11
                outer2 = 1000;
12
                while (outer2) {
13
                        while ( ms ) ms--;
14
                        outer2--;
15
                }
16
                outer1--;
17
        }
18
}

von Michael H* (Gast)


Lesenswert?

du sagst aber dem compiler schon, dass du jeweils nen andren atmel 
verwendest?

von LCD genervter (Gast)


Lesenswert?

Natürlich. Wird immer im Makefile geändert. Dass ich alles umstellen 
muss ist mir schon klar. Aber warum _delay... Probleme macht verstehe 
ich nicht so ganz.

von Michael H* (Gast)


Lesenswert?

also dass ein interner takt dermaßen unsauber ist, dass deswegen die 
init nicht klappt, kann ich mir eig nicht vorstellen.
aber probier doch mal folgendes:
1
void warten(unsigned int bla) {
2
   for(unsigned int wart; wart<bla; wart++)   _delay_ms(1);
3
}
1
while(1) {
2
   PORTLED ^= PINLED;
3
   warten(1000);
4
}
schau doch einfach mal, ob deine led mit 0,5Hz blinkt.

von Michael H* (Gast)


Lesenswert?


von LCD genervter (Gast)


Lesenswert?

Die LED bringt sehr regelmäßig, was sie aber auch bei früheren 
Testprogrammen immer tat. Also der Takt dürfte in Ordnung sein.

Der Kontrast ist an einen Poti angeschloßen und auf relativ gut lesbar 
eingestellt. Also ca. halb zwischen weg und voll.

von Michael H* (Gast)


Lesenswert?

tjo, dann rat ich mal weiter: mal die timing zeiten verdoppelt?
oder vielleicht in einer schleife um ein x-faches erhöhen. das aktuelle 
x per led oder so ausgeben. was dümmeres fällt mir auch nimmer ein. 
schon gar ned zu so ner zeit.

von LCD genervter (Gast)


Lesenswert?

Mir fällt langsam auch keine Möglichkeit mehr ein. Einmal funktioniert 
es wieder nur mit _delay..., dann wieder nur mit delay..., ein anderes 
mal nur mit beiden gemischt im Code. Entweder es blinkt dann wie gewollt 
4x oder mal wieder nur 1x.

Irgendwie hat der µC ziemliche Eigenheiten. Vielleicht ist er nicht gut 
drauf, oder launisch?

Naja egal. Immerhin weiß ich jetzt grob dass es an den Zeitfunktionen 
liegt. Da habe ich ja dann noch viel Zeit um die richtige Einstellung zu 
finden.

Nochmal ein großes THX an alle die mir hier geholfen haben.

von Niels H. (monarch35)


Lesenswert?

Ich bin übrigengs immernoch der Meinung, daß keine zu langen Wartezeiten 
bei der Ansteuerung des Kontrollers gibt. Die Referenz, die für einen 
Timeout genannt worden ist, betraf einen völlig anderen, einen 
grafischen LCD- Kontroller. Diesen Timeout gibt es bei HD44780 und 
kompatibelen nicht!

Ich schlage daher vor, du bastelst dir erstmal eine Funktion zusammen, 
die es dir ermöglicht, die Signale Schritt für Schritt per Tastendruck 
an das LCD zu senden, die du dann mit einem Multimeter direkt am Display 
nachmessen kannst. Damit solltest du jeden zweifel aus den Weg räumen 
können.

von Michael H* (Gast)


Lesenswert?

klar, gut möglich. aber die kategorische aussage, dass es keine zu 
langen timings gäbe, war ned richtig.
ich glaube zur not könnte man manche displays auch per taster und übung 
initialisiern =)
bisher hab ich aber die hd44780 immer schnell genug anders zum laufen 
gebracht ^^

von Niels H. (monarch35)


Lesenswert?

Michael H* wrote:

> bisher hab ich aber die hd44780 immer schnell genug anders zum laufen
> gebracht ^^

Bei der Ansteuerung meines ersten 44780 Displays (muss ca. anfang 90'er 
gewesen sein) hatte ich nichtmal ein Datenblatt mit ner Pinbelegung. Mit 
reinem Trial and Error hab ich ca. nach einer Woche erste sinnvolle 
Ergebnisse. Vorteil war der ansteuernde C64, der in Basic programmiert 
garnicht zu schnell sein konnte :)

von LCD genervter (Gast)


Angehängte Dateien:

Lesenswert?

Ich nochmal: Soweit ich jetzt rausgefunden habe, darf _delay_us nur ein 
paar mal im Code vorkommen, oder eventuell pro Durchgang? Naja das ist 
aber eher egal. Mehr ist das Problem dass er das Init noch nicht richtig 
annimmt.
Alle 4 Befehle werden gesendet, und nach dem 4. (0x06) erscheint wieder 
nur der schwarze Balken oben.
Vom 1. bis zum 4. Befehl ist das LCD leer. Ich wüsste jetzt nicht wo da 
ein Fehler im Init vorhanden ist?
Im Anhang nochmal der Screen vom Init im Datenblatt.
1
  lcd_befehl (0x38); // 111000
2
  _delay_us (50);
3
  lcd_befehl (0x0E); // 1110
4
  _delay_us (50);
5
  lcd_leeren();  // 0x01
6
  _delay_ms (5);
7
  lcd_befehl (0x06); // 110

von Michael H* (Gast)


Lesenswert?

LCD genervter wrote:
> Ich nochmal: Soweit ich jetzt rausgefunden habe, darf _delay_us nur ein
> paar mal im Code vorkommen, oder eventuell pro Durchgang? Naja das ist
hö? wo steht sowas?

> Alle 4 Befehle werden gesendet, und nach dem 4. (0x06) erscheint wieder
> nur der schwarze Balken oben.
hast du mal versucht, jetzt daten aufs lcd zu schreiben?

> Vom 1. bis zum 4. Befehl ist das LCD leer. Ich wüsste jetzt nicht wo da
> ein Fehler im Init vorhanden ist?
> Im Anhang nochmal der Screen vom Init im Datenblatt.
>
>
1
>   lcd_befehl (0x38); // 111000
2
// 0x38? dispay off?
3
4
>   _delay_us (50);
5
>   lcd_befehl (0x0E); // 1110
6
// aso, und hier wieder an. mal ohne ausschalten probiert?
7
8
>   _delay_us (50);
9
>   lcd_leeren();  // 0x01
10
>   _delay_ms (5);
11
>   lcd_befehl (0x06); // 110
12
>

hast du schon mal nur den µc resettet, wenn das LCD schon "warm" ist, 
also seit längerem mit spannung versorgt wird?

> S_PORT &= ~(1<<PIN_RS) | (1<<PIN_E);      // RS auf 0
bist du dir dabei eig sicher?

setz doch zum schluss deinen R/W und E pin testweise auf high.

ich hab grad ein dbl gefunden, bei dem zur init noch n bisschen mehr 
gehört. war von samsung. nen hersteller kannst du woh ned identifiziern?

von mui (Gast)


Lesenswert?

Was mir gerade noch einfällt zum Thema delay.h: Damit die korrekt 
arbeitet, muss die Compileroptimierung -Os eingeschaltet sein...hast du 
daran gedacht?

von LCD genervter (Gast)


Lesenswert?

>hö? wo steht sowas?
Das steht nirgendwo. Nur wenn ich mehr davon schreibe, passiert das 
Problem was ich oben immer hatte. Er führt nur den 1. Befehl aus, danach 
nichts mehr.
Daten schreiben habe ich versucht, aber es wird nichts angezeigt. Weder 
in die 2. Zeile wechseln, noch LCD leeren oder irgendwas anzeigen 
funktioniert.

> // aso, und hier wieder an. mal ohne ausschalten probiert?
Also  E direkt auf High lassen, oder wie ist das gemeint?

Soweit ich gefunden habe ist der KS0066 von Samsung. Zumindest nach dem 
bisher gefundenen Datenblatt und den Infos darin. Das ganze Bauteil ist 
von "Anag Vision". Conrad-Nr: 183350. Leider ist das Datenblatt von der 
Artikelbeschreibung sehr sparsam. Im Datenblatt von Samsung selbst steht 
noch ein etwas komischer Init Prozess. Aber außer einem zusätzlichen 1. 
Befehl ist er mit dem anderen Init gleich, nur in reiner Textform(Seite 
24). Der extra Befehl sagt ungefährt: "Write 20H to all DDRAM".

>> S_PORT &= ~(1<<PIN_RS) | (1<<PIN_E);      // RS auf 0
>bist du dir dabei eig sicher?
Falsch? Laut Datenblatt müssen die auf Low, also 0 sein.
PIN_E ja nur zum Senden des Befehls auf High.

@mui Ja die Optimierung ist auf Os eingestellt.

von LCD genervter (Gast)


Lesenswert?

Und das mit dem Warmstart habe ich jetzt auch probiert, brachte aber 
keinen Unterschied. Init läuft durch, und dann kommt wieder der Balken.

von Michael H* (Gast)


Lesenswert?

>>> S_PORT &= ~(1<<PIN_RS) | (1<<PIN_E);      // RS auf 0
>> bist du dir dabei eig sicher?
> Falsch? Laut Datenblatt müssen die auf Low, also 0 sein.
> PIN_E ja nur zum Senden des Befehls auf High.
dann fehlt da entweder eine klammer oder eine zweite invertierung.
1
S_PORT &= ~(1<<PIN_RS) | ~(1<<PIN_E); //oder
2
S_PORT &= ~((1<<PIN_RS) | (1<<PIN_E));

von verwunderter (Gast)


Lesenswert?

Ich habe das jetzt geändert, aber kein Unterschied. Habe auch noch viele 
verschiedene Möglichkeiten probiert(direkte Angaben ohne Variablen, 
usw.), aber nichts.

von reflection (Gast)


Lesenswert?

Habe jetzt nicht alles gelesen, aber hatte mal so ein blödes Teil wo ich 
erst nach weiss nicht wie lang suchen und probieren herausfand, dass man 
das LSB zuerst senden muss. War auch irgend ein KS...

Gruss reflection

von Simon S. (herrbert)


Lesenswert?

reflection wrote:
> Habe jetzt nicht alles gelesen, aber hatte mal so ein blödes Teil wo ich
> erst nach weiss nicht wie lang suchen und probieren herausfand, dass man
> das LSB zuerst senden muss. War auch irgend ein KS...
>
> Gruss reflection

Das ist doch aber nur im 4-bit Betrieb wichtig.

von Michael K. (aemkai)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bekomme auch mein LCD nicht zum laufen. Es ist ein L2432 von Seiko,
laut Datenblatt mit KS0066-Controller.

Die Delay-Zeiten sollten nach dem Datenblatt eigentlich hinhauen, die
anderen Funktionen habe ich vom HD44780 übernommen.
Ich habe auch schon andere Zeiten und andere Initialisierungsschritte 
versucht - hat alles nichts geholfen.
Weiß jemand ob ich die anderen Funktionen noch abändern muss?

Kann mir jemand sagen wo mein Fehler liegt, ich such und probier jetzt
schon mehrere Tage und finde nix.

Danke schonmal.

Micha

von Niels H. (monarch35)


Lesenswert?

ist sicher, daß der Kontroller generell läuft?

von Michael K. (aemkai)


Lesenswert?

Niels Hüsken wrote:
> ist sicher, daß der Kontroller generell läuft?

Also die erste Zeile ist schwarz, wie beim HD44780 vorm initialisieren.
Bei dem jetzigen Quelltext flackert diese schwarze Zeile regelmäßig, 
(wahrscheinlich so wie der ATmega Daten sendet), allerdings sind keine 
Zeichen zu erkennen und auch die zweite Zeile kommt nicht. Ich hab 
mehrere Displays und es ist bei allen so, von daher denke ich nicht, 
dass das Display kaputt ist.

von holger (Gast)


Lesenswert?

>Bei dem jetzigen Quelltext flackert diese schwarze Zeile regelmäßig,

Dann nimm das lcd_init() mal aus der Endlosschleife raus.

von Michael A. (micha54)


Lesenswert?

Hallo,

also ich würde mich beim Init sklavisch an das Datenblatt halten, wenn 
da ein Delay steht, dann benutze genau das genannte.

Die ersten Befehle sind sehr sensibel, weil der KS0066 wohl darüber eine 
eigene Initialisiserung fährt. Daher sollte man die einhalten.

Das Init des KS0066 weicht von anderen Kontrollern ab.

Ach ja, selbst delay_us(1) ist kein Problem, es gibt keine Magie beim 
delay.

Gruss,
Michael

von Michael K. (aemkai)


Lesenswert?

@Holger: lcd_init() ist nicht in der Endlosschleife, sondern wird am 
Anfang von main() einmal aufgerufen (s.u.)

@Michael: Werd's mal probieren, hab die Delay-Zeiten bisschen 
großzügiger bemessen, hat beim HD44780 auch immer geklappt.


Mein Hauptprogramm:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <util/delay.h>
4
5
6
#define sbi(port, bit) (port) |= (1 << (bit))
7
#define cbi(port, bit) (port) &= ~(1 << (bit))
8
9
int main(void)
10
{
11
lcd_init();
12
lcd_clear();
13
14
while(1)
15
{
16
17
lcd_string("Test: ");
18
set_cursor(3,2);
19
lcd_string("Hello World");
20
_delay_ms(100);
21
22
}
23
return 0;
24
}


meine Headerdatei lcd-routines.h:
1
void lcd_data(unsigned char temp1);
2
void lcd_command(unsigned char temp1);
3
void lcd_enable(void);
4
void lcd_init(void);
5
void lcd_home(void);
6
void lcd_clear(void);
7
void set_cursor(uint8_t x, uint8_t y);
8
 
9
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
10
#ifndef F_CPU 
11
#define F_CPU 1000000
12
#endif 
13
// LCD Befehle
14
 
15
#define CLEAR_DISPLAY 0x01
16
#define CURSOR_HOME   0x02
17
 
18
// Pinbelegung für das LCD, an verwendete Pins anpassen
19
 
20
#define LCD_PORT        PORTC
21
#define LCD_DDR         DDRC
22
#define RS            PC4
23
#define EN            PC5 
24
//--> DB4..7 = PC0..3

von Michael K. (aemkai)


Lesenswert?

Hat leider auch nichts genützt .

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.