STM32でUARTをやってみる5(MicroShell

こんかいもUARTのネタです

中村さん作のMicroShellの話でございます。

実を言うと中村さんには一度SignalBottomでお会いしたことがあります。
その時は中村さんの作品を一つしか使ったことなかったので次回お会いできる機会があれば聞いて見たいことをいっぱい聞いて見たいと思います。

本人blogは以下のリンクから

shinta-main-jp.blogspot.jp

本題

簡単に説明すると組み込み用Shellです。

導入はLPCのサンプルプロジェクトが入ってるのでEclipseプロジェクトでの導入は楽だろう
しいて言えば

  • uart_getc
  • uart_putc
  • uart_puts

APIがSTMにないのでラッピングして作るのが結構めんどかったりする。

とりあえずlibファイル一式インポートして
f:id:gsmcustomeffects:20170324025400p:plain

指示通りAPIをパースする。

f:id:gsmcustomeffects:20170324025656p:plain

main.cの無限ループ内で以下の記述をする

f:id:gsmcustomeffects:20170324025938p:plain

あとは好きにコマンドなりをサンプルと同じように追加していく

f:id:gsmcustomeffects:20170324030112p:plain

Teratermで確認

適当にコマンド追加してLEDトグルしてみた

f:id:gsmcustomeffects:20170324030243p:plain

タスクの追加方法

上部でタスクを定義

f:id:gsmcustomeffects:20170417200057p:plain

コマンドテーブルに追加

f:id:gsmcustomeffects:20170417200203p:plain

実際の処理部分を追加

f:id:gsmcustomeffects:20170417200345p:plain

まとめ

いやぁ凄いの一言

ここまで簡単に使えてコードサイズが10KB程度って凄すぎでしょ・・・・・・・・
F030で普通に使えるし

コマンド追加も結構楽

あとはデバッグ途中関数ポインタを使った簡単なプログラムでつまずいてリアルテック氏にご教授いただいたのでもっと勉強します。
ポインタできないと彼女できないらしいので・・・・・

STM32でUARTをやってみる4(Chanさんのxprintf)

今回はやっとこの話題を書いていく。

  • uart_getc
  • uart_putc
  • uart_puts

が必要なのでそれを読んでほしい

gsmcustomeffects.hatenablog.com

Xprintf

組み込み用printfモジュールである。
まあ組み込みだと素のprintfが使えないことが多いしましてやUARTに吐くとなるといろいろな制約がある。
そこでFatFsで有名なChan氏が作ってくれたのである。

詳しくは以下参照

ELM - 組み込み用printfモジュール

導入

ダウンロードされた

  • xprintf.h
  • xprintf.c

をプロジェクトにインポートする。

ファイルからコピーしてペーストするとこういうふうに入る

f:id:gsmcustomeffects:20170324022100p:plain

んでmain.cでインクルード

f:id:gsmcustomeffects:20170324022210p:plain

使ってみる

使い方は結構簡単で上記の送信関数uart_putcをxdev_outマクロに投げるだけだ。
ポインタ形式じゃないのはChanさんが丁寧にマクロ化してくれてるからです

f:id:gsmcustomeffects:20170324022518p:plain

APIは普通のprintfと同じ(xprintfだけど
ちなみに浮動小数点は非対応

f:id:gsmcustomeffects:20170324023134p:plain

Teratermで確認

こんな感じになってればOK

f:id:gsmcustomeffects:20170324023211p:plain

まとめ

今回はUARTのちょっとした利用例とのことでprintfを作ってみたがSTのsampleにも似たようなものがあった気がする(あれば謎

でも汎用モジュールなのでやはりCHANさんが最強w

STM32でUARTをやってみる3

前回と前々回でUARTのくっそ簡単な送受信について書いたんだけど今回はグローバル変数いちいち作るのダサいしそんなのあんましつかわんよね見たいな感じだったので
LPCマイコンAPIで用意されてるやつをSTMでも作ってみようということで

  • uart_getc
  • uart_putc
  • uart_puts

的なのを作る。


作るとはいっても送信APIと受信APIをラップするだけ(おい~

f:id:gsmcustomeffects:20170323125050p:plain

まあ適当につくったのでこんな感じ

これがあるとこんな感じで文字列型で投げれるのでちょいちょいデバッグしたいときに便利
まあ最近はデバッガで変数の中の値を見れるので組み込み用ミニprintfなんかを作らなくてもいいかななんて思うこともしばしば。

f:id:gsmcustomeffects:20170323125329p:plain

まとめ

実際これはPC→MCUみたいな時の関数なので

MCUMCUなんかだとなんかしら決まりを作ってマルチバイトで送るのがベストというかあとあとbitシフトで取り出しやすいというかんじ。

ascii形式を使うのはTeratermでみれるからというのが一番の理由かな

本来ならバイナリ形式だしね

次回はCHANさんのxprintfでもやってみます。

STM32でUARTをやってみる2

はじめに

前回はすごく簡単なUARTのHelloWorldをやったので今回は受信とかやってみようと思う。

ちなみに前回の記事はコレ

gsmcustomeffects.hatenablog.com

CubeMXの設定は前回と同じ

f:id:gsmcustomeffects:20170322123624p:plain

f:id:gsmcustomeffects:20170322123737p:plain

f:id:gsmcustomeffects:20170322123804p:plain

Ac6での作業

今回やること

  • 'a'を受け取ったらボード上のLEDが点灯
  • 'b'を受け取ったらボード上のLEDが消灯
  • それ以外だとUARTでOther Key Pressedの文字を返す

前回は送信だけだったが受信は受け取り側のバッファ確保が必要となるのでそれっぽい配列を確保しとく


僕はこの辺に追加しました
f:id:gsmcustomeffects:20170323114506p:plain

UserCodeBeginとかの間にコード書いとくとCubeで再度出力したときに消えないので便利です。

んであとは無限ループ内でコードを書いていくだけ今回は受信APIを使うのでそれについて少し

HAL_UART_Receive(&huart2,(uint8_t *)rxbuf, sizeof(rxbuf), 0xF);

ほとんど送信APIと使い方は同じだが、最後のタイムアウト時間で送信の場合自発行為なのでタイムアウトすることがほとんどない。
受信の場合向こうからくるまでプログラムが止まるので注意しないといけない。
特に何も考えずにFFFFとかにするとめっちゃ止まる。

基本この辺は割り込みでレジスタ見に行くのでUARTを割り込みでさばけるならそうしたほうがいいかもしれない。

んで肝心なくそコードがこんなかんじ

f:id:gsmcustomeffects:20170323115415p:plain

実際の動作確認

Teratermだと

f:id:gsmcustomeffects:20170323115609p:plain

実際のボード

f:id:gsmcustomeffects:20170323115637j:plain

eclipseのbreak

ちゃんとaが格納されてる

f:id:gsmcustomeffects:20170323115931p:plain

STM32でUARTをやってみる1

今回は自分用メモでUARTのやり方を書いていく
環境は

  • ボード:Nucleo32 STM32F303
  • IDE:Ac6 SystemWorkbenchforSTM32

を使う

ちなみにCubeMXの使い方は結構省いてるのでほんとの初心者はこの辺読んでください

gsmcustomeffects.hatenablog.com

gsmcustomeffects.hatenablog.com

やること

  • HelloWorld的な文字をTeratermに表示する。

いたって簡単

CubeMXでの設定

まず各種機能の有効化をしていく
何とかなくだけど動かなかった時のためにLEDも設定しとく
f:id:gsmcustomeffects:20170322123624p:plain

次にクロック設定
あくまで一例なのでこだわった設定する人はデータシートとにらめっこしながら確認するのを頑張ってください

f:id:gsmcustomeffects:20170322123737p:plain

UART2の詳細設定はこんな感じだ

f:id:gsmcustomeffects:20170322123804p:plain

Oversamplesは基本RX側のやつで多めにサンプリングしてこぼしを防ぐやつ

設定が終わったらいつもの感じでエクスポート

Ac6での作業

さっそくさっき作ったプロジェクトをインポートをする。

ちなみにUART関連の出力コードはこんな感じ
構造体でいろいろ管理してるっぽい
f:id:gsmcustomeffects:20170322124102p:plain

んで今回はこの部分にコードを記述していく

f:id:gsmcustomeffects:20170322124155p:plain

以下に示すように二行を追加する。

f:id:gsmcustomeffects:20170322124234p:plain

動作確認

Teratermを起動してボーレートとかを設定する。

あとはデバッグなりしてスタートして以下のように表示されればOK
f:id:gsmcustomeffects:20170322124332p:plain

STM32のベーシックタイマー(TIM6/TIM7を使う)

Basic timer (TIM6/TIM7)

見出しの通りベーシックなタイマである。
STの中では一番チープなタイマである。(つか他のが高機能かつ複雑怪奇w

  • 16-bit オートリロードアップカウンタ
  • 16-bit プログラマブルプリスケーラ(1-65535)
  • Interrupt/DMA generation on the update event: counter overflow(カウンタのオーバーフローで割り込み又はDMAの生成)

要は単純に時間はかったりカウンタが一定値に達した時に割り込みリクエストできる機能があるというやつ。

主に思いつく使い方

  • タクトスイッチの入力を一定間隔で見に行くことで簡単なチャタリング除去
  • ADCと組み合わせて一定間隔でサンプリング値をUARTで送信とか

割り込みありきな使い方しか思いつかないが
エフェクターに使うとなるとタップテンポの感覚の計測とかかな・・・・・

使い方

さっそく使い方を見ていこう

今回はSTM32F303(Nucleo32から評価ボードが出てる)でやって行こうと思う

内容としては以下の感じ

  • TIM6/TIM7両方使って別周期で割り込み
  • 両方の割り込みハンドラ内でLEDをちかちかする。

いたって簡単だ。

CubeMXを起動する

手順

  1. Nucleo32タブで今回使うやつを選ぶ
  2. GUIピンコンフィグで設定
  3. TIM6/TIM7タイマーを有効にする

みたいな感じ

詳細設定をしていく

タイマーペリフェラルのクロックはこんな感じになっている。


次に割り込みとかの設定をしていくよ

終ったらジェネレートする。

Ac6での作業

こっからはほとんどすることない。

Mainに二行追加

stm32f3xx_it.cのハンドラ内にLチカ処理を書く

こっから先細かい解説

まあ単に動かしたい人はここは読まなくていいです。
読みたい人だけ読んで

プリスケーラについて

プリスケーラはなんというか分周器です。
これがないと速攻カウンタがオーバフローするので入ってくるクロックを遅くする役目を担っています。

今回の例を示すと

{ \displaystyle
freq[1/sec] = (Tim_{Clock}/Prescaler)/CounterPeriod
}

{ \displaystyle
freq[1/sec] = (64000000/10000)/6400
}

ここで9999は0を含めでなので10000
TimClockはSystemCoreClockから計算できるのでプリスケーラ値はSTのサンプルではこうなっています。

uwPrescalerValue = (uint32_t)((SystemCoreClock/ 2) / 10000) - 1;

というわけなんで1秒間で6400までカウントアップしてリロード値と一致するのでそこで割り込みがかかります。

主なレジスタ

CR1レジスタが基本設定項目でCR2はトリガイベントの設定

DIERは割り込み及びDMA

SRはカウンタ一致でbitが立つReadレジスタ

CNTは現在のcounter値

PSCはプリスケーラ

ARRはカウンタピリオド値

実際に動かしてブレークしてIOレジスタ見てみるとこんな感じ