Ich benutze bei C18 oft die itoa-funktion (integer to string) um mir
diverse werte im LCD anzeigen zu lassen ...
Beispiel:
1
LCD_WriteValue(itoa(minuten));
Die entsprechende Funktion sieht so aus:
1
voidLCD_WriteValue(unsignedchar*pdata)
2
{
3
charn=0;//
4
chartemp;//
5
while(temp=pdata[n++])//
6
LCD_WriteChar(temp);//
7
}
welche wieder in diese Springt:
1
voidLCD_set_char(unsignedcharchararray[],intlen)
2
{
3
inti;
4
i=0;
5
while(i<len)
6
{
7
LCD_WriteChar(chararray[i]);
8
i++;
9
}
10
}
Das funktioniert eig. wunderbar, außer, das mir der Compiler diese
Meldungen bringt:
Warning [2058] call of function without prototype
Warning [2054] suspicious pointer conversion
Einbinden in das project tu ich nur:
#include <delays.h>
#include <string.h>
sobald ich die Lib einbinde, in der ITOA definiert ist, will er, das ich
das ausgabeformat mit angebe; sprich itoa(intzahl,10) .. 10 = dezimal ..
aber dann zeigt mein LCD nur noch blödsin an...
jemand ne idee, woher der compiler die itoa nimmt, wenn ich die lib
nicht einbinde, oder/und warum das einbinden fehlerhafte werte bringt.
@ Gero Nimo (geronimo76)
>void LCD_WriteValue(unsigned char *pdata)>{>char n = 0; //>char temp; //>while(temp = pdata[n++]) //>LCD_WriteChar(temp); //>}>welche wieder in diese Springt:>void LCD_set_char(unsigned char chararray[],int len)
Nö,
LCD_WriteChar(temp); ist nicht LCD_set_char
>{>int i;>i = 0;>while(i<len)> {> LCD_WriteChar(chararray[i]);> i++;> }>}>Warning [2058] call of function without prototype
Dein Funktionsname ist falsch und nirgends in einem Headerfile
deklariert.
MFG
Falk
> sobald ich die Lib einbinde, in der ITOA definiert ist, will er, das ich> das ausgabeformat mit angebe; sprich itoa(intzahl,10) .. 10 = dezimal ..> aber dann zeigt mein LCD nur noch blödsin an...
Toll, du hast das erste mal erklärt bekommen,
daß itoa
char *itoa(int value, char *string, int radix);
nicht so ist wie du glaubst daß sie ist.
char *itoa(int value);
http://www.mkssoftware.com/docs/man3/itoa.3.asp
und alle deine bisherigen programm grobe Fehler
enthielten (schreibt irgendwo in den Speicher,
mit irgendeinem radix..).
NIX MEHR VERSTEHT ^^
...wenn ich jetzt nach Schema vorgehe:
#include <stdlib.h>
char *itoa(int value, char *string, int radix);
DESCRIPTION
The itoa() function constructs a string representation of an integer.
PARAMETERS
value
Is the integer to be converted to string representation.
string
Points to the buffer that is to hold resulting string. The resulting
string may be as long as seventeen bytes.
radix
Is the base of the number; must be in the range 2 - 36.
und entsprechend mein Code ändere ->
char Buffer[20];
itoa( minuten, Buffer,10);
LCD_WriteString(Buffer);
sagt er mir, jetzt sinds zu viele Argumente^^
Gero Nimo schrieb:> sagt er mir, jetzt sinds zu viele Argumente^^
Hast du auch stdlib.h inkludiert?
Welche anderen Header Dateien inkludierst du? Vielleicht haben dir ja
die Leute von Keil auch noch ein anderes itoa mitgegeben?
Mich macht zb stutzig, dass du einmal itoa klein schreibst, ein anderes
mal schreibst du es gross.
ich benutze itoa immer klein geschreiben (daran liegts nicht)
wenn ich mir den quelltext der stdlib.h ansehe, dann steht das drin
(stdlib.h nimmt er aus dem INstallationsverzeichniss von C18/h/..)
1
char*itoa(autointvalue,autochar*s);
2
/** @name ltoa
3
* The {\bf ltoa} function converts the {\bf long} value {\bf value} to
4
* a radix 10 string representation, storing the resultant string into
5
* the location pointed to by {\bf s}.
6
*
7
* The {\bf ltoa} function is an MPLAB-Cxx extension to the ANSI required
8
* libraries and may not be present in other implementations.
9
* @param value value to convert
10
* @param s pointer to destination string object
11
* @return The {\bf ltoa} function returns the value of {\bf s}.
Dann musst Du diese Variante verwenden, denn das ist die zu Deinem
Compiler gehörende.
Ungewöhnlich, weil vom Standard abweichend.
Um auf Deinen Codeschnippsel zurückzukommen, das muss dann also so
aussehen:
ich glaub, es liegt an meiner LCD Routine
Warning [2054] suspicious pointer conversion
kommt, wenn ich
LCD_WriteValue(itoa(minuten,10));
aufrufe
WRITEVALUE:
Gero Nimo schrieb:> ich glaub, es liegt an meiner LCD Routine>
jetzt bin ich aber enttäuscht
> Warning [2054] suspicious pointer conversion> kommt, wenn ich> LCD_WriteValue(itoa(minuten,10));> aufrufe>
wie war noch mal dein itoa definiert?
itoa( zahl, buffer in dem der String abgelegt werden soll)
und wie benutzt du es
itoa( minuten, 10 )
seit wann ist denn 10 die Adresse eines char-Arrays in das itoa einen
String ablegen darf?
Du warst so gut unterwegs, wie du dir aus deinem stdlib.h die notwendige
Information rausgesucht hast. Und dann verwendest du diese Information
nicht, sondern fängst erst recht wieder mit Raten an.
>ich glaub, es liegt an meiner LCD Routine
Nö.
>Warning [2054] suspicious pointer conversion>kommt, wenn ich>LCD_WriteValue(itoa(minuten,10));>aufrufe
Die 10 muss durch einen Zeichenpuffer ersetzr
werden wo dein String auch reinpasst. Radix
kennt dein itoa nicht.
Gero Nimo schrieb:> Warning [2054] suspicious pointer conversion
Du übergibst einen char* (oder bei manchen Implementierungen von itoa()
vielleicht auch einen const char* an eine Funktion, die einen unsigned
char erwartet. Ich finde das suspicious, der C18 (der übrigens nicht von
Keil, sondern Microchip kommt @KHB) findet das auch. Zurecht.
holger schrieb:> Die 10 muss durch einen Zeichenpuffer ersetzr> werden wo dein String auch reinpasst. Radix> kennt dein itoa nicht.
Die Warning[2054] hat er schon im Eröffnungspost.
tut mir leid, ich bin irgendwie nicht in der lage, auf einen grünen
zweig zu kommen...
hab jetzt umgeändert in
LCD_WriteValue(itoa(minuten,Buffer));
mit der selben fehlermeldung
wobei ich Buffer vorher als char declariert habe...
char Buffer[10];
oder
char *Buffer[10];
oder auch ohne längenangabe ... erfolglos
Loonix schrieb:> holger schrieb:>> Die 10 muss durch einen Zeichenpuffer ersetzr>> werden wo dein String auch reinpasst. Radix>> kennt dein itoa nicht.>> Die Warning[2054] hat er schon im Eröffnungspost.
Aber aus einem anderen Grund. Da hatte er noch keinen Prototypen und
daher itoa als Funktion angenommen, die einen int liefert.
Die 10 sind trotzdem falsch.
Deine char* / unsigned char* mismatch könnte es tatsächlich sein, aber
ich denke doch, dass sich der Compiler darüber beschwert, dass man ihm
einen int anstelle eines Pointers unterjubelt.
Gero Nimo schrieb:> tut mir leid, ich bin irgendwie nicht in der lage, auf einen grünen> zweig zu kommen...>> hab jetzt umgeändert in> LCD_WriteValue(itoa(minuten,Buffer));>> mit der selben fehlermeldung> wobei ich Buffer vorher als char declariert habe...> char Buffer[10];> oder> char *Buffer[10];> oder auch ohne längenangabe ... erfolglos
Dann teil das doch mal auf. Du musst das doch nicht so gedrängt
schreiben.
char Buffer[10];
itoa( minuten, Buffer );
LCD_WriteValue( Buffer );
Bei welcher Zeile gibts die Warning?
Gero Nimo schrieb:> hab jetzt umgeändert in> LCD_WriteValue(itoa(minuten,Buffer));
Und wie sieht der Prototyp von LCD_WriteValue aus?
1
voidLCD_WriteValue(unsignedchar*pdata)
Du übergibst hier einen char*, keinen unsigned char*.
Das ist der Grund für die Warnung, nicht die Deklaration von Buffer.
Es ist in solchen Problemfällen immer sinnvoll, nur ein Statement pro
Quelltextzeile zu haben und nicht mehrere zu schachteln.
Statt
1
LCD_WriteValue(itoa(minuten,Buffer));
solltest Du schreiben
1
itoa(minuten,Buffer);
2
LCD_WriteValue(Buffer);
Dann hättest Du klar gesehen, woher die Warnung kommt.
> wobei ich Buffer vorher als char declariert habe...> oder> char *Buffer[10];> oder auch ohne längenangabe ...
Die beiden letzten Varianten sind natürlich vollkommen falsch.
das witzige ist ja, das sobald ich die stdlib.h raus schmeiße, itoa ohne
alles benutze (lcd_writeValue(itoa(intzahl)); alles funktioniert ...
richtig im LCD angezeigt wird ... mich haben nur die vielen Warnings
gestört, beim compilieren^^
Gero Nimo schrieb:> das witzige ist ja, das sobald ich die stdlib.h raus schmeiße,
das ist das Blödeste was du tun kannst.
So eine Warnung:
1
Warning [2058] call of function without prototype
solltest du immer als Fehler ansehen und beheben.
Wenn sie kommt, dann muss der Compiler Standardannahmen treffen. Wenn
die passen, dann hast du Glück gehabt. Aber wehe wenn sie nicht passen!
(UNd bei dir haben sie nicht gepasst)
itoa ohne
> alles benutze (lcd_writeValue(itoa(intzahl)); alles funktioniert ...
scheinbar.
In Wirklichkeit hattest du einen enormen Bock geschossen, den du bisher
nur noch nicht bemerkt hast. Aber auch ein Fehler, den man noch nicht
entdeckt hat, ist und bleibt ein Fehler.
Üblicherweise wartet der solange zu, bis er maximalen Schaden anrichten
kann und schlägt dann erbarmungslos zu. Zb wenn du das Programm das
erste mal dem Kunden vorführst :-)
Gero Nimo schrieb:> das witzige ist ja, das sobald ich die stdlib.h raus schmeiße, itoa ohne> alles benutze (lcd_writeValue(itoa(intzahl)); alles funktioniert ...
Das ist eher ein sehr großer Zufall. itoa erwartet zwei Argumente, Du
übergibst nur eines. Das zweite Argument ist also was, was eher
zufälligerweise auf dem Stack steht. Sofern das eine RAM-Adresse ist,
kann itoa dort hineinschreiben und diese Adresse zurückgeben, auf daß
sie Deiner LCD_WriteValue-Funktion übergeben wird.
Mit anderen Worten: Das ist Pfusch der ganz üblen Art.
Gero Nimo schrieb:> wir sind noch nicht fertig^^ ... Code geändert in:>>
1
>itoa(minuten,Buffer);
2
>LCD_WriteValue(Buffer)
3
>
>> Ergebiss:>> Warning [2054] suspicious pointer conversion
bei welcher Zeile?
Sinn der Übung war es ja, herauszufinden, worin genau die Warnung
begründet ist. Also wurde deine ultrakompakte Lösung in 2 Teile zerlegt,
damit man weiter eingrenzen kann.
(Aber jetzt kann es nur noch der char*/unsiged char* mismatch sein)
uebergabe=uebergabe|0b01000000;//IORLW B'10000000' ; DDRAM AREA
53
OutLcdControl(uebergabe);
54
}
55
56
voidLcdBusy(void)
57
{
58
Delay1KTCYx(10);//2ms
59
60
TRIS_LCD=0b11110000;//TRISB || 0b11110000;
61
62
while(LcdStatus,7==1)
63
{
64
LcdRs=0;
65
LcdRw=1;
66
LcdE=1;
67
Nop();
68
LcdPort=0b11110000;
69
LcdStatus=LcdPort;
70
LcdE=0;
71
Nop();
72
LcdE=1;
73
Nop();
74
LcdE=0;
75
}
76
LcdRw=0;
77
TRIS_LCD=TRIS_LCD&0b00001111;
78
79
}
80
81
voidOutLcdControl(unsignedcharControlData)
82
{
83
unsignedcharx;
84
x=ControlData;
85
LcdBusy();
86
LcdDaten=ControlData;
87
x=x&0xf0;
88
LcdPort=x;
89
LcdE=1;
90
Nop();
91
LcdE=0;
92
93
x=ControlData;
94
x=(x<<4)&0xf0;
95
LcdPort=x;
96
LcdE=1;
97
Nop();
98
LcdE=0;
99
100
}
101
102
voidLCD_WriteString(staticconstromchar*string)
103
{
104
while(*string){LCD_WriteChar(*string++);}
105
}
106
107
voidLCD_WriteValue(unsignedchar*pdata)
108
{
109
//char Buffer[3] = IntWert;
110
charn=0;//
111
chartemp;//
112
while(temp=pdata[n++])//
113
LCD_WriteChar(temp);//
114
115
}
116
117
voidLCD_set_char(unsignedcharchararray[],intlen)
118
{
119
inti;
120
SET_CG_ADDR(0b00000000);
121
i=0;
122
while(i<len)
123
{
124
LCD_WriteChar(chararray[i]);
125
i++;
126
}
127
SET_DD_ADDR(0b00000000);
128
}
129
130
voidLCD_WriteChar(unsignedcharOutput)
131
{
132
unsignedcharx;
133
x=Output&0xf0;
134
LcdBusy();
135
LcdPort=x;
136
LcdRs=1;
137
LcdE=1;
138
Nop();
139
LcdE=0;
140
x=Output;
141
x=(x<<4)&0xf0;
142
LcdPort=x;
143
LcdRs=1;
144
LcdE=1;
145
Nop();
146
LcdE=0;
147
LcdRs=0;
148
}
149
150
voidControl8Bit(unsignedcharControlBit)
151
{
152
LcdPort=ControlBit;
153
LcdE=1;
154
Nop();
155
LcdE=0;
156
Delay1KTCYx(50);
157
158
}
159
160
161
162
voidLCD_INIT(void)
163
{
164
Delay10KTCYx(250);
165
LcdPort=0b00110000;
166
LcdE=1;
167
Nop();
168
LcdE=0;
169
Delay1KTCYx(250);
170
Control8Bit(0b00110000);
171
Control8Bit(0b00110000);
172
Control8Bit(0b00100000);
173
OutLcdControl(0b00000001);
174
OutLcdControl(0b00101000);
175
OutLcdControl(0b00001000);
176
OutLcdControl(0b00000110);
177
OutLcdControl(0b00000011);
178
OutLcdControl(0b00001100);
179
}
Will ich text ausgeben, dann:
LCD_WriteString("Mein Text");
Bei berechneten zahlen nahm ich immer :
LCD_WriteValue(itoa(intzahl));
WriteString: void LCD_WriteString(static const rom char *string);
WriteValue: void LCD_WriteValue(unsigned char *pdata);
itoa(minuten,Buffer);
LCD_WriteValue(Buffer); => Warning [2054] suspicious pointer conversion
ODER
itoa(minuten,Buffer);
LCD_WriteString(Buffer); => Warning [2066] type qualifier mismatch in
assignment
Lies doch einfach mal, was man Dir hier hinschreibt!
> void LCD_WriteValue(unsigned char *pdata);
Da steht unsigned char*
Und, wie ist Buffer deklariert?
Gero Nimo schrieb:> hab ich gelesen und geändert, leider mit gleichbleibender Fehlermeldung> beim itoa aufruf>> Warning [2054] suspicious pointer conversion
Und, was sagt dir das jetzt?
auf der einen Seite bräuchtest du für itoa ein char Array
Und auf der anderen Seite bräuchtest du für LCD_WriteValue ein unsigned
char Array.
Ein Array kann aber nicht beides gleichzeitig sein. Es kann nicht
gleichzeitig nur char und trotzdem unsigned char sein.
Was ist deine Schlussfolgerung?
Na siehste.
Und beim nächsten mal kennst du die Fehlermeldung bereits und weißt,
worauf du achten musst.
Datentypen müssen übereinstimmen. Tun sie das nicht, dann kann das ein
Hinweis auf einen systematischen Fehler sein.
Ist wie in der Physik. Wenn man eine Geschweindigkeit berechnet, indem
man Körpermasse durch Wegstrecke dividiert, dann kann da was nicht
stimmen.
Körpermasse hat als Einheit kg, Wegstrecke hat als Einheit meter.
Berechnet wird also kg / meter. Eine Geschwindigkeit hat aber die
Einheit meter / sekunde. Also kann bei dieser Berechnung der
"Geschwindigkeit" schon mal etwas nicht stimmen.
meter / sekunde = kg / meter
das passt hinten und vorne nicht. Da steht links vom = und rechts davon
völlig andere Einheiten. Was auch immer da berechnet wird, es kann
keine Geschwindigkeit sein.
Und deine 'Einheiten' sind in der Programmierung eben die Datentypen von
Variablen. Wenn die nicht zusammenpassen, dann kann das ein Hinweis auf
ein verstecktes Problem sein. Und deshalb warnt dich der Compiler.