Forum: Mikrocontroller und Digitale Elektronik Nach dem Flashen des ersten Programms keine Anzeige im LCD


von Patrick L. (masterkennie)


Lesenswert?

Hallo,
auch ich bin nun dabei mich in die µC-Programmierung einzuarbeiten. 
Nachdem ich heute meinen ersten Test mit dem myAVR-Board und dem 
LCD-AddOn durchführen wollte hab ich ein eher enttäuschendes Ergebnis 
damit erzielt.

Nach dem erstellen des Hex-Files (fehlerfrei) und dem Brennen des 
Hexfiles wird im LCD nix angezeigt außer dem schwarzen Balken. Ein Test 
per myAVR-Quickprog verlief jedoch erfolgreich.

Meine Frage ist jetzt natürlich, woran kann das liegen? Wo muss ich den 
Fehler suchen?

Meine main.c
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
4
5
int main(void){
6
  
7
  lcd_init();
8
  
9
  lcd_clear();
10
  
11
  lcd_home();
12
  
13
  lcd_string("Test");
14
15
16
  while(1){
17
  
18
  }
19
  return 0;
20
}

Die lcd-routines.c
1
/*Testdatei aus dem AVR-Tutorial*/
2
3
//Pinbelegung über defines einstellbar
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include "lcd-routines.h"
7
8
//LCD-Befehle
9
#define CLEAR_DISPLAY 0x01
10
#define CURSOR_HOME 0x02
11
12
//Pinbelegung für das LCD
13
#define LCD_PORT  PORTD
14
#define LCD_DDR   DDRD
15
#define LCD_RS    4
16
#define LCD_EN    5
17
18
19
//Sendet ein Datenbyte an das LCD
20
21
void lcd_data(unsigned char temp1){
22
23
  unsigned char temp2 = temp1;
24
  
25
  LCD_PORT |= (1<<LCD_RS);  //RS auf 1 setzen Operator |= sagt: Das Ergebnis des Ausdruckes auf der 
26
                //                  rechten Seite nach links schieben
27
                //                  |= ist ein Zuweisungsoperator!
28
  temp1 = temp1 >> 4;
29
  temp1 = temp1 & 0x0F;    // &= AND
30
  LCD_PORT &= 0XF0;
31
  LCD_PORT |= temp1;
32
  lcd_enable();
33
  
34
  temp2 = temp2 & 0x0F;
35
  LCD_PORT &= 0xF0;
36
  LCD_PORT |= temp2;
37
  lcd_enable();
38
  
39
  _delay_ms(42);
40
}
41
42
//sendet einen Befehl an das LCD
43
44
void lcd_command(unsigned char temp1){
45
46
  unsigned char temp2 = temp1;
47
  
48
  LCD_PORT &= ~ (1 << LCD_RS);   //RS Setzen
49
  temp1 = temp1 >> 4;        //oberes Nibble holen
50
  temp1 = temp1 & 0x0F;      //maskieren
51
  LCD_PORT &= 0xF0;
52
  LCD_PORT |= temp1;        //setzen
53
  lcd_enable();
54
  
55
  temp2 = temp2 & 0x0F;      //unteres Nibble holen und maskieren
56
  LCD_PORT &= 0xF0;
57
  LCD_PORT |= temp2;        //setzen
58
  lcd_enable();
59
  
60
  _delay_ms(42);
61
62
}
63
64
//Den enable Puls erzeugen
65
66
void lcd_enable(void){
67
68
  LCD_PORT |= (1<<LCD_EN);
69
  _delay_ms(10);          //kurze Pause machen
70
  LCD_PORT &= ~ (1<<LCD_EN);
71
  
72
}
73
74
75
//Initialisierung
76
//Die Initialisierung muss am Anfang jedes LCD-Porgramms stattfinden
77
78
void lcd_init(void){
79
80
  LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN); //Port auf Ausgang schalten
81
  
82
  //muss 3 mal hintereinander gesendet werden zur Initialisierung
83
  
84
  _delay_ms(15);
85
  LCD_PORT &= 0xF0;
86
  LCD_PORT |= 0x03;
87
  LCD_PORT &= ~ (1<<LCD_RS);   //RS auf 0
88
  lcd_enable();
89
  
90
  _delay_ms(20);
91
  lcd_enable();
92
  
93
  _delay_ms(10);
94
  lcd_enable();
95
  
96
  //4-Bit Modus aktivieren
97
  LCD_PORT &= 0xF0;
98
  LCD_PORT |= 0x02;
99
  lcd_enable();
100
  
101
  //Der Befehlssatz kann im Datenblatt des LCD nachgelesen werden
102
  //4-Bit / 2 Zeilen / 5x7
103
  lcd_command(0x28);
104
  
105
  //Display ein / Cursor aus / kein Blinken
106
  lcd_command(0x0C);
107
  
108
  //inkrement / kein scrollen
109
  lcd_command(0x06);
110
  
111
  //alle bisherigen Zeichen vom LCD löschen
112
  lcd_clear();
113
  
