C-Code für LCD-Display (Displaytech 162B)

OP #1990937
Lesenswert?

Nach eingehender Prüfung konnte ich bis jetzt keinen Fehler feststellen.
Anbei mein Schaltplan, das Datenblatt und der verwendete 
Initialisierungscode.

Der Kontrast des Displays lässt sich regeln, wird aber nur in der 1. 
Zeile angezeigt.

1
/*
2
  LCD Ausgabe für Hitachi HD44780 kompatible LCD Controller
3

4
  ATMEGA8/16/32 und kompatibel
5

6
  Dieses Beispiel sollte mit allen HD44780 kompatiblen LCD
7
   Displays funktionieren. 
8
*/
9

10
#define F_CPU    3686400
11

12
#include <avr/io.h>
13
#include <util/delay.h>
14

15
/*
16
*  BITTE HIER IHRE VERWENDETEN PINS KONFIGURIEREN!
17
*
18
*  Standardkonfiguration:
19
*   PORTD7 = LCD D7
20
*   PORTD6 = LCD D6
21
*   PORTD5 = LCD D5
22
*   PORTD4 = LCD D4
23
*
24
*/
25
#define  LCDPORT      PORTD
26
#define  LCDDDR      DDRD
27
#define LCD_PIN_RS    2
28
#define LCD_PIN_E    3
29
#define LCD_PIN_D4    4
30
#define LCD_PIN_D5    5
31
#define LCD_PIN_D6    6
32
#define LCD_PIN_D7    7
33

34

35
/* LCD STEUERBEFEHLE **********  */
36

37
#define LCD_CLEAR    0x01
38
#define LCD_HOME    0x02
39
#define LCD_ON      0x0C  /* 0x0C = Cursor unsichtbar */
40
#define LCD_ON      0x0E    /* 0x0E = Cursor sichtbar */
41
#define LCD_OFF      0x08
42

43
/* HILFSDEFINITIONEN **********  */
44

45
#define  BEFEHL      0
46
#define DATEN      1
47
#define sbi(sfr, bit)   (sfr|=(1<<bit))
48
#define cbi(sfr, bit)   (sfr&=~(1<<bit)) 
49

50

51
/****** Schickt ein Byte an den LCD Controller */
52
void lcd_send(unsigned char type, unsigned char c)
53
{
54
  if (type==BEFEHL)
55
    cbi(LCDPORT, LCD_PIN_RS); /* RS=0: Befehl folgt ... */
56
  else
57
    sbi(LCDPORT, LCD_PIN_RS); /* RS=1: Daten folgen ... */
58

59

60
  /* (1) ==== HIGH NIBBLE wird gesendet */
61
  if (bit_is_set(c, 7)) sbi(LCDPORT, LCD_PIN_D7); else cbi(LCDPORT, LCD_PIN_D7);
62
  if (bit_is_set(c, 6)) sbi(LCDPORT, LCD_PIN_D6); else cbi(LCDPORT, LCD_PIN_D6);
63
  if (bit_is_set(c, 5)) sbi(LCDPORT, LCD_PIN_D5); else cbi(LCDPORT, LCD_PIN_D5);
64
  if (bit_is_set(c, 4)) sbi(LCDPORT, LCD_PIN_D4); else cbi(LCDPORT, LCD_PIN_D4);
65

66
  /* Flanke zur Übernahme der Daten schicken ... */
67
  sbi(LCDPORT, LCD_PIN_E);
68
  cbi(LCDPORT, LCD_PIN_E);
69

70
  
71
  /* (2) ==== LOW NIBBLE wird gesendet */
72
  if (bit_is_set(c, 3)) sbi(LCDPORT, LCD_PIN_D7); else cbi(LCDPORT, LCD_PIN_D7);
73
  if (bit_is_set(c, 2)) sbi(LCDPORT, LCD_PIN_D6); else cbi(LCDPORT, LCD_PIN_D6);
74
  if (bit_is_set(c, 1)) sbi(LCDPORT, LCD_PIN_D5); else cbi(LCDPORT, LCD_PIN_D5);
75
  if (bit_is_set(c, 0)) sbi(LCDPORT, LCD_PIN_D4); else cbi(LCDPORT, LCD_PIN_D4);
76

77
  /* Flanke zur Übernahme der Daten schicken ... */
78
  sbi(LCDPORT, LCD_PIN_E);
79
  cbi(LCDPORT, LCD_PIN_E);
80

81
  
82
  /* (3) Auf den LCD Controller warten ...*/
83
  _delay_ms(5);
84
}
85

86

87
/****** Stellt eine Zeichenkette am LCD dar */
88
void lcd_write(char *t)
89
{
90
  unsigned char i;
91
  for (i=0;i<255;i++)
92
  {
93
    if (t[i]==0) // String-Ende? Dann raus hier ...
94
      return;
95
    else 
96
      lcd_send(DATEN, t[i]);
97
  }
98
}
99

