LCD funktioniert nich

OP #3639831
Lesenswert?

Hallo,

ich bin neu :)
Stelle mich kurz vor, ich heiße Philipp und habe auch schon einfrage zu 
einem LCD Programm ;-)

Ich habe genau das selbe gemacht wie es in dem Tutorial LCD Ansteuerung 
beschrieben ist.
Wenn ich den Code aber Debug, kommt das hier:
1
Warning  1  #warning "F_CPU not defined for <util/delay.h>"
2
Error  2  undefined reference to `lcd_init()'
3
Error  3  undefined reference to `lcd_data(unsigned char)'  
4
Error  4  undefined reference to `lcd_data(unsigned char)'  
5
Error  5  undefined reference to `lcd_data(unsigned char)'  
6
Error  6  undefined reference to `lcd_data(unsigned char)'    
7
Error  7  undefined reference to `lcd_setcursor(unsigned char, unsigned char)'
8
Error  8  undefined reference to `lcd_string(char const*)'
woran liegt das? :-/

Hier habe ich mal den Quelltext angehangen

Schonmal danke für eure Antworten :)

-----------------------------------------------------------------------

main.cpp
1
#include <stdlib.h>
2
#include <avr/io.h>
3

4
#include "lcd-routines.h"
5
 
6
int main(void)
7
{
8
  lcd_init();
9

10
  lcd_data( 'T' );
11
  lcd_data( 'e' );
12
  lcd_data( 's' );
13
  lcd_data( 't' );
14
 
15
  lcd_setcursor( 0, 2 );
16
 
17
  lcd_string("Hello World!");
18
 
19
  while(1)
20
  {
21
  }
22
 
23
  return 0;
24
}
------------------------------------------------------------------------ 
--
lcd_routines.h
1
#ifndef LCD_ROUTINES_H
2
#define LCD_ROUTINES_H
3
 
4
#ifndef F_CPU
5
#define F_CPU 16000000L
6
#endif
7
 
8
//  LCD DB4-DB7 <-->  PORTD Bit PD0-PD3
9
#define LCD_PORT      PORTD
10
#define LCD_DDR       DDRD
11
#define LCD_DB        PD0
12
 
13
//  LCD RS      <-->  PORTD Bit PD4     (RS: 1=Data, 0=Command)
14
#define LCD_RS        PD4
15
 
16
//  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
17
#define LCD_EN        PD5
18
 
19
 
20
#define LCD_BOOTUP_MS           15
21
#define LCD_ENABLE_US           20
22
#define LCD_WRITEDATA_US        46
23
#define LCD_COMMAND_US          42
24
 
25
#define LCD_SOFT_RESET_MS1      5
26
#define LCD_SOFT_RESET_MS2      1
27
#define LCD_SOFT_RESET_MS3      1
28
#define LCD_SET_4BITMODE_MS     5
29
 
30
#define LCD_CLEAR_DISPLAY_MS    2
31
#define LCD_CURSOR_HOME_MS      2
32
 
33
 
34
#define LCD_DDADR_LINE1         0x00
35
#define LCD_DDADR_LINE2         0x40
36
#define LCD_DDADR_LINE3         0x10
37
#define LCD_DDADR_LINE4         0x50
38
 
39

40
void lcd_init( void );
41

42
void lcd_clear( void );
43

44
void lcd_home( void );
45

46
void lcd_setcursor( uint8_t spalte, uint8_t zeile );
47
 
48
void lcd_data( uint8_t data );
49

50
void lcd_string( const char *data );
51
 
52
void lcd_generatechar( uint8_t code, const uint8_t *data );
53
 
54
void lcd_command( uint8_t data );
55

56
#define LCD_CLEAR_DISPLAY       0x01
57
 
58
#define LCD_CURSOR_HOME         0x02
59

60
#define LCD_SET_ENTRY           0x04
61
 
62
#define LCD_ENTRY_DECREASE      0x00
63
#define LCD_ENTRY_INCREASE      0x02
64
#define LCD_ENTRY_NOSHIFT       0x00
65
#define LCD_ENTRY_SHIFT         0x01
66

67
#define LCD_SET_DISPLAY         0x08
68
 
69
#define LCD_DISPLAY_OFF         0x00
70
#define LCD_DISPLAY_ON          0x04
71
#define LCD_CURSOR_OFF          0x00
72
#define LCD_CURSOR_ON           0x02
73
#define LCD_BLINKING_OFF        0x00
74
#define LCD_BLINKING_ON         0x01
75
 
76
#define LCD_SET_SHIFT           0x10
77
 
78
#define LCD_CURSOR_MOVE         0x00
79
#define LCD_DISPLAY_SHIFT       0x08
80
#define LCD_SHIFT_LEFT          0x00
81
#define LCD_SHIFT_RIGHT         0x04
82

83
#define LCD_SET_FUNCTION        0x20
84
 
85
#define LCD_FUNCTION_4BIT       0x00
86
#define LCD_FUNCTION_8BIT       0x10
87
#define LCD_FUNCTION_1LINE      0x00
88
#define LCD_FUNCTION_2LINE      0x08
89
#define LCD_FUNCTION_5X7        0x00
90
#define LCD_FUNCTION_5X10       0x04
91
 
92
#define LCD_SOFT_RESET          0x30
93

94
#define LCD_SET_CGADR           0x40
95
 
96
#define LCD_GC_CHAR0            0
97
#define LCD_GC_CHAR1            1
98
#define LCD_GC_CHAR2            2
99
#define LCD_GC_CHAR3            3
100
#define LCD_GC_CHAR4            4
101
#define LCD_GC_CHAR5            5
102
#define LCD_GC_CHAR6            6
103
#define LCD_GC_CHAR7            7
104

105
#define LCD_SET_DDADR           0x80
106
 
107
#endif
-------------------------------------------------------------------
lcd_routines.c
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include "lcd-routines.h"
4

5
static void lcd_enable( void )
6
{
7
    LCD_PORT |= (1<<LCD_EN);     // Enable auf 1 setzen
8
    _delay_us( LCD_ENABLE_US );  // kurze Pause
9
    LCD_PORT &= ~(1<<LCD_EN);    // Enable auf 0 setzen
10
}
11
 
12
static void lcd_out( uint8_t data )
13
{
14
    data &= 0xF0;                       // obere 4 Bit maskieren
15
 
16
    LCD_PORT &= ~(0xF0>>(4-LCD_DB));    // Maske löschen
17
    LCD_PORT |= (data>>(4-LCD_DB));     // Bits setzen
18
    lcd_enable();
19
}
20
 
21
void lcd_init( void )
22
{
23
    // verwendete Pins auf Ausgang schalten
24
    uint8_t pins = (0x0F << LCD_DB) |           // 4 Datenleitungen
25
                   (1<<LCD_RS) |                // R/S Leitung
26
                   (1<<LCD_EN);                 // Enable Leitung
27
    LCD_DDR |= pins;
28
 
29
    LCD_PORT &= ~pins;
30
 
31
    _delay_ms( LCD_BOOTUP_MS );
32
 
33
    lcd_out( LCD_SOFT_RESET );
34
    _delay_ms( LCD_SOFT_RESET_MS1 );
35
 
36
    lcd_enable();
37
    _delay_ms( LCD_SOFT_RESET_MS2 );
38
 
39
    lcd_enable();
40
    _delay_ms( LCD_SOFT_RESET_MS3 );
41
 
42
    // 4-bit Modus aktivieren 
43
    lcd_out( LCD_SET_FUNCTION |
44
             LCD_FUNCTION_4BIT );
45
    _delay_ms( LCD_SET_4BITMODE_MS );
46
 
47
    // 4-bit Modus / 2 Zeilen / 5x7
48
    lcd_command( LCD_SET_FUNCTION |
49
                 LCD_FUNCTION_4BIT |
50
                 LCD_FUNCTION_2LINE |
51
                 LCD_FUNCTION_5X7 );
52
 
53
    // Display ein / Cursor aus / Blinken aus
54
    lcd_command( LCD_SET_DISPLAY |
55
                 LCD_DISPLAY_ON |
56
                 LCD_CURSOR_OFF |
57
                 LCD_BLINKING_OFF); 
58
 
59
    // Cursor inkrement / kein Scrollen
60
    lcd_command( LCD_SET_ENTRY |
61
                 LCD_ENTRY_INCREASE |
62
                 LCD_ENTRY_NOSHIFT );
63
 
64
    lcd_clear();
65
}
66

67
void lcd_data( uint8_t data )
68
{
69
    LCD_PORT |= (1<<LCD_RS);    // RS auf 1 setzen
70
 
71
    lcd_out( data );            // zuerst die oberen, 
72
    lcd_out( data<<4 );         // dann die unteren 4 Bit senden
73
 
74
    _delay_us( LCD_WRITEDATA_US );
75
}
76

77
void lcd_command( uint8_t data )
78
{
79
    LCD_PORT &= ~(1<<LCD_RS);    // RS auf 0 setzen
80
 
81
    lcd_out( data );             // zuerst die oberen, 
82
    lcd_out( data<<4 );           // dann die unteren 4 Bit senden
83
 
84
    _delay_us( LCD_COMMAND_US );
85
}
86
 
87
void lcd_clear( void )
88
{
89
    lcd_command( LCD_CLEAR_DISPLAY );
90
    _delay_ms( LCD_CLEAR_DISPLAY_MS );
91
}
92
 
93
void lcd_home( void )
94
{
95
    lcd_command( LCD_CURSOR_HOME );
96
    _delay_ms( LCD_CURSOR_HOME_MS );
97
}
98
 
99
void lcd_setcursor( uint8_t x, uint8_t y )
100
{
101
    uint8_t data;
102
 
103
    switch (y)
104
    {
105
        case 1:    // 1. Zeile
106
            data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;
107
            break;
108
 
109
        case 2:    // 2. Zeile
110
            data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;
111
            break;
112
 
113
        case 3:    // 3. Zeile
114
            data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;
115
            break;
116
 
117
        case 4:    // 4. Zeile
118
            data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;
119
            break;
120
 
121
        default:
122
            return;                                   // für den Fall einer falschen Zeile
123
    }
124
 
125
    lcd_command( data );
126
}
127
 
128
void lcd_string( const char *data )
129
{
130
    while( *data != '\0' )
131
        lcd_data( *data++ );
132
}
133
 
134
void lcd_generatechar( uint8_t code, const uint8_t *data )
135
{
136
    // Startposition des Zeichens einstellen
137
    lcd_command( LCD_SET_CGADR | (code<<3) );
138
 
139
    // Bitmuster übertragen
140
    for ( uint8_t i=0; i<8; i++ )
141
    {
142
        lcd_data( data[i] );
143
    }
144
}/*
#3640235
Lesenswert?

> Forum: Projekte & Code
> Hier könnt ihr eure Projekte, Schaltungen oder Codeschnipsel
> vorstellen und diskutieren. Bitte hier keine Fragen posten!
Fällt dir was auf?


Hast du die LCD.h auch in Projektordner?
Definiere F_CPU. Wenn du z.B. einen 16MHz Quarz hast:
1
#define F_CPU 16000000
(Firma: Privat) #3641053
Lesenswert?

Was zeigt es denn an? Schwarze Balken oder gar nichts?

Es ist möglich das du es falsch angeschlossen hast. Es ist wichtig das 
die Kontrastspannung stimmt, zudem solltest du am LCD die Datenleitungen 
an 4-7 (je nach zähl weise 5-8) anschließen.

Die Frage ist vielleicht dumm, aber hast du den Code wirklich als 3 
Dateien?

Du solltest auch die Fuses nochmal ansehen. Versuch es doch fürs erste 
mal mit dem internen 8MHz Quarz (den sollte jeder AVR haben).

- Fals es gar nichts zeigt liegt der Fehler im Anschluss.

- Wenn es schwarze Balken bringt, liegt es eher beim AVR.
OP #3641758
Lesenswert?

Anzeigen tut es nix.
Wenn ich den Kontrast einstelle, werden alle Schwarzen Balken entweder 
dunkel oder hell mehr leider nich.

Beim Anschließen habe ich D4-D7 (vom Display) an PD0-PD3 (meine Adrduino 
UNO Boards) Angeschlossen.
"RS" (vom Display) liegt an PD4 (des Adrduino).
"E" (vom Display) geht an PD5 (des Arduino).
VSS - Masse
VDD - 5V
VEE - Poti
R/W - Masse


Habe alles in einer Datei gehabt und dann habe ich es mal aufegteilt.
OP #3646231
Lesenswert?

Sorry für die späte Antwort.
Wenn ich am Poti drehe seh ich die änderung der Balken aber nix von dem 
programm :-(
Aber richtig angeschlossen habe ich ich es ja...
Oder muss ich im code noch was ändern?
Kann mir vielleicht jemand schritt für schritt erklären wie ihr es macht 
mit code und anschließen, vielleicht finde ich dann den fehler :-(
Gast #3649874
Lesenswert?

Philipp K. schrieb:
> Hier habe ich mal den Quelltext angehangen

Und warum nicht als Dateianhang?
Und bei Originalbiliotheken reicht ein Link. Und falls deine 
Bibliotheken nicht im (bewährten) Originalzustand sind, solltest du 
genau angeben, was du geändert hast.

Wie sieht es mit einem Arduino Beispiele zum LCD, z.B. 
LiquidCrystal/HelloWord.c aus? Läuft das?
#3652604
Lesenswert?

Auf deinem Bild beginnt die Riege der benutzten Ausgangspins mit PD0 (am 
Port D)

Hier jedoch
1
#define LCD_PORT      PORTD
2
#define LCD_DDR       DDRD
3
#define LCD_DB        PD2
4
 
5
//  LCD RS      <-->  PORTD Bit PD4     (RS: 1=Data, 0=Command)
6
#define LCD_RS        PD6
7
 
8
//  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
9
#define LCD_EN        PD7
ist von PD0 nichts zu sehen.


Ich hab die Pinbelegung der Arduino Klemmen nicht rausgesucht. Aber 
irgendeine der beiden Angaben, Bild oder Code, muss falsch sein.
OP #3658376
Lesenswert?

du hast genau die dateien die ich da oben eingestellt habe bei dir rein 
kopiert. einmal als main datei, dann eine als lcd.h und eine als lcd.c?
genauso wie die dort oben sind?

Habe mal ein paar bilder gemacht wie ich es erstellt habe.
das müsste ja auch richtig sein
#define F_CPU 16000000UL
(habe ein Arduino UNO)
Angehängte Dateien:
OP #3658378
Lesenswert?

du hast genau die dateien die ich da oben eingestellt habe bei dir rein 
kopiert. einmal als main datei, dann eine als lcd.h und eine als lcd.c?
genauso wie die dort oben sind?

Habe mal ein paar bilder gemacht wie ich es erstellt habe.
das müsste ja auch richtig sein
#define F_CPU 16000000UL
(habe ein Arduino UNO)
Angehängte Dateien:
OP #3658429
Lesenswert?

genau die das ist bei mir auch so.
Wenn ich die 1600000UL zu 1600000 oder zu 1600000L oder so ändere bringt 
er mir irgendwelche zahlen und buchstaben aber bei 1600000UL nix.

Habe mal Bilder gemacht wo ich genau zeige wie ich das mache, also bei 
Bild "neu" erstelle ich das Projekt mit dem was gelb markiert ist, dnach 
das Bild "neu1" da suche ich den Atmega aus und nehme den der markiert 
ist, danach kopiere ich alle 3 Datei also die Main.c, lcd.c und die 
lcd.h in das Projekt rein. danach speicher ich alles und drücke auf 
Build Projekt.
Dann gehe ich in das upload Programm und suche den Ordner wo es drin ist 
nach der erstellten HEX datei, geben dann unten 115200 ein und mache 
upload...
das müsste doch alles eigentlich genauso sein oder?
#3658619
Lesenswert?

Ich habe mit dem AVR-Studio5 oder AVR-Studio6 noch nicht gearbeitet, 
kann dir daher nicht helfen.
Der Fehler liegt aber sicher in einer falschen Einstellung oder du lädst 
konsequent eine falsche *.hex.

Ein Tipp noch, gibt deinen Projekten einen aussagekräftigen Namen. In 
zwei Monaten weisst du nicht mehr was du unter AVRGCC2 gemacht hast.

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