Mikrocontroller und Digitale Elektronik
›
Thread
Problem mit sprintf()
S
Sili
Gast
21.02.2016 14:09
#4477738
Hallo zusammen,
ich stehe auf dem Schlauch, ich versuche ganz bannal "Hello" auf meinem
Display auszugeben. Wenn ich einzeln meine Zeichen sende funktioniert
das auch, aber wenn ich es mit sprintf() probiere bekomm ich beim
Kompilieren zwei Warnungen und auf dem Display wird mir nur der erste
Buchstabe (H) ausgegeben. Hätte jemand eine Idee woran das liegt?
Code:
char s[50];
...
GotoXY(0,0); So heißt meine Funktion zum Cursor verschieben kein goto!!!
sprintf(s,"Hello");
WriteLCD(s);
Warnungen:
implicit declaration of function 'sprintf'
[-Wimplicit-function-decleration]
incompatible implict declaration of built-in function 'sprintf' [enabled
by default]
H
Hans
Gast
21.02.2016 14:13
#4477742
S
Sili
Gast
21.02.2016 14:14
#4477744
Hi,
#include <stdio.h> ist drin ich hab es nur nicht dazu geschrieben.
S
Schlaumeier
Gast
21.02.2016 14:18
#4477747
Da fehlt die "Multibyte"-Einstellung bei der lib oder wie immer das bei
Deinem Compiler heißt.
Also, welcher Compiler?
S
Schlaumeier
Gast
21.02.2016 14:19
#4477749
Ach, und das volle, ganz banale Programm fehlt auch ...
S
Sili
Gast
21.02.2016 14:24
#4477753
Hi,
ich verwende Atmel Studio 6.2
1 main . c :
2 #include <avr/io.h>
3 #include <stdio.h>
4 #include "LCD.h"
5
6
7 void USART_Init ( unsigned int ubrr )
8 {
9 PORTD |= ( 1 << PD2 );
10
11 UBRRH = ( unsigned char ) ( ubrr >> 8 ); //Set baud rate
12
13 UBRRL = ( unsigned char ) ubrr ;
14
15 UCSRB |= ( 1 << TXEN ); // | (1<<RXEN) Transmitter enabled
16
17 UCSRB |= ( 1 << UCSZ2 ); //Activated 9-Bit-Mode, 1 Stop-Bit
18 }
19
20 void USART_Send ( unsigned int send )
21 {
22 while ( ! ( UCSRA & ( 1 << UDRE )));
23
24 UCSRB &= ~ ( 1 << TXB8 );
25
26 if ( send & 0x0100 )
27 {
28 UCSRB |= ( 1 << TXB8 );
29 }
30
31 UDR = send ;
32 }
33
34
35 int main ( void )
36 {
37 char s [ 50 ];
38
39 DDRD |= ( 1 << DDD2 );
40
41 InitLCD ();
42
43 USART_Init ( 0x67 );
44 ui32Wait = 1000000 ;
45 while ( ui32Wait -- );
46 USART_Send ( 0x00ff );
47 ui32Wait = 100000 ;
48 while ( ui32Wait -- );
49 USART_Send ( 0x0000 );
50 ui32Wait = 100000 ;
51 while ( ui32Wait -- );
52 USART_Send ( 0x000f );
53
54 GotoXY ( 0 , 0 );
55 sprintf ( s , "Hello World" );
56 WriteLCD ( s );
57 /*WriteLCD("H");
58 GotoXY(1,0);
59 WriteLCD("e");
60 GotoXY(2,0);
61 WriteLCD("l");
62 GotoXY(3,0);
63 WriteLCD("l");
64 GotoXY(4,0);
65 WriteLCD("o");*/
66
67
68 while ( 1 )
69 {
70 //USART_Send(0x0100);
71
72
73 }
74 }
75
76 LCD . c :
77 #define __LCD_C
78
79 #include "lcd.h"
80 #include <avr/io.h>
81
82
83
84
85
86 /************ FUNKTION : void WaitForBusyLCD(void) ***********************************************
87 * *
88 * Wartet bis LCD-Display wieder bereit *
89 * *
90 * Uebergabeparameter: keiner *
91 * Rückgabewert: keiner *
92 * *
93 *************************************************************************************************/
94
95 void WaitForBusyLCD ( void )
96 {
97 while ( 1 )
98 {
99
100 PORTA |= ( 1 << LCD_RW );
101 PORTA &= ~ ( 1 << LCD_RS );
102
103 ui32Wait = 300 ;
104 while ( ui32Wait -- );
105 PORTA |= ( 1 << LCD_E );
106 ui32Wait = 300 ;
107 while ( ui32Wait -- );
108
109 if ( ! ( PORTB & ( 1 << LCD_D7 ))) break ;
110
111 PORTA &= ~ ( 1 << LCD_E );
112 ui32Wait = 300 ;
113 while ( ui32Wait -- );
114 }
115
116 PORTA &= ~ ( 1 << LCD_RW );
117 PORTA &= ~ ( 1 << LCD_E );
118 ui32Wait = 300 ;
119 while ( ui32Wait -- );
120
121 }
122
123
124 /************ FUNKTION : void CommandLCD(byte) ***************************************************
125 * *
126 * Sendet Kommando an LCD-Display *
127 * *
128 * Uebergabeparameter: byte byCommand (Kommando) *
129 * Rückgabewert: keiner *
130 * *
131 *************************************************************************************************/
132
133 void CommandLCD ( unsigned int ui8Command )
134 {
135 PORTA &= ~ ( 1 << LCD_RS );
136
137 ui32Wait = 300 ;
138 while ( ui32Wait -- );
139
140 PORTB = ui8Command ;
141
142 PORTA |= ( 1 << LCD_E );
143 ui32Wait = 100000 ;
144 while ( ui32Wait -- );
145 PORTA &= ~ ( 1 << LCD_E );
146 ui32Wait = 100000 ;
147 while ( ui32Wait -- );
148 }
149
150
151 /************ FUNKTION : void InitLCD(void) ******************************************************
152 * *
153 * Initialisiert LCD-Display *
154 * *
155 * Uebergabeparameter: keiner *
156 * Rückgabewert: keiner *
157 * *
158 *************************************************************************************************/
159
160 void InitLCD ( void )
161 {
162
163 DDRA |= ( 1 << DDD0 ) | ( 1 << DDD1 ) | ( 1 << DDD2 );
164 DDRB = 0xff ;
165
166 PORTA &= ~ ( 1 << LCD_E );
167 PORTA &= ~ ( 1 << LCD_RS );
168 PORTA &= ~ ( 1 << LCD_RW );
169
170 CommandLCD ( INITCMD ); // 8Bit Modus
171
172 CommandLCD ( DONCMD ); // Display ein
173
174 CommandLCD ( CLEARCMD ); // Display löschen
175
176 CommandLCD ( ENTRYCMD ); // Auto increment
177
178
179 }
180
181
182 /************ FUNKTION : void GotoXY(byte, byte)) ************************************************
183 * *
184 * Setzt Cursor an vorgegebene Koordinate *
185 * *
186 * Uebergabeparameter: byte byX (X-Koordinate 0..) *
187 * byte byY (Y-Koordinate 0..) *
188 * Rückgabewert: keiner *
189 * *
190 *************************************************************************************************/
191
192
193 void GotoXY ( unsigned int ui8X , unsigned int ui8Y )
194 {
195
196 CommandLCD ( SETDDADR | ui8X | ( ui8Y << 6 ));
197
198 }
199
200
201 /************ FUNKTION : void Clear() ************************************************************
202 * *
203 * Löscht Display *
204 * *
205 * Uebergabeparameter: keiner *
206 * *
207 * Rückgabewert: keiner *
208 * *
209 *************************************************************************************************/
210
211 void Clear ( void )
212 {
213 CommandLCD ( CLEARCMD ); // Display löschen
214 CommandLCD ( SETDDADR ); // Cursor Home
215 }
216
217 /************ FUNKTION : void WrCharLCD(char chChar) *********************************************
218 * *
219 * Gibt Zeichen auf LCD-Display aus *
220 * *
221 * Uebergabeparameter: char chChar *
222 * *
223 * Rückgabewert: keiner *
224 * *
225 *************************************************************************************************/
226
227 void WrCharLCD ( char chChar )
228 {
229 PORTA |= ( 1 << LCD_RS );
230 PORTA &= ~ ( 1 << LCD_RW );
231
232 PORTB = chChar ;
233
234 PORTA |= ( 1 << LCD_E );
235 ui32Wait = 3000 ;
236 while ( ui32Wait -- );
237 PORTA &= ~ ( 1 << LCD_E );
238 ui32Wait = 3000 ;
239 while ( ui32Wait -- );
240
241
242 WaitForBusyLCD ();
243 }
244
245 /************ FUNKTION : void HideCur() **********************************************************
246 * *
247 * Blendet Cursor aus *
248 * *
249 * Uebergabeparameter: keiner *
250 * *
251 * Rückgabewert: keiner *
252 * *
253 *************************************************************************************************/
254
255 void HideCur ( void ) // Cursor ausblenden
256 {
257 GotoXY ( 17 , 1 );
258 }
259
260
261
262 void WriteLCD ( char * s )
263 {
264 while ( * s )
265 {
266 WrCharLCD ( * s ++ );
267 }
268 }
LCD.h: 1 #ifndef LCD_H
2 #define LCD_H
3
4
5 #ifndef __LCD_C
6 #define EXTERN extern
7 #else
8 #define EXTERN
9 #endif
10
11 /*************************************************************************************************
12 * *
13 * Definitionen *
14 * *
15 *************************************************************************************************/
16
17 EXTERN unsigned long ui32Wait ;
18
19 #define CLEARCMD 0x01 // clear whole display
20 #define ENTRYCMD 0x06 // incremental address, no shift
21 #define DONCMD 0x0e // display on, cursor off, blink on
22 #define INITCMD 0x38 // 8 bit data, 2 lines, font 5x8
23 #define XMAX 0x10 // number of colums-1
24 #define YMAX 0x01 // number of lines-1
25 #define SETCGADR 0x40 // select address for character
26 #define SETDDADR 0x80 // select address for display
27 #define CONTROLREG 0x00 // control register
28 #define DATAREG 0x01 // data register
29 #define LCDBUSY 0x80 // mask for busy flag
30
31
32 #define SET1 0
33 #define SET2 1
34
35 #define LCD_E PA0
36 #define LCD_RS PA2
37 #define LCD_RW PA1
38 #define LCD_D0 PB0
39 #define LCD_D1 PB1
40 #define LCD_D2 PB2
41 #define LCD_D3 PB3
42 #define LCD_D4 PB4
43 #define LCD_D5 PB5
44 #define LCD_D6 PB6
45 #define LCD_D7 PB7
46
47 /*************************************************************************************************
48 * *
49 * Variablendeklaration *
50 * *
51 *************************************************************************************************/
52
53
54 /*************************************************************************************************
55 * *
56 * Funktionsdeklarationen *
57 * *
58 *************************************************************************************************/
59
60 EXTERN void InitLCD ( void );
61 EXTERN void GotoXY ( unsigned int ui8X , unsigned int ui8Y );
62 EXTERN void Clear ( void );
63 EXTERN void WrCharLCD ( char chChar );
64 EXTERN void HideCur ( void );
65 EXTERN void LoadCharacter ( unsigned int ui8Set );
66 EXTERN void WaitForBusyLCD ( void );
67 EXTERN void CommandLCD ( unsigned int ui8Command );
68 EXTERN void WriteLCD ( char * s );
69
70 #undef EXTERN
71
72
73
74 #endif
--
Quelltext wird lesbarer, wenn man die Code-Tags benutzt. Noch besser ist
es, bei längeren Quelltexten diese als Anhang zu posten, dann gibts den
Quelltextbetrachter, der sogar Zeilennummern davorschreibt.
-rufus
S
Schlaumeier
Gast
21.02.2016 14:43
#4477768
Ok, multibyte war Quatsch.
Wo bekommt s seinen Wert?
Aber was soll das sprintf dort bewirken? Müßte es nicht:
1 void USARTSendStr ( char * s )
2 {
3 while ( * s )
4 {
5 USART_Send ( * s ++ );
6 }
7 }
8
9 ...
10
11 USARTSendStr ( "Hello World" );
heißen, wenn der Text auf die serielle soll?
Was hast Du für ein Display? Hat das fünf Zeilen?
usw.
alles etwas wirr ...
S
Sili
Gast
21.02.2016 14:46
#4477772
Hi,
ne der Usart hat damit nichts zu tun, der macht später mal was anderes,
ich versuche gerade nur etwas auf dem Display mit sprintf auszugeben.
Display:
2x16 Zeilen (DEM16214)
S
Schlaumeier
Gast
21.02.2016 14:47
#4477773
Schlaumeier schrieb:
> Wo bekommt s seinen Wert?
Ach, war ja sprintf ... falsch verwendet:
http://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm
Warum so umständlich?
S
Schlaumeier
Gast
21.02.2016 14:50
#4477780
Sili schrieb:
> ne der Usart hat damit nichts zu tun, der macht später mal was anderes,
Sorry, ich hatte *f*printf im Kopf ... da steht ja *s*printf
S
Sili
Gast
21.02.2016 14:52
#4477785
Hier nochmal der Code in lesbar:
1 main . c :
2
3 #include <avr/io.h>
4 #include <stdio.h>
5 #include "LCD.h"
6
7
8 void USART_Init ( unsigned int ubrr )
9 {
10 PORTD |= ( 1 << PD2 );
11
12 UBRRH = ( unsigned char ) ( ubrr >> 8 ); //Set baud rate
13
14 UBRRL = ( unsigned char ) ubrr ;
15
16 UCSRB |= ( 1 << TXEN ); // | (1<<RXEN) Transmitter enabled
17
18 UCSRB |= ( 1 << UCSZ2 ); //Activated 9-Bit-Mode, 1 Stop-Bit
19 }
20
21 void USART_Send ( unsigned int send )
22 {
23 while ( ! ( UCSRA & ( 1 << UDRE )));
24
25 UCSRB &= ~ ( 1 << TXB8 );
26
27 if ( send & 0x0100 )
28 {
29 UCSRB |= ( 1 << TXB8 );
30 }
31
32 UDR = send ;
33 }
34
35
36 int main ( void )
37 {
38 char s [ 50 ];
39
40 DDRD |= ( 1 << DDD2 );
41
42 InitLCD ();
43
44 USART_Init ( 0x67 );
45 ui32Wait = 1000000 ;
46 while ( ui32Wait -- );
47 USART_Send ( 0x00ff );
48 ui32Wait = 100000 ;
49 while ( ui32Wait -- );
50 USART_Send ( 0x0000 );
51 ui32Wait = 100000 ;
52 while ( ui32Wait -- );
53 USART_Send ( 0x000f );
54
55 GotoXY ( 0 , 0 );
56 sprintf ( s , "Hello World" );
57 WriteLCD ( s );
58 /*WriteLCD("H");
59 GotoXY(1,0);
60 WriteLCD("e");
61 GotoXY(2,0);
62 WriteLCD("l");
63 GotoXY(3,0);
64 WriteLCD("l");
65 GotoXY(4,0);
66 WriteLCD("o");*/
67
68
69 while ( 1 )
70 {
71 //USART_Send(0x0100);
72
73
74 }
75 }
76
77 LCD . c :
78
79 #define __LCD_C
80
81 #include "lcd.h"
82 #include <avr/io.h>
83 #include <stdio.h>
84
85
86 void WaitForBusyLCD ( void )
87 {
88 while ( 1 )
89 {
90
91 PORTA |= ( 1 << LCD_RW );
92 PORTA &= ~ ( 1 << LCD_RS );
93
94 ui32Wait = 300 ;
95 while ( ui32Wait -- );
96 PORTA |= ( 1 << LCD_E );
97 ui32Wait = 300 ;
98 while ( ui32Wait -- );
99
100 if ( ! ( PORTB & ( 1 << LCD_D7 ))) break ;
101
102 PORTA &= ~ ( 1 << LCD_E );
103 ui32Wait = 300 ;
104 while ( ui32Wait -- );
105 }
106
107 PORTA &= ~ ( 1 << LCD_RW );
108 PORTA &= ~ ( 1 << LCD_E );
109 ui32Wait = 300 ;
110 while ( ui32Wait -- );
111
112 }
113
114 void CommandLCD ( unsigned int ui8Command )
115 {
116 PORTA &= ~ ( 1 << LCD_RS );
117
118 ui32Wait = 300 ;
119 while ( ui32Wait -- );
120
121 PORTB = ui8Command ;
122
123 PORTA |= ( 1 << LCD_E );
124 ui32Wait = 100000 ;
125 while ( ui32Wait -- );
126 PORTA &= ~ ( 1 << LCD_E );
127 ui32Wait = 100000 ;
128 while ( ui32Wait -- );
129 }
130
131
132 void InitLCD ( void )
133 {
134
135 DDRA |= ( 1 << DDD0 ) | ( 1 << DDD1 ) | ( 1 << DDD2 );
136 DDRB = 0xff ;
137
138 PORTA &= ~ ( 1 << LCD_E );
139 PORTA &= ~ ( 1 << LCD_RS );
140 PORTA &= ~ ( 1 << LCD_RW );
141
142 CommandLCD ( INITCMD ); // 8Bit Modus
143
144 CommandLCD ( DONCMD ); // Display ein
145
146 CommandLCD ( CLEARCMD ); // Display löschen
147
148 CommandLCD ( ENTRYCMD ); // Auto increment
149
150
151 }
152
153 void GotoXY ( unsigned int ui8X , unsigned int ui8Y )
154 {
155
156 CommandLCD ( SETDDADR | ui8X | ( ui8Y << 6 ));
157
158 }
159
160
161 void Clear ( void )
162 {
163 CommandLCD ( CLEARCMD ); // Display löschen
164 CommandLCD ( SETDDADR ); // Cursor Home
165 }
166
167
168 void WrCharLCD ( char chChar )
169 {
170 PORTA |= ( 1 << LCD_RS );
171 PORTA &= ~ ( 1 << LCD_RW );
172
173 PORTB = chChar ;
174
175 PORTA |= ( 1 << LCD_E );
176 ui32Wait = 3000 ;
177 while ( ui32Wait -- );
178 PORTA &= ~ ( 1 << LCD_E );
179 ui32Wait = 3000 ;
180 while ( ui32Wait -- );
181
182
183 WaitForBusyLCD ();
184 }
185
186
187 void HideCur ( void ) // Cursor ausblenden
188 {
189 GotoXY ( 17 , 1 );
190 }
191
192
193
194 void WriteLCD ( char * s )
195 {
196 while ( * s )
197 {
198 WrCharLCD ( * s ++ );
199 }
200 }
201
202 LCD . h :
203
204 #ifndef LCD_H
205 #define LCD_H
206
207
208 #ifndef __LCD_C
209 #define EXTERN extern
210 #else
211 #define EXTERN
212 #endif
213
214
215 EXTERN unsigned long ui32Wait ;
216
217 #define CLEARCMD 0x01 // clear whole display
218 #define ENTRYCMD 0x06 // incremental address, no shift
219 #define DONCMD 0x0e // display on, cursor off, blink on
220 #define INITCMD 0x38 // 8 bit data, 2 lines, font 5x8
221 #define XMAX 0x10 // number of colums-1
222 #define YMAX 0x01 // number of lines-1
223 #define SETCGADR 0x40 // select address for character
224 #define SETDDADR 0x80 // select address for display
225 #define CONTROLREG 0x00 // control register
226 #define DATAREG 0x01 // data register
227 #define LCDBUSY 0x80 // mask for busy flag
228
229
230 #define SET1 0
231 #define SET2 1
232
233 #define LCD_E PA0
234 #define LCD_RS PA2
235 #define LCD_RW PA1
236 #define LCD_D0 PB0
237 #define LCD_D1 PB1
238 #define LCD_D2 PB2
239 #define LCD_D3 PB3
240 #define LCD_D4 PB4
241 #define LCD_D5 PB5
242 #define LCD_D6 PB6
243 #define LCD_D7 PB7
244
245
246 EXTERN void InitLCD ( void );
247 EXTERN void GotoXY ( unsigned int ui8X , unsigned int ui8Y );
248 EXTERN void Clear ( void );
249 EXTERN void WrCharLCD ( char chChar );
250 EXTERN void HideCur ( void );
251 EXTERN void LoadCharacter ( unsigned int ui8Set );
252 EXTERN void WaitForBusyLCD ( void );
253 EXTERN void CommandLCD ( unsigned int ui8Command );
254 EXTERN void WriteLCD ( char * s );
255
256 #undef EXTERN
257
258
259
260 #endif
S
Schlaumeier
Gast
21.02.2016 14:53
#4477787
Dein WriteLCD kann mit Strings umgehen, also WriteLCD("Hello World")
sollte funktionieren.
Warum GOTOXY nicht geht, überschau ich gerade nicht.
S
Sili
Gast
21.02.2016 14:55
#4477788
Hi,
ja aber ich muss später auch integer Werte ausgeben.
S
Schlaumeier
Gast
21.02.2016 14:55
#4477790
Schlaumeier schrieb:
> Warum GOTOXY nicht geht, überschau ich gerade nicht.
Ah, ok, war auskommentiert. In dem langen Quelltext schwer zu
überschauen.
Bitte längere Quelltexte als Dateien einzeln anhängen, dann kann man das
Ganze viel besser überschauen.
F
Forist
Gast
21.02.2016 14:56
#4477791
Sili schrieb:
> main.c:
> #include <avr/io.h>
> #include <stdio.h>
Ist dein Browser kaputt, das du den Quellcode nicht als Dateianhang
dranhängen kannst, so dass man sich beim Scrollen wunde Finger holt?
S
Schlaumeier
Gast
21.02.2016 14:57
#4477794
Integer-Werte mußt Du vorher in ASCII umformatieren, z. B.:
https://en.wikibooks.org/wiki/C_Programming/C_Reference/stdlib.h/itoa
mit Beispielcode oder eben sprintf korrekt verwenden, siehe link vorher.
Antwort schreiben