スキータイム計測機 開発日誌

とある大学生の競技スキー用タイム計測機の開発日誌です。とかいいつつ関係ないことも書きます。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

C18でfprintfを使う(_user_putc関数の設定)

C18コンパイラにもprintfといった標準文字出力関数が存在します。
その関数はコンパイラをインストールしたフォルダのstdio.hにまとめられているのですが、挙げてみると

putc
vsprintf
vprintf
sprintf
printf
fprintf
vfprintf
puts
fputs

のように様々な関数が存在します。
それぞれ使いかたが違うものもあるわけですが、もし使うのであればfprintfのみで十分かと思います。

これひとつでUSART、キャラクタLCDへのフォーマット指定出力が可能になります。
ただ、USARTへは特に何も設定せず使えるのですが、fprintfをLCDへ出力するためには、そのための_user_putc関数というのを設定しなければなりません。
今回はfprintfを使ってUSART、LCDへフォーマット指定をして出力する方法について書きたいと思います。


ちなみに、標準文字出力関数については、後閑哲也氏の「電子工作のためのPIC18F本格活用ガイド」にも載ってます。


まずfprintfについて簡単に説明すると、この関数はストリーム(出力先)とフォーマットをそれぞれ指定できる関数で、stdio.hをインクルードすることでPIC18Fで使えるようになります。
USARTとLCD一緒に書くとごっちゃになりそうなので分けて書くことにします。


・fprintfでUSARTに出力する方法
こちらは簡単です。
PIC18Fには標準でハードウェアUSARTが備わっているので、USARTの設定を行ったあと、fprintfをすぐに使う事ができます。
その際、ストリームには「_H_USART」を指定すればOKです。

例:

(USART設定省略)
int i = 100;
fprintf(_H_USART,"Hello%d",i);   //「Hello100」と出力

fprintf(_H_USART,"Hello%4d",i)   //「Hello 100」など文字数指定もできます


引数はフォーマットが正しければ2個以上指定ももちろん可能です。



・fprintfでLCDに出力する方法
さらに、fprintfでキャラクタLCDにも文字出力ができれば、fprintfのみで便利に文字出力が可能になります。
これを行うには、fprintfのストリームに_H_USERを指定すればいいのですが、USERの文字からわかるように、出力関数はユーザーによって指定されなければなりません。
つまり、LCDに文字を出力する関数をfprintf用に書いてやらなければならないわけです。


なお、ここから先は既にRAM文字列をLCDに出力することはできて、lcd_data(char c)という1文字出力用関数が既にできている前提で話を進めていきます。


fprintf関数で最終的に使われるputc関数(MCC18\src\traditional\stdclib\putc.c)を見てみると、ストリームに「_H_USER」を指定した場合_user_putc(c)が呼び出されることがわかります。
じゃぁ_user_putc(c)ってなんぞ、ということですがこれもputc.cと同じフォルダにあります。MCC18\src\traditional\stdclib\_user_putc.cというやつです。
これをひらいてみると「デフォルトでは何もしません。_H_USERストリームを使う場合はintを返す関数を作ってね」みたいなことが書いてあります。


ユーザー用の関数はつくるものによって変わるので、まずこの_user_putc.cをプロジェクトフォルダにコピーし、プロジェクトに加えてください。
その上でユーザー用の関数をそれに書いていきます。


書くこととしては、引数であるchar型のcをLCDに出力し、int型を返せばOKです。
何を返り値とすればいいかですが、fprintfから呼び出されるvfprintfを見てみると、EOF(stdio.hで(int)-1と定義されている)を返された場合以外OKのようなので、-1以外の数(0とか1とか)を返せばいいと思います。



例:(_user_putc.c)

/* this default version should not do anything. it is entirely a
placeholder symbol. To keep code size at a minimum, it is declared
without a return value or parameters. The caller will still clean up
the stack frame correctly.

When using the _H_USER stream, the function will be implemented in
application code with the prototype:
int _user_putc (char c);
*/
//LCD 出力fprintf文用出力関数)
#include "lcdlib18.h"
int
_user_putc (char c)
{
lcd_data(c);
return 1;//OK
}


とこのようなものです。出力して1を返すだけです。返り値の型をintにするのを忘れずに。
インクルードしているlcdlib18.hはlcd_data関数を宣言しているヘッダです。


これだけ書いてプロジェクトに追加すれば、fprintf関数のみで、USART、LCDへフォーマット指定して出力することが可能になります。便利です。


なお、USARTに出力する場合はfprintfではなくprintfでも可能です。
printfはstdoutにフォーマット指定で出力するのですが、PICの場合stdoutはハードウェアUSARTに設定されているので、printfでUSARTに出力することもできます。


標準文字出力関数は他にもあるので、色々試してみるといいと思います。
スポンサーサイト
次のページ

FC2Ad

まとめ

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。