Forum: Mikrocontroller und Digitale Elektronik LCD-Display an ATMega8 funktioniert nicht


von Marco H. (spider-man)


Angehängte Dateien:

Lesenswert?

Hallo,
ich versuche seit 2 Wochen ein LCD-Display vom Typ CFAH1602B-TMC-JP mit 
einem Controller HD44780 (lt. Datenblatt) von einem ATMega8 aus 
anzusteuern. Anschlüsse siehe lt. beigefügtes Schaltbild. Leider 
leuchten vom 2x16-Display die obere Zeile hell und die untere dunkel. 
Das was angezeigt werden soll erscheint jedoch nicht.
Hab schon alles versucht und bin mittlerweile ganz schön verzweifelt. 
Vielleicht kann mir mal einer ein ganz kurzes C-Programm mit kompletter 
Include-Datei, das was ganz Simples wie z.B. "TEST" ausgibt, zumailen 
oder jemand weiss die Lösung zu meinem Problem.
Schon mal vielen Dank für alle, die sich bemühen mir zu helfen.

Gruß
Marco

von Oliver J. (skriptkiddy)


Lesenswert?

Zeig doch mal deinen Code.

von Peter D. (peda)


Lesenswert?


von Fritz M. (Gast)


Lesenswert?

Die Datei lcd_routines.c enthält die Grundfunktionen für die 
LCD-Ansteuerung aus dem AVR-GCC-Tutorial.


--------------------------------- lcd_routines.c
1
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
2
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
3
//
4
// Die Pinbelegung ist über defines in lcd-routines.h einstellbar
5
 
6
#include <avr/io.h>
7
#include "lcd_routines.h"
8
#include <util/delay.h>
9
 
10
// sendet ein Datenbyte an das LCD
11
 
12
void lcd_data(unsigned char temp1)
13
{
14
    unsigned char temp2 = temp1;
15
 
16
    LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
17
 
18
    temp1 = temp1 >> 4;
19
    temp1 = temp1 & 0x0F;
20
    LCD_PORT &= 0xF0;
21
    LCD_PORT |= temp1;               // setzen
22
    lcd_enable();
23
 
24
    temp2 = temp2 & 0x0F;
25
    LCD_PORT &= 0xF0;
26
    LCD_PORT |= temp2;               // setzen
27
    lcd_enable();
28
 
29
    _delay_us(42);
30
}
31
 
32
// sendet einen Befehl an das LCD
33
 
34
void lcd_command(unsigned char temp1)
35
{
36
    unsigned char temp2 = temp1;
37
 
38
    LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen
39
 
40
    temp1 = temp1 >> 4;              // oberes Nibble holen
41
    temp1 = temp1 & 0x0F;            // maskieren
42
    LCD_PORT &= 0xF0;
43
    LCD_PORT |= temp1;               // setzen
44
    lcd_enable();
45
 
46
    temp2 = temp2 & 0x0F;            // unteres Nibble holen und maskieren
47
    LCD_PORT &= 0xF0;
48
    LCD_PORT |= temp2;               // setzen
49
    lcd_enable();
50
 
51
    _delay_us(42);
52
}
53
 
54
// erzeugt den Enable-Puls
55
void lcd_enable(void)
56
{
57
    // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen
58
    // http://www.mikrocontroller.net/topic/81974#685882
59
    LCD_PORT |= (1<<LCD_EN);
60
#if 1
61
    _delay_us(4); // kurze Pause, Original aus dem Tutorial ist bei meinem Display zu kurz!
62
#else
63
    _delay_us(1); // kurze Pause
64
#endif
65
    // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
66
    // http://www.mikrocontroller.net/topic/80900
67
    LCD_PORT &= ~(1<<LCD_EN);
68
}
69
 
70
// Initialisierung:
71
// Muss ganz am Anfang des Programms aufgerufen werden.
72
 
73
void lcd_init(void)
74
{
75
    LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN);   // Port auf Ausgang schalten
76
 
77
    // muss 3mal hintereinander gesendet werden zur Initialisierung
78
 
79
    _delay_ms(15);
