DATE: 2018/07/27(金)   CATEGORY: Nucleoマウス
Nucleo-32boardを使ったクラシックマウスの開発その12 ~UART~

UARTを使ってターミナル上に
printfでHello Worldする話です。

基本的に送信関数しか扱いません。

今回はほぼほぼ自分用の備忘録です。

・UARTの設定

参考記事はこちら。
STM32でUARTをやってみる1 -ガレスタさんのDIY日記

基本的に上の通りでやっていれば、動くと思います。

F303ボードではあらかじめ、
USART2用のピンが接続されています。
間違えないように。

Configurationについてです。
今回はこんな設定にしました。

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です。

HelloWorld.png


・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の生成を選択

終了→syscalls.cがある

syscallsがある

syscall.cを自分のプロジェクトのSrcにコピーして、
作ったプロジェクトは消しましょう。


※12/25更新
上のようなことをしなくても、
新規→その他→システムコールから簡単に生成できるようです。

syscallsの生成


次にこの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の確認

printfが動いてますね。
ん?%fが使えていない??


・floatに対応させる

ではprintfをfloat型に対応させましょう。
といってもその方法も先ほどの参考記事に書いてあります。

プロジェクト→プロパティ→C/C++Build→Settings→Tool Settings→C Linker→Miscellaneous→Other options
に「-u _printf_float」を追加するだけです。

無事にfloat型も出せたら終了です。

float確認


・やっぱりTera Termがいい

シリアルターミナルの話です。
今回はプラグインのシリアルターミナルを使用しましたが、
やっぱりTera Termの方が使いやすいと思いました。
→設定が柔軟にできる。体に染みついている。\rを書きたくない。

設定を保存して、Tera Termをタスクバーに置いておく方が
自分には合っているなと感じたので、
今後シリアルターミナルを使うときがあったら
Tera Termを使います(笑)



あとは余談ですが、
せっかくデバッガが使えるならデバッガのウインドウに
出力してみると面白そうだなと思いました。(参考
→気が向いたら読みたいのでブックマーク代わりに貼る

自分の技術力が足りていなく、
デバッガの使い方がわかっていないのが残念過ぎる。


スポンサーサイト




コメントの投稿

 管理者にだけ表示を許可する
管理人のみ閲覧できます
| | 2019/05/09(木) 15:19 [編集]
このコメントは管理人のみ閲覧できます
Copyright © うむ夫の歩み. all rights reserved.