Forum: Mikrocontroller und Digitale Elektronik HD44780 kompatibles LCD Display.


von Cyb3r (Gast)


Lesenswert?

Hallo
Ich habe heute mein HD44780 kompatibles LCD Display angeschlossen udn 
versuche nun vergebens etwas auszugeben.
Als ich das ganze das erstemal angeschlossen habe da waren alle Stellen 
wo man dann etwas ausgeben kann noch dunkel und übers Poti regelbar, das 
ist nichtmehr so.
kann es sein das das kaputt ist?
Also es mach nichts außer schön blau leuchten. Wie kann man das ganze 
einfach testen? Anschlüsse habe ich eigl alle überprüft

möchte den 4-bit modus
http://www.reichelt.de/?;ACTION=7;LA=6;OPEN=0;INDEX=0;FILENAME=A500%252FLCD162CBL%2523EAS.pdf;SID=28j-7afqwQARwAAEaGIsQ56348d90cb62dc427f0177218373e087

Ich habe das gefühl ich verstehe dei initialisierung falsch und wie gebe 
ich dann ein Zeichen aus, z.B. H das dieplay ist zweilzeilig.

Danke

von Cyb3r (Gast)


Lesenswert?

so ist mein testcode
1
#include <avr/io.h>         
2
#include <stdio.h>
3
#include <stdlib.h>
4
5
#define LCD_PORT         PORTC        
6
#define LCD_DATA0_PIN    3          
7
#define LCD_DATA1_PIN    4            
8
#define LCD_DATA2_PIN    5          
9
#define LCD_DATA3_PIN    6           
10
#define LCD_RS_PIN       0         
11
#define LCD_RW_PIN       1            
12
#define LCD_E_PIN        2       
13
14
void msleep(int msec);
15
void enable();
16
17
int main(void)
18
{
19
  DDRC = 0xff; // port als ausgang
20
  msleep(20);
21
  
22
  LCD_PORT = 0b00010000; // 4bit datenlänge einschalten
23
  enable();
24
  msleep(10);
25
26
27
  LCD_PORT = 0b00000000; 
28
  enable();
29
  msleep(10);        //display ein cursor ein cursor blinken
30
  LCD_PORT = 0b01111000; 
31
  enable();
32
  msleep(10);
33
  
34
  
35
36
37
38
  
39
  
40
  while(1);
41
}
42
43
void enable()
44
{
45
  LCD_PORT |= (1 << LCD_E_PIN);
46
  msleep(5);
47
  LCD_PORT &= ~(1 << LCD_E_PIN);
48
}
49
50
void msleep(int msec)
51
{  
52
  for (int s=0; s<msec; s++) {
53
    for (long int i=0; i<2403; i++) {
54
      asm volatile("nop"); 
55
    }
56
  }
57
}

von Wilhelm F. (Gast)


Lesenswert?

>Ich habe das gefühl ich verstehe dei initialisierung falsch und wie
>gebe ich dann ein Zeichen aus, z.B. H das dieplay ist zweilzeilig.

Ein Flußdiagramm der Initialisierung sollte im Datenblatt vorhanden 
sein.

Am besten suchst du mal nach Softwarebeispielen.

von Bastler (Gast)


Lesenswert?

Soweit ich es im Kopf habe muss 3x 0x03 und einpaar zeichen mehr 
ausgegebenwerden zur Initialisierung.
Zu diesem Controller findet man genügend Beispiele.
Nicht vergessen D/I umschalten.

von Cyb3r (Gast)


Lesenswert?

Ja Ok
aber wie ist das mit Function Set da blick ich nicht durch.
Muss ich das 2mal machen? und da muss ich ja auch irgendwie die Display 
größe mit reinbringen wie mache ich das?

von holger (Gast)


Lesenswert?

>größe mit reinbringen wie mache ich das?

Gar nicht. Initialisieren musst du nur auf eine oder zwei Zeilen.

>  LCD_PORT = 0b00010000; // 4bit datenlänge einschalten

Und zählen lernen;) 0x20 sieht bei mir anders aus.

von Wilhelm F. (Gast)


Lesenswert?

Cyb3r schrieb:

>aber wie ist das mit Function Set da blick ich nicht durch.

>Muss ich das 2mal machen?

Ich sah Beispiele, wo es auch 3 mal gemacht wurde.

Und zwischen den Initialisierungsschritten, müssen Wartezeiten 
eingehalten werden.

Daher, bitte auf jeden Fall mal das Datenblatt besorgen.

