2016-07-12 18 views
1

Ich verwende ATmega8 und ich versuche, Zeichenfolge über USART (in printf Stil), die eine Variable enthalten. Ich verwende Atmel Studio 6.2 als IDE für AVR-Programmierung. Hier ist mein Code: -Übergabe einer Variablen in String in Embedded C

#define F_CPU 8000000UL 
#include <avr/io.h> 
#include <util/delay.h> 

void USARTInit(uint16_t ubrr_value) // initialize USART 
{ 

    UBRRL = ubrr_value; 
    UBRRH = (ubrr_value>>8); 
    UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); 
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN); 

} 

void USARTWriteChar(char data) // send character using USART 
{ 

    while(!(UCSRA & (1<<UDRE))); 
    UDR=data; 
} 

void send_string(char s[]) // send string using USART 
{ 
    int i =0; 

    while (s[i] != 0x00) 
    { 
     USARTWriteChar(s[i]); 
     i++; 
    } 
    USARTWriteChar('\n'); 
} 


int main(void) 
{ 
    USARTInit(51); 
    char val='A'; 
    while(1) 
    { 
     send_string("Value = %c",val); 

    } 
} 

Nun, wenn ich meinen Code zu kompilieren ich diesen Fehler hätte: -

too many arguments to function 'send_string`

Also, klar ist es nicht akzeptieren %c, wie es in der C-Programmierung funktioniert. Gibt es eine Möglichkeit in embedded C eine Variable in einem String zu übergeben?

+0

Es gibt keine Sprache „Embedded C“! Und diese Funktion ist nicht Teil der Standard-Bibliothek, also ** funktioniert nicht in "C-Programmierung". Vielleicht möchten Sie zuerst lernen, C und welche Funktionen sind. – Olaf

Antwort

1

too many arguments to function send_string

Die Botschaft ist ganz klar da, Ihr send_string() akzeptiert nur einen Zeiger auf char als Eingabeargument, aber beim Aufruf, Sie versuchen, zwei Eingänge Argumente zu übergeben "Value = %c",val wodurch die Fehlanpassung.

Formatbezeichner können hier nicht wie angegeben verwendet werden.

Im Allgemeinen besteht die Möglichkeit, einen temporären Puffer zu verwenden, verwenden Sie snprintf(), um die Eingabezeichenfolge zu generieren, und übergeben Sie den Puffer dann an den send_string()-Aufruf.

das gesagt ist, da Sie nur interessiert nebenbei den Wert von c-send_string() sind, können Sie die Funktion reduzieren kann nur eine char, wie

void send_string(char s) { ... 

und dann übergeben Sie die Konstante zu nehmen (vordefiniert) Zeichenfolge Value = und dann das Eingabeargument erhalten den gleichen Effekt.

+0

Sie können tatsächlich * können * - Aber Sie müssen die Funktion neu schreiben, um eine variable Argumentliste zu nehmen. Ihre Methode, die 's [n] printf verwendet, ist jedoch weniger aufwendig. – tofro

+1

Sorry, aber die 'printf'-Bloat auf einem Embedded-System ist eine wirklich schlechte Idee - wenn es überhaupt verfügbar ist. – Olaf

+0

@tofro deshalb habe ich _ ".. die Art und Weise, die Sie gezeigt haben .." _ erwähnt. –

-1

Erstens gibt es keine eingebettete C-Sprache. Sie programmieren in C. Und dieser Code ist ungültig.

Ihre Funktion void send_string(char s[]) akzeptiert nur ein Argument vom Typ char []. Sie nennen es send_string("Value = %c",val);, also übergeben Sie zwei Argumente an es. In C-Strings % Zeichen hat keine besondere Bedeutung. Es ist nur sinnvoll, printf Funktionen. Sie rufen entspricht send_string("It doesn't matter what you write here", 'A');

Sie können tun, was Sie in einer anderen Art und Weise wollte:

#include <stdio.h> 
... 
int main(void) 
{ 
    USARTInit(51); 
    char val='A'; 
    char buffer[64]; 
    sprintf(buffer, "Value = %c", val); 
    while(1) 
    { 
     send_string(buffer); 
    } 
} 
+0

Ich wiederhole, was ich zu der anderen Antwort geschrieben habe: Die Verwendung des 'printf'-Bloat auf einem eingebetteten System ist eine wirklich schlechte Idee - wenn es überhaupt verfügbar ist. (Und Ihre Antwort enthält das gleiche wie das andere, nur ein wenig ausgeklügelter). Übrigens. 1KiB Puffer auf einem System, das nur 1KB RAM hat ?? Ernst? – Olaf

+0

@Olaf Es sollte so schlimm sein, solange du es nicht zu oft nennst.Für mich lief es auf STM32 recht gut. Auf Atmega8 muss es allerdings schlimmer sein ... Und ja, wahrscheinlich ist 1KiB Puffer auf Atmega8 keine so gute Idee ... Wie auch immer, wir wissen nicht, was OP versucht zu erreichen, aber er wollte eindeutig 'printf' Syntax verwenden. Ich empfehle es auch nicht. – Rames

+0

@Olaf Ich meine, wenn die Operation dauert 1 Sekunde, aber es wird einmal pro Minute ausgeführt, dann kann seine Ausführungszeit akzeptabel sein. Ich habe die Frage einfach beantwortet. Er wollte die 'printf'-Syntax verwenden. Schreiben Sie eine bessere Antwort, wenn Sie möchten, aber OP ist kein erfahrener Programmierer und wollte etwas Einfaches ... Was langsam ist und was nicht, hängt von Ihren Anforderungen ab. Manchmal möchten Sie ein Feature schnell implementieren, ohne die Float-to-String-Konvertierung und ähnliches neu zu erfinden. – Rames