80
    LCD_PORT &= 0xF0;
81
    LCD_PORT |= 0x03;
82
    LCD_PORT &= ~(1<<LCD_RS);      // RS auf 0
83
    lcd_enable();
84
 
85
    _delay_ms(5);
86
    lcd_enable();
87
 
88
    _delay_ms(1);
89
    lcd_enable();
90
    _delay_ms(1);
91
 
92
    // 4 Bit Modus aktivieren
93
    LCD_PORT &= 0xF0;
94
    LCD_PORT |= 0x02;
95
    lcd_enable();
96
    _delay_ms(1);
97
 
98
    // 4Bit / 2 Zeilen / 5x7
99
    lcd_command(0x28);
100
 
101
    // Display ein / Cursor aus / kein Blinken
102
    lcd_command(0x0C);
103
 
104
    // inkrement / kein Scrollen
105
    lcd_command(0x06);
106
 
107
    lcd_clear();
108
}
109
 
110
// Sendet den Befehl zur Löschung des Displays
111
 
112
void lcd_clear(void)
113
{
114
    lcd_command(CLEAR_DISPLAY);
115
    _delay_ms(5);
116
}
117
 
118
// Sendet den Befehl: Cursor Home
119
 
120
void lcd_home(void)
121
{
122
    lcd_command(CURSOR_HOME);
123
    _delay_ms(5);
124
}
125
 
126
// setzt den Cursor in Zeile y (1..4) Spalte x (0..15)
127
 
128
void set_cursor(uint8_t x, uint8_t y)
129
{
130
    uint8_t tmp;
131
 
132
    switch (y)
133
    {
134
    case 1:
135
        tmp=0x80+0x00+x;
136
        break;    // 1. Zeile
137
    case 2:
138
        tmp=0x80+0x40+x;
139
        break;    // 2. Zeile
140
    case 3:
141
        tmp=0x80+0x10+x;
142
        break;    // 3. Zeile
143
    case 4:
144
        tmp=0x80+0x50+x;
145
        break;    // 4. Zeile
146
    }
147
    lcd_command(tmp);
148
}
149
 
150
// Schreibt einen String auf das LCD
151
 
152
void lcd_string(char *data)
153
{
154
    while (*data)
155
    {
156
        lcd_data(*data);
157
        data++;
158
    }
159
}
------------------------------------------------

Die Includedatei lcd_routines.h enthält die Leitungszuordnung für die 
LCD-Ansteuerung und die Prototypen für die LCD Funktionen.


----------------------------------------------- lcd_routines.h
1
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
2
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
3
//
4
5
void lcd_data(unsigned char temp1);
6
void lcd_string(char *data);
7
void lcd_command(unsigned char temp1);
8
void lcd_enable(void);
9
void lcd_init(void);
10
void lcd_home(void);
11
void lcd_clear(void);
12
void set_cursor(uint8_t x, uint8_t y);
13
 
14
#if 0
15
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
16
#define F_CPU 8000000
17
#endif
18
 
19
// LCD Befehle
20
 
21
#define CLEAR_DISPLAY 0x01
22
#define CURSOR_HOME   0x02
23
 
24
// Pinbelegung für das LCD, an verwendete Pins anpassen
25
 
26
// Änderung des LCD Anschlusses
27
28
// DB4 bis DB7 des LCD sind mit PD4 bis PD7 des AVR verbunden
29
#define LCD_PORT      PORTD
30
#define LCD_DDR       DDRD
31
#define LCD_EN        PD3
32
#define LCD_RS        PD2
33
#define LCD_DB7       PD7
34
#define LCD_DB6       PD6
35
#define LCD_DB5       PD5
36
#define LCD_DB4       PD4
------------------------------------------------------


--------------------------------------------- test.c
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdlib.h>
4
 
5
#include "lcd_routines.h"
6
7
int main(void)
8
{
9
10
  lcd_init();
11
  set_cursor(0,1);
12
  lcd_string("Test Zeile 1");
13
  set_cursor(0,2);
14
  lcd_string("Test Zeile 2");
15
  
16
  while(1)
17
  {
18
  }
19
}
--------------------------------------------------

