'0' (0x30 im string) != 0x00 ('\0' als stringende)
in C wird 0x00 oft als Markierung für das Ende eines Strings genutzt,
sofern deine usart_write_P() wie printf() arbeiten sollte, fügt auch sie
das am Ende ein.
Lass dir auf einem PC vielleicht mal einen String als HEX ausgeben,
damit du die einzelnen Bytes siehst
Ich kann mir einfach nicht erklären Warum der XC18 Compiler hier diesen
Fehler ausschreibt:
../../../Microchip/TCPIP Stack/UART.c:213:Error: syntax error
Vermutlich erlaubt der Compiler es nicht ohne weiteres, in einem
switch/case-Konstrukt Variablen zu definieren:
Probier mal, entweder i vorher zu definieren oder um die ganzen
Anweisungen {} zu setzen:
simon schrieb:> void usart_write_P (const char *Buffer,...)> ...> Aufruf mit:> usart_write_P("receive: %i \n", (int) u);
Der Aufruf passt nicht zum Prototypen. usart_write_P erwartet einen
Zeiger auf Characters, nicht einen int. Was versuchst du hier zu tun?
Ich habe mal die ConversionLoop ganz auskommentiert.
Nun klagt er über
UART.c:202:Warning [2054] suspicious pointer conversion
1
voidputsUSART(char*data){
2
3
}
4
5
6
voidusart_write_P(constchar*Buffer,...)
7
{
8
intformat_flag;
9
10
11
12
case'c':
13
//Int to char
14
format_flag=va_arg(ap,int);
15
putsUSART(format_flag++);// <___ Fehler
16
break;
Also wir halten mal fest, der code hat auf einem ATxmega bestens
funktioniert.
Nur was ich mich nun Frage va_arg Liefert doch ganz klar ein integer
zurück.
Der Integer wird mit format_flag++ um eins erhöht (ist aber kein
Pointer)
putsUSART erwartet ein char pointer.
kann ich hier nun einfach casten mit
Tom M. schrieb:>> void usart_write_P (const char *Buffer,...)>> ...>> Aufruf mit:>> usart_write_P("receive: %i \n", (int) u);>> Der Aufruf passt nicht zum Prototypen. usart_write_P erwartet einen> Zeiger auf Characters, nicht einen int. Was versuchst du hier zu tun?
der *Buffer ist das "receive: %i \n" danach folgt (int) u was ein
weiterer Parameter der funktion ist.
also ich es scheint so als "na" recht hatte,
er erlaubt mir keine Variablen inerhalb von switch zu definieren.
Und ito weicht zwischen GCC und XC18 auch ab
GCC:
char *itoa (int __val, char *__s, int __radix)
XC18:
char *itoa (auto int value, auto char *s);
es gibt da kein radix.
Gibt es da beim XC18 irgend eine Standard Funktion um ein byte
umzuwandeln in ein string der den hex wert enthällt?
BYTE b = 255;
sooo mir in einen string 0xFF schreiben.
Warum nimmst Du nicht einfach das fertige printf()? Brauchst Du wirklich
die paar Byte Programmspeicher, die Du mit der Selbstbauvariante ggf.
sparst? Mir wärs das nicht wert ...
Na offenbar hast du ja ein
putsUSART(str_buffer);
zur Verfügung.
Also:
void putiUSART( int i )
{
char buffer[10];
itoa( buffer, i ); // weil dein itoa ja kein radix Argument hat
putsUSART( buffer );
}
oder
void putiUSART( int i )
{
char buffer[10];
sprintf( buffer, "%d", i );
putsUSART( buffer );
}
das sollte es wohl fürs erste tun.
Edit: Argh. WEnn man keine Tippfehler machen würde. Arrays werden
natürlich mit [ ] geschrieben und nicht mit ( )
simon schrieb:> eh ja, ich würde natuerlich auch sprintf oder printf nehmen wenn ich das> mit meiner UART funktion verwenden kann
Du brauchst nur eine Funktion, die ein einzelnes Zeichen per UART
ausgibt:
1
intuart_putchar(charc,FILE*stream)
2
{
3
returnputcUSART(c);
4
}
Die registrierst Du als Ausgabefunktion eines FILEs. Beim AVR
funktioniert das so:
Um Deine ursprüngliche Frage zu beantworten:
simon schrieb:> wieso kann man hier mit by==0 abfragen ob der Buffer zu Ende ist?> würde das nicht zu einem Problem führen wenn u == 0?
Die Funktion
1
voidusart_write_P(constchar*Buffer,...)
ist eine Funktion mit variablen Argumenten ("VarArgs"), zu erkennen an
dem "..." als Argument(enliste).
In einer solchen Funktion wird mithilfe von "stdarg.h" die variable
Liste von Argumenten abgearbeitet.
Dein Code-Ausschnitt
1
by=pgm_read_byte(Buffer++);
2
if(by==0)break;// end of format string
bezieht sich nun einzig und allein auf den String, den Du in "buffer"
übergeben hast, aber keineswegs auf die weiteren Argumente.
Das heißt
1
usart_write_P("receive: %i \n",(int)u);
übergibt in "buffer" den String "receive: %i \n", welcher mit dem
impliziten Character 0x00 abgeschlossen ist.
Die Bedingung
1
if(by==0)
wird also wahr, wenn dieses implizite 0x00 erreicht wird.
Was die Funktion aber mit den anderen Argumenten anfängt, hat damit gar
nichts zu tun.