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 | }/* |