von Marco H. (spider-man)


Angehängte Dateien:

Lesenswert?

Hallo,
erstmal Dankeschön für die Zusendung des Source-Codes.
Habe den Source-Code ausprobiert. Leider kommt hier immer eine 
Fehlermeldung.

Gruß
Marco

von Marco H. (spider-man)


Angehängte Dateien:

Lesenswert?

Hallo,
vielen Dank.
Ichbin noch nicht weiter gekommen. Anbei der Code.

Gruß
Marco

von Fritz M. (Gast)


Angehängte Dateien:

Lesenswert?

Hier geht Dein Code sauber durch.


Grüße Fritz M.

von Fritz M. (Gast)


Lesenswert?

Damit Dein LCD auch richtig angesprochen wird, müßtest Du natürlich noch 
die Anpassungen in der lcd-routines.h vornehmen.
1
////////////////////////////////////////////////////////////////////////////////
2
// Pinbelegung für das LCD, an verwendete Pins anpassen
3
// Alle LCD Pins müssen an einem Port angeschlossen sein und die 4
4
// Datenleitungen müssen auf aufeinanderfolgenden Pins liegen
5
 
6
//  LCD DB4-DB7 <-->  PORTD Bit PD4-PD7
7
#define LCD_PORT      PORTD
8
#define LCD_DDR       DDRD
9
#define LCD_DB        PD4
10
 
11
//  LCD RS      <-->  PORTD Bit PD4     (RS: 1=Data, 0=Command)
12
#define LCD_RS        PD2
13
 
14
//  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
15
#define LCD_EN        PD3
16
 
17
////////////////////////////////////////////////////////////////////////////////

von Marco H. (spider-man)


Lesenswert?

Leider nicht. Die Einstellungen hatte ich schon so, bis auf die 
Frequenz, die war aber nicht ursächlich.
Ich benutze übrigens AVRStudio4, mit AVRStudio5 funktioniert der 
Programmer nicht.

Viele Grüße
Marco

von Fritz M. (Gast)


Lesenswert?

Wird der Code den jetzt ohne Fehler kompiliert? Ist R/W am Display mit 
Masse verbunden?

Der Anschluss Vee benötigt eine Positve Spannung. Vdd-Vo(Vee) Typ 4.2 V

           10 - 20k
           ______
Vss  -----|________|------- Vdd
              ^
              |
              |
             Vee

Grüße
Fritz M.

von Fritz M. (Gast)


Lesenswert?

Ich habe hier AVR Studio 4.19 (build 730) und das AVR Toolchain 3.3.0 
(AVR-GCC) installiert.

Direktlinks unter:

http://www.mikrocontroller.net/articles/AVR-Studio

Grüße Fritz M.

von Marco H. (spider-man)


Angehängte Dateien:

Lesenswert?

Nee, der Fehler beim Compilieren ist nach wie vor da. Ich benutze auch 
Version 4.19.
Fehlt bei mir irgendein File (s. Anhang)???

Gruß
Marco

von Fritz M. (Gast)


Angehängte Dateien:

Lesenswert?

So sieht es bei mir aus.

Ich vermisse bei Dir das File mit der main routine. lcd-test.c oder 
test.c

Bitte achte auch darauf welchen Code du verwendest. Bei dem von mir 
geposteten sind die Bezeichnungen mit Unterstrich bei dem von Dir 
geposteten mit Bindestrich.

lcd_routines.h lcd_routines.c > lcd-routines.h lcd-routines.c

Solange da nicht gemischt wird, sollte das aber kein problem sein.

Ich habe beide Versionen erfolgreich kompiliert. Sollten also in Ordnung 
sein.

Ich habe die Dateien lcd-routines.h lcd-routines.c und lcd-test.c im 
Projektordner und wie im Anhang in den "Projektbaum" eingefügt. Also 
lcd-routines.c und lcd-test.c unter Source Files und die lcd_routines.h 
unter Header Files.

Grüße
Fritz M.

von Fritz M. (Gast)


Lesenswert?

Fritz M. schrieb:
> unter Source Files und die lcd_routines.h
> unter Header Files.

