Nucleo-32boardを使ったクラシックマウスの開発その12 ~UART~
UARTを使ってターミナル上に
printfでHello Worldする話です。
基本的に送信関数しか扱いません。
今回はほぼほぼ自分用の備忘録です。
・UARTの設定
参考記事はこちら。
STM32でUARTをやってみる1 -ガレスタさんのDIY日記
基本的に上の通りでやっていれば、動くと思います。
F303ボードではあらかじめ、
USART2用のピンが接続されています。
間違えないように。
Configurationについてです。
今回はこんな設定にしました。

これについてですが、
出力先のターミナルと設定を合わせる必要があります。
TrueSTUDIOの場合、あらかじめシリアルターミナル
のプラグインが入っているのでこちらを使って表示させます。

送信関数についてですが、
しっかりHALのマニュアルを読んでおきましょう。
/* USER CODE BEGIN 2 */
uint8_t hello[] = "Hello World\n\r";
HAL_UART_Transmit(&huart2, hello, sizeof(hello), 1000);
/* USER CODE END 2 */
無事にHello WorldがでればOKです。

・printfについて
UART機能が使えることが確認できました。
しかし、HAL_UART_Transmit関数は任意の文字列を出力できる関数であって、
実際に使うことを考えると不便です。
フォーマット指定子を使える形に対応させます。
参考記事はこちら
STM32でUARTをやってみる6 -ガレスタさんのDIY日記
SW4STM32の場合は参考記事通りにやって動きました。
TrueSTUDIOでも同様の方法でやっていきますが、
少し違う部分もあるので備忘録。
そもそもなんでsyscalls.cが必要なのか。
自分もそこまで詳しくないですが、
printf関数は_write関数という関数に従って出力を行うようです。
_write関数の出力先をUARTに設定することで、
printfの出力先をシリアルターミナルにします。
この_write関数が含まれるのがsyscalls.cみたいです。
→詳しい人が教えてくれると信じたい
まずは、syscalls.cを作ってもらいましょう。
ファイル→新規→C Projectです。
TrueSTUDIOではこうやれば作れました。
Embedded C Project→Atollic ARM Toolsを選択

一応ハードウェアを選択

syscalls.cを生成できるように選択

終了→syscalls.cがある

syscall.cを自分のプロジェクトのSrcにコピーして、
作ったプロジェクトは消しましょう。
※12/25更新
上のようなことをしなくても、
新規→その他→システムコールから簡単に生成できるようです。

次にこのsyscall.cを開いて
_write関数の中身を書き換えます。
このとき、
#include "usart.h"
をすることは忘れないこと。
int _write(int32_t file, uint8_t *ptr, int32_t len) {
/* Implement your write code here,
this is used by puts and printf for example */
/* return len; */
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++) {
HAL_UART_Transmit(&huart2, ptr++, 1, 1);
}
return len;
}
これは_write関数の中で
文字列を1byteづつ送信する
といった内容です。
これを見て愚か者が想像できる範囲では、
printfの流れは、
① フォーマット指定子に従って値を文字列に変換
② _write関数にて1文字づつ出力する
といった物だということがわかりました。
この「文字列に変換→1文字づつ出力する」
といった流れはLCDのときにも使うので覚えておいてください。
→Mice伝統の秘伝のタレも基本は同じです
ところで、これでprintf関数が使えるようになったと思います。
→M_PIを使うには#include <math.h>を忘れない。
/* USER CODE BEGIN 2 */
uint8_t hello[] = "Hello World\n\r";
setbuf(stdout, NULL);
printf("hello=%s", hello);
uint8_t hoge = 3;
printf("hoge=%d\n\r", hoge);
printf("M_PI=%f\n\r", M_PI);
/* USER CODE END 2 */
出力結果

printfが動いてますね。
ん?%fが使えていない??
・floatに対応させる
ではprintfをfloat型に対応させましょう。
といってもその方法も先ほどの参考記事に書いてあります。
プロジェクト→プロパティ→C/C++Build→Settings→Tool Settings→C Linker→Miscellaneous→Other options
に「-u _printf_float」を追加するだけです。
無事にfloat型も出せたら終了です。

・やっぱりTera Termがいい
シリアルターミナルの話です。
今回はプラグインのシリアルターミナルを使用しましたが、
やっぱりTera Termの方が使いやすいと思いました。
→設定が柔軟にできる。体に染みついている。\rを書きたくない。
設定を保存して、Tera Termをタスクバーに置いておく方が
自分には合っているなと感じたので、
今後シリアルターミナルを使うときがあったら
Tera Termを使います(笑)
あとは余談ですが、
せっかくデバッガが使えるならデバッガのウインドウに
出力してみると面白そうだなと思いました。(参考)
→気が向いたら読みたいのでブックマーク代わりに貼る
自分の技術力が足りていなく、
デバッガの使い方がわかっていないのが残念過ぎる。
スポンサーサイト
コメント : 1 ]

| ホーム |