久々にプログラミングの話題です。
さて、AVRでは適切な初期化を行えばprintfを用いることができます。また、avr-gccはデフォルトでは文字列定数をRAMに配置しますが、適切な記述を行うことでROMに配置することができます。おそらく、この二件は誰かが解説してくれると思いますので、詳しいことは省略します。(よろしくねShiozakiさん)
ところで、printfも同様にROMに配置された文字列定数を扱うためのprintf_Pが存在します。しかし、この関数を使うためにはprintf_P(PSTR(“Hello world!n”));というように二重括弧になりタイプ数が増えてしまいます。そこで、簡略化するためにマクロを使うと便利です。しかし、普通のマクロでは以下のように面倒なことになります。
[c]
#define P(str) printf_P(PSTR(str))
#define P2(str,a) printf_P(PSTR(str),a)
#define P3(str,a,b) printf_P(PSTR(str),a,b)
#define P4(str,a,b,c) printf_P(PSTR(str),a,b,c)
[/c]
これでは面倒なのでC99から導入された可変長引数マクロを利用してみましょう。
[c]
#define PF(format,…) printf_P(PSTR(format),__VA_ARGS__)
[/c]
このように書くと複数の引数をとるprintfを簡便に書くことができます。けれども、これでもまだ問題があります。フォーマットを利用しない引数が一つだけのprintfを利用することができません。そこでGCCのドキュメントの最後に書かれている仕様を利用してみましょう。
[c]
#define PF(format,…) printf_P(PSTR(format) , ##__VA_ARGS__)
[/c]
こうすると引数が一つだけのprintfも受け付けることができるようになります。必要に応じてデバッグメッセージの切り替えに用いたりしてみてください。
by Y.O