von Cyb3r (Gast)


Lesenswert?

holger schrieb:
> Und zählen lernen;) 0x20 sieht bei mir anders aus.

omg Liese doch mal den Quellcode ich hab doch oben definiert wie meine 
Pinbelegung ist auch wenn ichs zu dem Zeitpunkt nicht nutze

So ich habe meine Quellcode einmal überarbeitet:
    Jedoch ist mein Problem nun wie dei Funktion lcd_load_byte aussehen 
muss? Muss ich dsa ganze immer in s Register schreiben? ich bin 
irgendwie verwirrt /verpeilt heute
Danke für die Hilfe
1
#include <avr/io.h>    
2
3
#define LCD_PORT          PORTC
4
#define LCD_ENABLE_PIN    2
5
#define LCD_RW_PIN        1 
6
#define LCD_RS_PIN        0 
7
#define LCD_D4_PIN        3
8
#define LCD_D5_PIN        4
9
#define LCD_D6_PIN        5
10
#define LCD_D7_PIN        6
11
12
13
#defune FUNCTION_SET  
14
#define ENTRY_MODE_SET    
15
#define LCD_CMD_ON 
16
#define LCD_CMD_OFF  
17
#define LCD_CMD_CLEAR    
18
19
20
void _delay_ms(int msec);
21
void _delay_us(int usec);
22
23
void lcd_init();
24
void lcd_send_cmd();
25
void lcd_strobe_E();
26
void lcd_load_byte(int out_byte);
27
28
int main (void)
29
{
30
    // PORTC Pin 0...7 Outputs fürs Display
31
  DDRC = (1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1 << DDC4) | (1 << DDC5) | (1 << DDC6) | (1 << DDC7);                    
32
    
33
        
34
  while(true);
35
    return 0;
36
}
37
38
void lcd_load_byte(int out_byte)
39
{
40
41
}
42
43
void lcd_strobe_E()
44
{
45
    // strobe E Signal */
46
    LCD_PORT |= _BV(LCD_ENABLE_PIN);
47
    _delay_us(450); 
48
    LCD_PORT &= ~_BV(LCD_ENABLE_PIN);
49
}
50
51
void lcd_send_cmd()
52
{
53
    /* Befehl liegt an, so RS muss low (0) sein */
54
    LCD_PORT &= ~_BV(LCD_RS_PIN); 
55
    lcd_strobe_E();
56
    _delay_us(40);
57
}
58
59
void lcd_init()
60
{
61
  // 20ms delay ... LCD power
62
    _delay_ms(16);       
63
  LCD_PORT &= ~_BV(LCD_ENABLE_PIN);     // E = 0
64
  LCD_PORT &= ~_BV(LCD_RW_PIN);       // R/W = 0
65
  LCD_PORT &= ~_BV(LCD_RS_PIN);      // RS = 0   
66
   
67
    //schreibe 0x30 -> LCD und warte 5 ms damit die Instruktion verarbeitet ist 
68
    lcd_load_byte(0x30);
69
    lcd_send_cmd();
70
    _delay_ms(5);
71
   
72
    //schreibe 0x30 -> LCD und warte 160 us damit die Instruktion verarbeitet ist
73
    lcd_load_byte(0x30);
74
    lcd_send_cmd();
75
    _delay_us(160);
76
  
77
    //schreibe 0x30 -> LCD und warte 160 us damit die Instruktion verarbeitet ist
78
    lcd_load_byte(0x30);
79
    lcd_send_cmd();
80
    _delay_us(160);
81
   
82
    // Function Set und 40 us warten
83
    lcd_load_byte(FUNCTION_SET);
84
    lcd_send_cmd();
85
  _delay_us(40);
86
87
    // Display OFF 40 us warten
88
    lcd_load_byte(LCD_CMD_OFF);    
89
    lcd_send_cmd();
90
  _delay_us(40);
91
92
    // Clear Display und 2 ms warten
93
    lcd_load_byte(LCD_CMD_CLEAR);    
94
    lcd_send_cmd();
95
    _delay_ms(2);
96
  _delay_us(40);
97
    
98
    // Entry Mode Set und 40 us warten
99
    lcd_load_byte(ENTRY_MODE_SET);    
100
    lcd_send_cmd();
101
  
102
    // Display ON und 40 us warten
103
    lcd_load_byte(LCD_CMD_ON);    
104
    lcd_send_cmd();
105
  _delay_us(40);
106
}
107
108
109
void _delay_ms(int msec)
110
{  
111
  for (int s=0; s<msec; s++) {
112
    for (long int i=0; i<2403; i++) {
113
      asm volatile("nop"); 
114
    }
115
  }
116
}
117
118
void _delay_us(int usec)
119
{  
120
  for (int s=0; s<usec; s++) {
121
    for (long int i=0; i<2; i++) {
122
    if(true)
123
      asm volatile("nop"); 
124
    }
125
  }
126
}

