STM32+HALのUSARTでprintf(float),scanf, FPUを有効可

2019年6月26日

stm32 + makefileでのprintf,scanf,FPUの設定の仕方をやっていきたいと思います。

私が使用するマイコンはSTM32F405RGTです。

 




STM32CubeMxの設定

 

USARTの設定

Project Managerから.c,.hファイルに分けるというところにチェックを入れたのちコード生成をしてもらいましょう。USARTのボーレートはTeraTermなどのターミナルアプリケーションと同じ速度(bit/sec)に設定する必要があるので、各自の環境にあった値を設定してください。

プロジェクト名などを決めたらコードを生成してもらいましょう。

続いて、FPUの設定を行っていきます。

 

FPUの設定

Float Processing Unit:浮動小数点ユニットのことです。

今回使用するstm32F4シリーズには上記のFPUが搭載されており、機能を使用して計算するのとしないのとでは速度が圧倒的に速くなるそうなので有効にしたいですね。

有効にすることで”arm_math.h”に定義されている関数や数値を使用することができるようになります。

はじめに、プロジェクトの中の以下のディレクトリに

があるかどうかを確認してください。

ない場合は、stm32cubemxのファームウェアがダウンロードされているディレクトリに移動して”libarm_coretexM4lf_math.a”をコピーしにいきます。stm32cubemxのファームウェア直下のマイコンのシリーズのファームのディレクトリ内にありました。

私の環境では、以下のディレクトリにありました。

続いて、makefileを変更します。

libarm_cortexM4lf_math.aは静的ライブラリなので、プログラムにリンクする必要があるため、リンカーフラグに追加することでリンクすることができました。

これで、コンパイルをして無事コンパイルができればFPUを有効化できたと思います。

 

printfの設定

printfを表示するためには、syscalls.cというc言語ファイルが必要になります。STM32のサンプルコードのディレクトリ内にあるので探して、コピーをして持ってきてください。

syscalls.cをSrc直下に置き、makefileのC_SOURCESの一番したに追加してコンパイル対象のファイルとして追加してください。printfのfloat型を表示できるようにリンカーフラグに-u _printf_floatを追加する必要があるので追加も一緒にします。

 

syscalls.cの中身を見ていきます。printfはwriteシステムコールを使用するそうです。

writeの実装がどうなっているのか確認すると、

__io_putcharという関数が使われていることがわかります。

これは、ファイルの上部で

とありますが実体がないので実体の定義をしたいと思います。

定義内容は、_write内で文字を一文字ずつ送っているということも読み取れるので、UARTで文字を1文字ずつで送るプログラムを書けばいいということがわかります。

HALドライバでUARTを一文字ずつ送ることは、HAL_UART_Transmitという関数で可能です。

上記のことを踏まえてmain.cのuser code begin includeとendの間にソースを追加していきます。

printfを使用するために、標準入出力ファイルをインクルードして、マクロ定義でコンパイラごとにPUTCHAR_PROTOTYPEの読み替えが聞くようになってます。

理由としては、stm32のgccの定義がGNUCと違うためです。

printfのサンプルコードは以下のようになりました。

 

 

scanfの実装

scanfはシステムコールreadを使用するそうなのでreadの実装を見てみると

となっているので、printfと同様に__io_getchar()を定義しなおして使用することができるようになります。

scanfも使えるようにmain.cに追加でコードを書くと次のようになりました。

 

scanfでfloat型を読み込みたいときはリンカーフラグに-u scanf_floatを追加することでできました。

サンプルコード

サンプルコードの実行結果

 

さいごに

マイコンで標準入出力の関数が使えるっていいですね。

PCと同じ感覚でプログラムを書くことができてとても便利です。

参考文献

UM1725 User Manual