114
}
115
116
//Sendet den Befehl zur Löschung des Displays
117
118
void lcd_clear(void){
119
120
  lcd_command(CLEAR_DISPLAY);
121
  _delay_ms(20);
122
  
123
}
124
125
126
//Sendet den Befehl Cursor auf Homeposition
127
128
void lcd_home(void){
129
130
  lcd_command(CURSOR_HOME);
131
  _delay_us(20);
132
133
}
134
135
136
//Setzt den Cursor in Zeile y 1...4 Spalte 0...15
137
138
void set_cursor(uint8_t x , uint8_t y){
139
140
  switch (y){
141
    case 1: lcd_command(0x80 + 0x00 + x);  //1.Zeile
142
    case 2: lcd_command(0x80 + 0x40 + x);  //2.Zeile
143
    case 3: lcd_command(0x80 + 0x10 + x);  //3.Zeile
144
    case 4: lcd_command(0x80 + 0x50 + x);  //4.Zeile
145
  }
146
  
147
}
148
149
150
//Schreibt einen String aufs Display
151
152
void lcd_string(char *data){
153
154
  while(*data){
155
  
156
    lcd_data(*data);
157
    data++;
158
  
159
  }
160
161
}

Und die lcd-routines.h
1
/*Testdatei aus dem AVR-Tutorial*/
2
3
  void lcd_data(unsigned char temp1);
4
  void lcd_command(unsigned char temp1);
5
  void lcd_enable(void);
6
  void lcd_init(void);
7
  void lcd_home(void);
8
  void lcd_clear(void);
9
  void set_cursor(uint8_t x, uint8_t y);

von Andreas K. (a-k)


Lesenswert?

Diese Pause ist aber ein bischen sehr "kurz":
_delay_ms(10);          //kurze Pause machen

Kann es sein, dass dir der Unterschied zwischen Mikro- und Millisekunden 
nicht geläufig ist?

von holger (Gast)


Lesenswert?

>Ein Test per myAVR-Quickprog verlief jedoch erfolgreich.

Da hat das Display was angezeigt ?

>Meine Frage ist jetzt natürlich, woran kann das liegen? Wo muss ich den
>Fehler suchen?

Beim Anschluss des Displays. Vieleicht ist es nicht wie im Tutorial
angeschlossen.

von Patrick L. (masterkennie)


Lesenswert?

Andreas Kaiser wrote:
> Diese Pause ist aber ein bischen sehr "kurz":
> _delay_ms(10);          //kurze Pause machen
>
> Kann es sein, dass dir der Unterschied zwischen Mikro- und Millisekunden
> nicht geläufig ist?

Hallo,
doch sicher ist mir der Unterschied zwischen µ und m bekannt. Ich hab 
jedoch keinerlei Erfahrungen was die delays angeht und mich daher auf 
die im Tutorial angegebenen Zeiten verlassen (sie z.T. sogar um 10-15ms 
erhöht).

Was den Anschluss des LCD angeht, daran hatte ich auch schon gedacht und 
daher die Pinangaben mit den Pins auf dem Board verglichen. RS geht an 
PD2 des Controllers (Pin4) und EN geht an PD3 des Controllers (Pin5).

Mit der myAVR-Testsoftware hat das Display den Test-Text fehlerfrei 
angezeigt.

von Andreas K. (a-k)


Lesenswert?

Patrick Leier wrote:

> doch sicher ist mir der Unterschied zwischen µ und m bekannt.

Sicher? Auch dann wenn der C Zeichensatz kein µ mag und daher gerne "u" 
verwendet wird?

> die im Tutorial angegebenen Zeiten verlassen (sie z.T. sogar um 10-15ms
> erhöht).

Nur steht im Tutorial _delay_us(1) drin [1 Mikrosekunde], bei dir 
_delay_ms(10) [10 Millisekunden]. Was schon ziemlich viel mehr ist.

von holger (Gast)


Lesenswert?

Die Datenleitungen am AVR sind bei deinem Display anders
angeschlossen als im Tutorial. Das musst du in der
Software korrigieren.

von Patrick L. (masterkennie)


Lesenswert?

Hallo,
hmm, dann steh ich da jetzt etwas auf dem Schlauch. Denn die vier 
Datenleitungen des LCD (Pin11-14) sind am PORTD des Controllers 
angeschlossen, so wie auch in der lcd-routines.c definiert, oder versteh 
ich da jetzt was komplett verkehrt?

von holger (Gast)


Lesenswert?

Tutorial:

Pin #-LCD  Bezeichnung-LCD  Pin-µC
4  RS  PD4 am AVR
6  E  PD5 am AVR
11  DB4  PD0 am AVR
12  DB5  PD1 am AVR
13  DB6  PD2 am AVR
14  DB7  PD3 am AVR


Dein Board:

4  RS  PD2 am AVR
6  E  PD3 am AVR
11  DB4  PD4 am AVR
12  DB5  PD5 am AVR
13  DB6  PD6 am AVR
14  DB7  PD7 am AVR

von Patrick L. (masterkennie)


Lesenswert?

Ohh,
danke dir. die Details hab ich zu so später Stunde dann doch übersehen, 
danke nochmals.

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.