von Jobst M. (jobstens-de)


Lesenswert?

Setze es erst 2x hintereinander in den 8-Bit-Modus und dann in den 
4-Bit-Modus. Damit bist Du auf der sicheren Seite. Sonst weßt Du ja gar 
nicht, ob das Display gerade das obere oder das untere Halb-Byte 
erwartet.
1
void lcd_load_byte(int out_byte)
2
{
3
4
}

macht evtl. etwas wenig ...

... so wie eigentlich das ganze Programm ...


Du benötigst im 4-Bit-Mode zwei Schreibvorgänge pro Byte ... (hint)


Gruß

Jobst

von LCD (Gast)


Lesenswert?

void lcd_load_byte( char byte , uint8_t mode)
{
// daten oder befehlsmodus auswählen
// also die jeweiligen leitungen setzen/ löschen

//obere 4 bit des char out_byte an die 4 datenleitungen anlegen
// enable pin vom LCD an .... 80µs warten  ... aus

//untere 4 bit  an die datenleitungen anlegen
// enable pin vom LCD an .... 80µs warten  ... aus
}


um das ganze universell zu halten kann man die pins direkt vorher 
undefinieren

  if(byte & 0x80) LCDPORTD7 |= (1<<LCD_D7);
  if(byte & 0x40) LCDPORTD6 |= (1<<LCD_D6);
  if(byte & 0x20) LCDPORTD5 |= (1<<LCD_D5);
  if(byte & 0x10) LCDPORTD4 |= (1<<LCD_D4);
  dann enable togglen

dann entweder bitschieben byte<<=4 ; und nochmal das ganze
(in einer schleife schnell machbar)
oder man schreibt das ganze nochmal hin

  if(byte & 0x08) LCDPORTD7 |= (1<<LCD_D7);
  if(byte & 0x04) LCDPORTD6 |= (1<<LCD_D6);
  if(byte & 0x02) LCDPORTD5 |= (1<<LCD_D5);
  if(byte & 0x01) LCDPORTD4 |= (1<<LCD_D4);
  enable togglen


kann man sowas nit mit in das tut aufnehmen ???
alle 2 tage kommt sone frage

von Karl H. (kbuchegg)


Lesenswert?

Cyb3r schrieb:
> holger schrieb:
>> Und zählen lernen;) 0x20 sieht bei mir anders aus.
>
> omg Liese doch mal den Quellcode ich hab doch oben definiert wie meine
> Pinbelegung ist auch wenn ichs zu dem Zeitpunkt nicht nutze

omg Lies doch bitte das Tutorial. Da gibt es einen ganzen Abschnitt über 
LCD.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung

omg benutz doch bitte google. LCD Libraries gibt es für den HD44780 wie 
Sand am Meer.

von Karl H. (kbuchegg)


Lesenswert?

LCD schrieb:

> um das ganze universell zu halten kann man die pins direkt vorher
> undefinieren
>
>   if(byte & 0x80) LCDPORTD7 |= (1<<LCD_D7);

Das ist leider nur die halbe Miete
    if(byte & 0x80)
      LCDPORTD7 |= (1<<LCD_D7);
    else
      LCDPORTD7 &= ~(1<<LCD_D7);

> kann man sowas nit mit in das tut aufnehmen ???

Kann man. Warum nicht du?

von Cyb3r (Gast)


Lesenswert?

Ich habe auch alle fertigen Librarys jetzt durchgetestet das tut sich 
bei mir auch absolut garnichts und die Pinbelegung, sowie die Leitungen 
überprüft alles einwandfrei.

Aber trotzdem habe ich noch ein grundlegendes verständiss Problem
unzwar wenn ich im 4bit modus bin werden immer zuerst die 4 
höherwertigen bits gesendet?

und ich sende 4bit (hbit) erzeuge die negative flanke mit enable und 
dann wieder 4bit(lbit) und flanke ??
die wartezeit zwiscehn den bits kann beliebig lang sein?

von Cyb3r (Gast)


Lesenswert?

Es hat sich alles geklärt

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.