Sollte natürlich lcd-routines.h sein.

von Marco H. (spider-man)


Lesenswert?

Hallo,
erstmal zwischendurch danke für die große Geduld. Habe alles befolgt, 
aber es funktioniert trotzdem nicht. Bin mittlerweile mit meinem Latein 
am Ende. Habe nochmals das gesamte Forum durchstöbert, aber anscheinend 
habe nur ich ein Problem mit dem Display.
Kannst Du mir vielleicht Dein komplettes Verzeichnis inkl. Include-Files 
als zip-Datei zumailen (spider-man@t-online.de)?

Gruß
Marco

von Joe (Gast)


Lesenswert?

Die 4 freien DAtenleitungen müssen auf GND liegen !

von Joe (Gast)


Lesenswert?

Ist die Quarzfrequenz richtig eingetragen?

von Joe (Gast)


Lesenswert?

Erzeugt ein Programm für einen Sekundentakt (an LED) auch wirklich einen 
Sekundentakt ?

von spess53 (Gast)


Lesenswert?

Hi

>Die 4 freien DAtenleitungen müssen auf GND liegen !

Blödsinn. Der Display-Controller hat interne Pull-Up-Widerstände. Nicht 
einfach alles nachplappern.

MfG Spess

von Fritz M. (Gast)


Angehängte Dateien:

Lesenswert?

Marco H. schrieb:
> Kannst Du mir vielleicht Dein komplettes Verzeichnis inkl. Include-Files
> als zip-Datei zumailen


Hier die gewünschten Dateien. Leider nur als WinRAR-Archiv. Kostenlose 
Testversion unter http://www.winrar.de/

Im Ordner Test befinden sich die Dateien, die ich weiter oben gepostet 
hatte.
Im Ordner lcd-test, die Dateien von Dir.

Sollten sich die Projekte nicht kompilieren lassen, würde ich AVR-Studio 
neu installieren.

Ich empfehle das AVR Studio 4.19 (build 730) und das AVR Toolchain 3.3.0
(AVR-GCC) zu installieren. Winavr falls installiert, vorher 
deinstallieren.

Direktlinks unter:

http://www.mikrocontroller.net/articles/AVR-Studio

Grüße
Fritz M.

von Achim M. (minifloat)


Lesenswert?

Joe schrieb:
> Die 4 freien DAtenleitungen müssen auf GND liegen !

spess53 schrieb:
> Der Display-Controller hat interne Pull-Up-Widerstände.

Ich kaufe ein "Pull-Down". mfg mf

von Fritz M. (Gast)


Lesenswert?

Habe gerade noch einen Fehler gefunden.

Damit der Code im Ordner lcd-test mit deinem LCD funktioniert muß in der 
Datei lcd-routines.h noch die Zeile
1
//  LCD DB4-DB7 <-->  PORTD Bit PD4-PD7
2
#define LCD_PORT      PORTD
3
#define LCD_DDR       DDRD
4
#define LCD_DB        PD0  // ändern in #define LCD_DB        PD4

geändert werden.

Grüße
Fritz M.

von Marco H. (spider-man)


Lesenswert?

Hallo,
funktioniert jetzt nach noch langem Probieren. Vielen Dank für die 
Unterstützung. Alleine hätte ich das nicht hinbekommen. Bin nun seit 
heute dabei, mich meiner eigentlichen Hauptaufgabe zu widmen - der 
Drehzahlregelung. Die Drehzahl kann ich bereits mit einem Hall-Sensor 
erfassen. Bin jetzt auch auf einen ATMega32 umgestiegen, da dieser zwei 
Takt-Eingänge hat. Vielen Dank nochmals.

Gruß
Marco

von silch12 (Gast)


Lesenswert?

Hallo Marco
kannst du mir sagen, was deine Lösung für das Problem war, den ich stehe 
jetzt genau vor dem selben Problem!

von DirkZ (Gast)


Lesenswert?

Ich glaube kaum, dass Marco sich nach fast 2 Jahren meldet. Mach' besser 
einen eigenen Thread auf und post deinen Code.

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.