Forum: Compiler & IDEs LCD Initialisierung scheitert Atmel8


von patrick b. (calalex)


Angehängte Dateien:

Lesenswert?

Hallo,
ich nutze einen atmel8 und ein DIP162-D LCD und programmiere mit 
AtmelStudio 6. Die AVR programmierung klappt und ich kann auch eine LED 
zum blinken bringen. Leider kann ich das LCD nicht initialisieren. Habe 
den Code aus Beispielen übernommen und angepasst. Beim Kompilieren kommt 
auch kein Fehler. Würde mich über Feedback sehr freuen!
1
#ifndef LCD_ROUTINES_H
2
#define LCD_ROUTINES_H
3
4
void lcd_string( const char *data );
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);
10
11
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
12
13
#ifndef F_CPU
14
#define F_CPU 4000000
15
#endif
16
17
// LCD Befehle
18
19
#define CLEAR_DISPLAY 0x01
20
#define CURSOR_HOME   0x02
21
22
// Pinbelegung für das LCD, an verwendete Pins anpassen
23
24
#define LCD_PORT_4    PORTC
25
#define LCD_DDR_4     DDRC
26
#define LCD_D4      PD0
27
28
#define LCD_PORT_5    PORTC
29
#define LCD_DDR_5     DDRC
30
#define LCD_D5      PC1
31
32
#define LCD_PORT_6    PORTC
33
#define LCD_DDR_6     DDRC
34
#define LCD_D6      PC2
35
36
#define LCD_PORT_7    PORTC
37
#define LCD_DDR_7     DDRC
38
#define LCD_D7    PC3
39
40
#define LCD_RS_PORT   PORTB
41
#define LCD_RS_DDR    DDRB
42
#define LCD_RS        PB3
43
44
#define LCD_EN1_PORT  PORTB
45
#define LCD_EN1_DDR    DDRB
46
#define LCD_EN1       PB5
47
48
#define LCD_BOOTUP_MS           15
49
#define LCD_ENABLE_US           20
50
#define LCD_WRITEDATA_US        46
51
#define LCD_COMMAND_US          42
52
53
#define LCD_SOFT_RESET_MS1      5
54
#define LCD_SOFT_RESET_MS2      1
55
#define LCD_SOFT_RESET_MS3      1
56
#define LCD_SET_4BITMODE_MS     5
57
58
#define LCD_CLEAR_DISPLAY_MS    2
59
#define LCD_CURSOR_HOME_MS      2
60
61
#define LCD_DDADR_LINE1         0x00
62
#define LCD_DDADR_LINE2         0x40
63
64
65
66
// Set Entry Mode ------------- 0b000001xx
67
#define LCD_SET_ENTRY           0x04
68
69
#define LCD_ENTRY_DECREASE      0x00
70
#define LCD_ENTRY_INCREASE      0x02
71
#define LCD_ENTRY_NOSHIFT       0x00
72
#define LCD_ENTRY_SHIFT         0x01
73
74
// Set Display ---------------- 0b00001xxx
75
#define LCD_SET_DISPLAY         0x08
76
77
#define LCD_DISPLAY_OFF         0x00
78
#define LCD_DISPLAY_ON          0x04
79
#define LCD_CURSOR_OFF          0x00
80
#define LCD_CURSOR_ON           0x02
81
#define LCD_BLINKING_OFF        0x00
82
#define LCD_BLINKING_ON         0x01
83
84
// Set Shift ------------------ 0b0001xxxx
85
#define LCD_SET_SHIFT           0x10
86
87
#define LCD_CURSOR_MOVE         0x00
88
#define LCD_DISPLAY_SHIFT       0x08
89
#define LCD_SHIFT_LEFT          0x00
90
#define LCD_SHIFT_RIGHT         0x04
91
92
// Set Function --------------- 0b001xxxxx
93
#define LCD_SET_FUNCTION        0x20
94
95
#define LCD_FUNCTION_4BIT       0x00
96
#define LCD_FUNCTION_8BIT       0x10
97
#define LCD_FUNCTION_1LINE      0x00
98
#define LCD_FUNCTION_2LINE      0x08
99
#define LCD_FUNCTION_5X7        0x00
100
#define LCD_FUNCTION_5X10       0x04
101
102
#define LCD_SOFT_RESET          0x30
103
104
// Set CG RAM Address --------- 0b01xxxxxx  (Character Generator RAM)
105
#define LCD_SET_CGADR           0x40
106
107
#define LCD_GC_CHAR0            0
108
#define LCD_GC_CHAR1            1
109
#define LCD_GC_CHAR2            2
110
#define LCD_GC_CHAR3            3
111
#define LCD_GC_CHAR4            4
112
#define LCD_GC_CHAR5            5
113
#define LCD_GC_CHAR6            6
114
#define LCD_GC_CHAR7            7
115
116
// Set DD RAM Address --------- 0b1xxxxxxx  (Display Data RAM)
117
#define LCD_SET_DDADR           0x80
118
119
#endif

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
11
// sendet ein Datenbyte an das LCD
12
13
void lcd_data(unsigned char temp1)
14
{
15
  unsigned char temp2 = temp1;
16
  
17
  LCD_RS_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
18
  
19
  temp1 = temp1 >> 4;
20
  temp1 = temp1 & 0x0F;
21
  
22
  LCD_PORT_4 &= ~(1<<LCD_D4);
23
  LCD_PORT_5 &= ~(1<<LCD_D5);
24
  LCD_PORT_6 &= ~(1<<LCD_D6);
25
  LCD_PORT_7 &= ~(1<<LCD_D7);
26
  
27
  if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
28
  if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
29
  if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
30
  if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
31
  lcd_enable();
32
  
33
  
34
  
35
  temp2 = temp2 & 0x0F;
36
  
37
  LCD_PORT_4 &= ~(1<<LCD_D4);
38
  LCD_PORT_5 &= ~(1<<LCD_D5);
39
  LCD_PORT_6 &= ~(1<<LCD_D6);
40
  LCD_PORT_7 &= ~(1<<LCD_D7);
41
  
42
  if(temp2 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
43
  if(temp2 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
44
  if(temp2 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
45
  if(temp2 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
46
  lcd_enable();
47
48
  
49
  _delay_us(420);
50
}
51
52
// sendet einen Befehl an das LCD
53
54
void lcd_command(unsigned char temp1)
55
{
56
  unsigned char temp2 = temp1;
57
  
58
  LCD_RS_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen
59
  
60
  temp1 = temp1 >> 4;              // oberes Nibble holen
61
  temp1 = temp1 & 0x0F;
62
  
63
  LCD_PORT_4 &= ~(1<<LCD_D4);
64
  LCD_PORT_5 &= ~(1<<LCD_D5);
65
  LCD_PORT_6 &= ~(1<<LCD_D6);
66
  LCD_PORT_7 &= ~(1<<LCD_D7);            // maskieren
67
  
68
  if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
69
  if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
70
  if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
71
  if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
72
  lcd_enable();
73
  
74
  temp2 = temp2 & 0x0F;
75
  
76
  LCD_PORT_4 &= ~(1<<LCD_D4);
77
  LCD_PORT_5 &= ~(1<<LCD_D5);
78
  LCD_PORT_6 &= ~(1<<LCD_D6);
79
  LCD_PORT_7 &= ~(1<<LCD_D7);        // unteres Nibble holen und maskieren
80
  
81
  if(temp2 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
82
  if(temp2 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
83
  if(temp2 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
84
  if(temp2 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
85
  lcd_enable();
86
  
87
  _delay_us(420);
88
}
89
90
// erzeugt den Enable-Puls
91
92
void lcd_enable(void)
93
{
94
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen
95
     _delay_us(100);
96
  // http://www.mikrocontroller.net/topic/81974#685882
97
  LCD_EN1_PORT |= (1<<LCD_EN1);
98
  
99
  
100
  _delay_us(100);                   // kurze Pause
101
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
102
  // http://www.mikrocontroller.net/topic/80900
103
  LCD_EN1_PORT &= ~(1<<LCD_EN1);
104
  
105
  
106
  
107
}
108
// Initialisierung:
109
// Muss ganz am Anfang des Programms aufgerufen werden.
110
111
void lcd_init(void)
112
{  
113
  _delay_ms(150);
114
  // Ports auf Ausgang schalten
115
  LCD_DDR_4 |=(1<<LCD_D4);
116
  LCD_DDR_5 |=(1<<LCD_D5);
117
  LCD_DDR_6 |=(1<<LCD_D6);
118
  LCD_DDR_7 |=(1<<LCD_D7);
119
  LCD_EN1_DDR |= (1<<LCD_EN1);
120
  LCD_RS_DDR  |= (1<<LCD_RS);
121
  
122
  // muss 3mal hintereinander gesendet werden zur Initialisierung
123
  
124
  _delay_ms(150);
125
  
126
  LCD_PORT_4 |=  (1<<LCD_D4);
127
  LCD_PORT_5 |=  (1<<LCD_D5);
128
  LCD_PORT_6 &= ~(1<<LCD_D6);
129
  LCD_PORT_7 &= ~(1<<LCD_D7);
130
  LCD_RS_PORT &= ~(1<<LCD_RS);      // RS auf 0
131
  _delay_ms(50);
132
  lcd_enable();
133
  
134
  _delay_ms(50);
135
  lcd_enable();
136
  
137
  _delay_ms(50);
138
  lcd_enable();
139
  
140
  _delay_ms(50);
141
  
142
  // 4 Bit Modus aktivieren
143
    
144
  LCD_PORT_4 &=  ~(1<<LCD_D4);
145
  LCD_PORT_5 |=   (1<<LCD_D5);
146
  LCD_PORT_6 &=  ~(1<<LCD_D6);
147
  LCD_PORT_7 &=  ~(1<<LCD_D7);
148
  
149
  lcd_enable();
150
  _delay_ms(1);
151
  
152
  // 4Bit / 2 Zeilen / 5x7
153
  lcd_command(0x28);
154
  
155
  // Display ein / Cursor aus / kein Blinken
156
  lcd_command(0x0C);
157
  
158
  // inkrement / kein Scrollen
159
  lcd_command(0x06);
160
  
161
  lcd_clear();
162
}
163
164
// Sendet den Befehl zur Löschung des Displays
165
166
void lcd_clear(void)
167
{
168
  lcd_command(CLEAR_DISPLAY);
169
  _delay_ms(50);
170
}
171
172
// Sendet den Befehl: Cursor Home
173
174
void lcd_home(void)
175
{
176
  lcd_command(CURSOR_HOME);
177
  _delay_ms(5);
178
}
179
180
// setzt den Cursor in Zeile y (1..4) Spalte x (0..15)
181
182
void set_cursor(uint8_t x, uint8_t y)
183
{
184
  uint8_t tmp;
185
  
186
  switch (y) {
187
    case 1: tmp=0x80+0x00+x;  break;    // 1. Zeile
188
    case 2: tmp=0x80+0x40+x;  break;    // 2. Zeile
189
  }
190
  lcd_command(tmp);
191
}
192
193
// Schreibt einen String auf das LCD
194
195
void lcd_string( const char *data )
196
{
197
  while( *data != '\0' )
198
  lcd_data( *data++ );
199
}

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

von J.-u. G. (juwe)


Lesenswert?

Läuft der Controller mit der richtigen Taktfrequenz?
Alles richtig verdrahtet?
Programmieradapter abgezogen?

von patrick b. (calalex)


Lesenswert?

Taktfrequenz hab ich auf sut_cksel: intrcosc_4MHz_6ck_64MS eingestellt 
und auch in lcd-routines.h #define F_CPU 4000000 deklariert.

Verdrahtung stimmt, Portzuordnung denke ich ich ebenfalls.

Auch den Programmieradapter hab ich nach dem programmieren abgezogen.

von Karl H. (kbuchegg)


Lesenswert?

Du hast den RW Pin vom LCD an den Controller gelegt, bedienst ihn aber 
nicht vom Programm aus.

Nicht gut.

Wenn du RW nicht benutzen willst (was prinzipiell kein Problem ist), 
dann leg den Pin auf GND. Um dir das Umverdrahten zu ersparen, kannst du 
auch erst mal den µC-Pin PB4 auf Ausgang schalten und definiert dort 
eine 0 ausgeben. Aber irgendwas musst du damit machen. So wie es jetzt 
ist, hängt der in der Luft und ich weiß nicht auswendig, ob im LCD da 
ein Pullup oder Pulldown verbaut ist (wenn überhaupt).

von Karl H. (kbuchegg)


Lesenswert?

patrick Bateman schrieb:
> Taktfrequenz hab ich auf sut_cksel: intrcosc_4MHz_6ck_64MS eingestellt
> und auch in lcd-routines.h #define F_CPU 4000000 deklariert.

d.h. die 14 MHz im Schaltplan sind falsch?

: Wiederhergestellt durch User
von patrick b. (calalex)


Lesenswert?

ja ich nutz noch keinen externen Quarz, hab den als Bauelement noch 
nicht eingebaut.

von HD44780 (Gast)


Lesenswert?

patrick Bateman schrieb:
> #define LCD_PORT_4    PORTC
> #define LCD_DDR_4     DDRC
> #define LCD_D4      PD0

Das sieht ehrlich gesagt nicht so schön aus.

von patrick b. (calalex)


Lesenswert?

HD44780 schrieb:
> patrick Bateman schrieb:
>> #define LCD_PORT_4    PORTC
>> #define LCD_DDR_4     DDRC
>> #define LCD_D4      PD0
>
> Das sieht ehrlich gesagt nicht so schön aus.

wie würdest du es machen?

von J.-u. G. (juwe)


Lesenswert?

HD44780 schrieb:
> Das sieht ehrlich gesagt nicht so schön aus.
Du sagst es, ist ein "Schönheitsfehler", beeinflusst aber hier nicht die 
Funktionalität.

Was mir am Schaltplan auffällt:
Ich kenne es von diesen Displays eigentlich so, dass Vss auf GND liegt 
und VDD auf 5V. Hier ist es umgekehrt eingezeichnet.

patrick Bateman schrieb:
> wie würdest du es machen?

Statt PD0 PC0 schreiben.

von patrick b. (calalex)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wenn du RW nicht benutzen willst (was prinzipiell kein Problem ist),
> dann leg den Pin auf GND. Um dir das Umverdrahten zu ersparen, kannst du
> auch erst mal den µC-Pin PB4 auf Ausgang schalten und definiert dort
> eine 0 ausgeben. Aber irgendwas musst du damit machen. So wie es jetzt
> ist, hängt der in der Luft und ich weiß nicht auswendig, ob im LCD da
> ein Pullup oder Pulldown verbaut ist (wenn überhaupt).

Meinst du das so?

#define LCD_RW_PORT   PORTB
#define LCD_RW_DDR    DDRB
#define LCD_RW        PB4

und das in die Initialisierung?
LCD_RW &= ~(1<<PB4);

von Karl H. (kbuchegg)


Lesenswert?

patrick bateman schrieb:
> Karl Heinz Buchegger schrieb:
>> Wenn du RW nicht benutzen willst (was prinzipiell kein Problem ist),
>> dann leg den Pin auf GND. Um dir das Umverdrahten zu ersparen, kannst du
>> auch erst mal den µC-Pin PB4 auf Ausgang schalten und definiert dort
>> eine 0 ausgeben. Aber irgendwas musst du damit machen. So wie es jetzt
>> ist, hängt der in der Luft und ich weiß nicht auswendig, ob im LCD da
>> ein Pullup oder Pulldown verbaut ist (wenn überhaupt).
>
> Meinst du das so?
>
> #define LCD_RW_PORT   PORTB
> #define LCD_RW_DDR    DDRB
> #define LCD_RW        PB4
>
> und das in die Initialisierung?
> LCD_RW &= ~(1<<PB4);

Zum Beispiel.
Das DDR Register nicht vergessen um den Pin in der lcd_init auf Ausgang 
zu schalten.

von patrick b. (calalex)


Lesenswert?

Karl Heinz Buchegger schrieb:
> patrick bateman schrieb:
>> Karl Heinz Buchegger schrieb:
>>> Wenn du RW nicht benutzen willst (was prinzipiell kein Problem ist),
>>> dann leg den Pin auf GND. Um dir das Umverdrahten zu ersparen, kannst du
>>> auch erst mal den µC-Pin PB4 auf Ausgang schalten und definiert dort
>>> eine 0 ausgeben. Aber irgendwas musst du damit machen. So wie es jetzt
>>> ist, hängt der in der Luft und ich weiß nicht auswendig, ob im LCD da
>>> ein Pullup oder Pulldown verbaut ist (wenn überhaupt).
>>
>> Meinst du das so?
>>
>> #define LCD_RW_PORT   PORTB
>> #define LCD_RW_DDR    DDRB
>> #define LCD_RW        PB4
>>
>> und das in die Initialisierung?
>> LCD_RW &= ~(1<<PB4);
>
> Zum Beispiel.
> Das DDR Register nicht vergessen um den Pin in der lcd_init auf Ausgang
> zu schalten.

ja vielen Dank, hat funktioniert!

hier nochmal mein Code.


__________________________________________________________________
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
//
// Die Pinbelegung ist über defines in lcd-routines.h einstellbar

#include <avr/io.h>
#include "lcd-routines.h"
#include <util/delay.h>


// sendet ein Datenbyte an das LCD

void lcd_data(unsigned char temp1)
{
  unsigned char temp2 = temp1;

  LCD_RS_PORT |= (1<<LCD_RS);        // RS auf 1 setzen

  temp1 = temp1 >> 4;
  temp1 = temp1 & 0x0F;

  LCD_PORT_4 &= ~(1<<LCD_D4);
  LCD_PORT_5 &= ~(1<<LCD_D5);
  LCD_PORT_6 &= ~(1<<LCD_D6);
  LCD_PORT_7 &= ~(1<<LCD_D7);

  if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
  if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
  if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
  if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
  lcd_enable();



  temp2 = temp2 & 0x0F;

  LCD_PORT_4 &= ~(1<<LCD_D4);
  LCD_PORT_5 &= ~(1<<LCD_D5);
  LCD_PORT_6 &= ~(1<<LCD_D6);
  LCD_PORT_7 &= ~(1<<LCD_D7);

  if(temp2 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
  if(temp2 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
  if(temp2 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
  if(temp2 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
  lcd_enable();


  _delay_us(420);
}

// sendet einen Befehl an das LCD

void lcd_command(unsigned char temp1)
{
  unsigned char temp2 = temp1;

  LCD_RS_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen

  temp1 = temp1 >> 4;              // oberes Nibble holen
  temp1 = temp1 & 0x0F;

  LCD_PORT_4 &= ~(1<<LCD_D4);
  LCD_PORT_5 &= ~(1<<LCD_D5);
  LCD_PORT_6 &= ~(1<<LCD_D6);
  LCD_PORT_7 &= ~(1<<LCD_D7);            // maskieren

  if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
  if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
  if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
  if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
  lcd_enable();

  temp2 = temp2 & 0x0F;

  LCD_PORT_4 &= ~(1<<LCD_D4);
  LCD_PORT_5 &= ~(1<<LCD_D5);
  LCD_PORT_6 &= ~(1<<LCD_D6);
  LCD_PORT_7 &= ~(1<<LCD_D7);        // unteres Nibble holen und 
maskieren

  if(temp2 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
  if(temp2 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
  if(temp2 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
  if(temp2 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
  lcd_enable();

  _delay_us(420);
}

// erzeugt den Enable-Puls

void lcd_enable(void)
{
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
einfügen
     _delay_us(100);
  // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
  LCD_EN1_PORT |= (1<<LCD_EN1);


  _delay_us(100);                   // kurze Pause
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
verlängern
  // Beitrag "LCD -> Probleme mit Optimierungsgrad"
  LCD_EN1_PORT &= ~(1<<LCD_EN1);



}
// Initialisierung:
// Muss ganz am Anfang des Programms aufgerufen werden.

void lcd_init(void)
{
  //_delay_ms(150);

  // Ports auf Ausgang schalten
  LCD_DDR_4 |=(1<<LCD_D4);
  LCD_DDR_5 |=(1<<LCD_D5);
  LCD_DDR_6 |=(1<<LCD_D6);
  LCD_DDR_7 |=(1<<LCD_D7);
  LCD_EN1_DDR |= (1<<LCD_EN1);
  LCD_RS_DDR  |= (1<<LCD_RS);
  LCD_RW_DDR |=(1<<LCD_RW);

  // muss 3mal hintereinander gesendet werden zur Initialisierung

  _delay_ms(150);

  LCD_PORT_4 |=  (1<<LCD_D4);
  LCD_PORT_5 |=  (1<<LCD_D5);
  LCD_PORT_6 &= ~(1<<LCD_D6);
  LCD_PORT_7 &= ~(1<<LCD_D7);
  LCD_RS_PORT &= ~(1<<LCD_RS);      // RS auf 0
  LCD_RW_PORT &= ~(1<<LCD_RW);
  _delay_ms(50);
  lcd_enable();

  _delay_ms(50);
  lcd_enable();

  _delay_ms(50);
  lcd_enable();

  _delay_ms(50);

  // 4 Bit Modus aktivieren

  LCD_PORT_4 &=  ~(1<<LCD_D4);
  LCD_PORT_5 |=   (1<<LCD_D5);
  LCD_PORT_6 &=  ~(1<<LCD_D6);
  LCD_PORT_7 &=  ~(1<<LCD_D7);

  lcd_enable();
  _delay_ms(1);

  // 4Bit  2 Zeilen  5x7
  lcd_command(0x28);

  // Display ein  Cursor aus  kein Blinken
  lcd_command(0x0C);

  // inkrement / kein Scrollen
  lcd_command(0x06);

  lcd_clear();
}

// Sendet den Befehl zur Löschung des Displays

void lcd_clear(void)
{
  lcd_command(CLEAR_DISPLAY);
  _delay_ms(50);
}

// Sendet den Befehl: Cursor Home

void lcd_home(void)
{
  lcd_command(CURSOR_HOME);
  _delay_ms(5);
}

// setzt den Cursor in Zeile y (1..4) Spalte x (0..15)

void set_cursor(uint8_t x, uint8_t y)
{
  uint8_t tmp;

  switch (y) {
    case 1: tmp=0x80+0x00+x;  break;    // 1. Zeile
    case 2: tmp=0x80+0x40+x;  break;    // 2. Zeile
  }
  lcd_command(tmp);
}

// Schreibt einen String auf das LCD

void lcd_string( const char *data )
{
  while( *data != '\0' )
  lcd_data( *data++ );
}
_____________________________________________________________________

#ifndef LCD_ROUTINES_H
#define LCD_ROUTINES_H

void lcd_string( const char *data );
void lcd_enable(void);
void lcd_init(void);
void lcd_home(void);
void lcd_clear(void);
void set_cursor(uint8_t x, uint8_t y);

// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!

#ifndef F_CPU
#define F_CPU 4000000
#endif

// LCD Befehle

#define CLEAR_DISPLAY 0x01
#define CURSOR_HOME   0x02

// Pinbelegung für das LCD, an verwendete Pins anpassen

#define LCD_PORT_4    PORTC
#define LCD_DDR_4     DDRC
#define LCD_D4      PC0

#define LCD_PORT_5    PORTC
#define LCD_DDR_5     DDRC
#define LCD_D5    PC1

#define LCD_PORT_6    PORTC
#define LCD_DDR_6     DDRC
#define LCD_D6      PC2

#define LCD_PORT_7    PORTC
#define LCD_DDR_7     DDRC
#define LCD_D7    PC3

#define LCD_RS_PORT   PORTB
#define LCD_RS_DDR    DDRB
#define LCD_RS        PB3

#define LCD_EN1_PORT  PORTB
#define LCD_EN1_DDR    DDRB
#define LCD_EN1       PB5

#define LCD_RW_PORT   PORTB
#define LCD_RW_DDR    DDRB
#define LCD_RW        PB4

#define LCD_BOOTUP_MS           15
#define LCD_ENABLE_US           20
#define LCD_WRITEDATA_US        46
#define LCD_COMMAND_US          42

#define LCD_SOFT_RESET_MS1      5
#define LCD_SOFT_RESET_MS2      1
#define LCD_SOFT_RESET_MS3      1
#define LCD_SET_4BITMODE_MS     5

#define LCD_CLEAR_DISPLAY_MS    2
#define LCD_CURSOR_HOME_MS      2

#define LCD_DDADR_LINE1         0x00
#define LCD_DDADR_LINE2         0x40



// Set Entry Mode ------------- 0b000001xx
#define LCD_SET_ENTRY           0x04

#define LCD_ENTRY_DECREASE      0x00
#define LCD_ENTRY_INCREASE      0x02
#define LCD_ENTRY_NOSHIFT       0x00
#define LCD_ENTRY_SHIFT         0x01

// Set Display ---------------- 0b00001xxx
#define LCD_SET_DISPLAY         0x08

#define LCD_DISPLAY_OFF         0x00
#define LCD_DISPLAY_ON          0x04
#define LCD_CURSOR_OFF          0x00
#define LCD_CURSOR_ON           0x02
#define LCD_BLINKING_OFF        0x00
#define LCD_BLINKING_ON         0x01

// Set Shift ------------------ 0b0001xxxx
#define LCD_SET_SHIFT           0x10

#define LCD_CURSOR_MOVE         0x00
#define LCD_DISPLAY_SHIFT       0x08
#define LCD_SHIFT_LEFT          0x00
#define LCD_SHIFT_RIGHT         0x04

// Set Function --------------- 0b001xxxxx
#define LCD_SET_FUNCTION        0x20

#define LCD_FUNCTION_4BIT       0x00
#define LCD_FUNCTION_8BIT       0x10
#define LCD_FUNCTION_1LINE      0x00
#define LCD_FUNCTION_2LINE      0x08
#define LCD_FUNCTION_5X7        0x00
#define LCD_FUNCTION_5X10       0x04

#define LCD_SOFT_RESET          0x30

// Set CG RAM Address --------- 0b01xxxxxx  (Character Generator RAM)
#define LCD_SET_CGADR           0x40

#define LCD_GC_CHAR0            0
#define LCD_GC_CHAR1            1
#define LCD_GC_CHAR2            2
#define LCD_GC_CHAR3            3
#define LCD_GC_CHAR4            4
#define LCD_GC_CHAR5            5
#define LCD_GC_CHAR6            6
#define LCD_GC_CHAR7            7

// Set DD RAM Address --------- 0b1xxxxxxx  (Display Data RAM)
#define LCD_SET_DDADR           0x80

#endif

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.