100

101
/****** Initialisierung des LCD Controllers */
102
void lcd_init()
103
{
104
  /* Port auf Ausgang schalten */
105
  LCDPORT = 0x00;
106
  LCDDDR  = 0xFF;
107

108
  _delay_ms(50); // Warten bis LCD bereit ...
109

110
  /* 4-bit Modus konfigurieren */
111
  sbi(LCDPORT, LCD_PIN_D5);
112
  cbi(LCDPORT, LCD_PIN_D4);
113

114
  /* 4-Bit Modus starten ... */ 
115
  sbi(PORTD, LCD_PIN_E);
116
  cbi(PORTD, LCD_PIN_E);
117
  _delay_ms(5); 
118

119
  /* 2 Zeilen, 4-Bit Modus */
120
  lcd_send(BEFEHL, 0x28);
121

122
  lcd_send(BEFEHL, LCD_OFF);
123
  lcd_send(BEFEHL, LCD_CLEAR);
124

125
  lcd_send(BEFEHL, 0x06);
126
  lcd_send(BEFEHL, LCD_ON);
127
}
128

129

130
/****** Hilfsfunktion: Warte i Sekunden */
131
void sekunde(char i)
132
{
133
  unsigned char k;
134
  for (;i>0;i--)
135
  {
136
    for (k=0;k<10;k++)
137
      _delay_ms(100);
138
  }
139
}
140

141

142
/****** HAUPTPROGRAMM *****/
143

144
int main(void)
145
{
146
  lcd_init();
147
  lcd_write("Starting...");
148

149
  while (1)
150
  {
151

152
    sekunde(2);
153
    lcd_send(BEFEHL, LCD_CLEAR);
154
    lcd_write(" Test");
155

156
    sekunde(2);
157
    lcd_send(BEFEHL, LCD_CLEAR);
158
    lcd_write(" ---LCD DEMO---");
159
  }
160
}
Angehängte Dateien:
Gast #1991009
Lesenswert?

Hi

>Du solltest die unbenutzten Datenpins (DB0-DB3) auf GND legen. Offene
>Eingänge können jedes beliebige Potential annehmen. So kann es dann
>seind as die initialisierung mal klappt, und mal nicht.

Vor solchen Vorschlägen sollte man das Datenblatt lesen. 
Displaycontroller haben im allgemeinen einen integrierten 
Pull-Up-widerstand. Eine Verbindung nach GND ist da eher 
kontraproduktiv.

Datenblatt vom KS0070:

DB0~DB3  'During 4-bit bus mode open these pins'

MfG Spess
#1991496
Lesenswert?

Heimo G. schrieb:
> Die Displayanzeige funktioniert grundsätzlich. Allerdings erhalte ich in
> der 1. Zeile nur wirres Zeug (000/0000////<<<).

Wenn du prinzipiell eine Anzeige hast, dann liegt das Problem nicht mehr 
in der Init oder im Function Set.

* Anzeigefunktion untersuchen
* Nochmal die Verdrahtung kontrollieren, ob da nicht 2 Datenleitungen 
vertauscht wurden.
OP #1991500
Lesenswert?

Habs schon!!!

Ich habe die Init-Routine wie folgt geändert:
1
/****** Initialisierung des LCD Controllers */
2
void lcd_init()
3
{
4
  /* Port auf Ausgang schalten */
5
  LCDPORT = 0x00;
6
  LCDDDR  = 0xFF;
7

8
  _delay_ms(50); // Warten bis LCD bereit ...
9

10
  /* 4-bit Modus konfigurieren ------Function-Set 1*/    
11
  sbi(LCDPORT, LCD_PIN_D5);
12
  cbi(LCDPORT, LCD_PIN_D4);
13

14
  _delay_ms(50);
15
  /* 4-bit Modus konfigurieren ------Function-Set 2*/
16
  sbi(LCDPORT, LCD_PIN_D5);
17
  cbi(LCDPORT, LCD_PIN_D4);
18
  
19
  _delay_ms(1);
20
  /* 4-bit Modus konfigurieren ------Function-Set 3*/
21
  sbi(LCDPORT, LCD_PIN_D5);
22
  cbi(LCDPORT, LCD_PIN_D4);
23

24
  /* 4-Bit Modus starten ... */ 
25
  sbi(PORTD, LCD_PIN_E);
26
  cbi(PORTD, LCD_PIN_E);
27
  _delay_ms(5); 
28

29
  /* 2 Zeilen, 4-Bit Modus */
30
  lcd_send(BEFEHL, 0x28);
31

32
  lcd_send(BEFEHL, LCD_OFF);
33
  lcd_send(BEFEHL, LCD_CLEAR);
34

35
  lcd_send(BEFEHL, 0x06);
36
  lcd_send(BEFEHL, LCD_ON);
37
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren