2016-07-12 15 views
1

私はATmega8を使用していますが、変数を含むUSART(printfスタイル)の文字列を送信しようとしています。AVRプログラミングのIDEとしてAtmel Studio 6.2を使用しています。ここに私のコードは次のとおりです。 - 私は私のコードをコンパイルするとき埋め込み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); 

    } 
} 

は今、私はこのエラーを得た: - それはCプログラミングの場合と同様

too many arguments to function 'send_string`

だから、明らかにそれは%cを受け付けていません。 embedded Cに文字列の変数を渡す方法はありますか?

+0

何語「組み込みC」はありません!その関数は標準ライブラリの一部ではないので、 "Cプログラミング"では**動作しません。あなたは、まずCと関数が何であるかを知りたいかもしれません。 – Olaf

答えて

1

too many arguments to function send_string

メッセージがあなたのsend_string()は、入力引数としてcharへのポインタだけを受け入れますが、呼び出し中に、あなたはミスマッチを引き起こして2つの入力引数を渡す"Value = %c",valしようとしている、そこには非常に明確です。

フォーマット指定子は、ここで示した方法で使用することはできません。

一般に、テンポラリバッファを使用するには、snprintf()を使用して入力文字列を生成し、バッファをsend_string()コールに渡します。

言った、あなただけのsend_string()cの値を渡すことで興味を持っているので、あなたは

void send_string(char s) { ... 

のように、唯一のcharを取るために機能を削減してから、定数を渡すことができます( 事前定義)の文字列Value =と入力引数goが同じ効果を得ます。

+0

あなたは実際に* can * - しかし、可変引数リストを取るために関数を書き直す必要があります。しかし、 's [n] printf'を使ったあなたの方法ははるかに少ない労力です。 – tofro

+1

申し訳ありませんが、組み込みシステムで 'printf'-bloatを使用することは本当に悪い考えです。 – Olaf

+0

@tofroだからこそ私はあなたが示したように言いました。 " –

-1

まず、埋め込みC言語のようなものはありません。あなたはCでプログラミングしています。そして、このコードは無効です。

あなたの関数void send_string(char s[])は、タイプchar []の引数を1つだけ受け取ります。あなたはsend_string("Value = %c",val);と呼んでいるので、2つの引数を渡しています。 Cの文字列%には特殊な意味はありません。 printfの機能には意味があります。あなたはあなたが別の方法で望んでいたものを行うことができますsend_string("It doesn't matter what you write here", 'A');

と同等です呼び出す:

#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

私は他の答えに書いたことを繰り返します:組み込みシステムで 'printf'-bloatを使うのは、まったく利用できない場合、本当に悪い考えです。 (あなたの答えは他のものと同じですが、もう少し精巧です)。 Btw。わずか1KiBのRAMを搭載したシステム上の1KiBバッファ真剣に? – Olaf

+0

@Olafあなたはそれをあまりにも頻繁に呼び出さない限り、それは悪いはずです。私にとっては、STM32ではかなりうまくいっていました。 Atmega8ではそれは悪化するはずです...そしてそうです、Atmega8の1KiBバッファは良い考えではありません...とにかくOPが何を達成しようとしているのか分かりませんが、明らかにprintf構文を使いたいと思っていました。私もそれをお勧めしません。 – Rames

+0

@Olaf私は、操作に1秒かかるが、1分に1回実行されると、その実行時間は受け入れられることを意味します。私は単にその質問に答えました。彼は 'printf'構文を使いたいと思っていました。あなたが望むなら、より良い答えを書いてください。しかし、明らかにOPは経験豊富なプログラマーではなく、単純なものを求めていました。浮動小数点数から文字列への変換やそのようなものを再開発することなく、素早く機能を実装したいことがあります。 – Rames

関連する問題