がれすたさんのDIY日記

電子回路、Python、組み込みシステム開発、自作エフェクターを語るblog

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レジスタ見てみるとこんな感じ


KiCad : 分割シンボルの作り方

導入

近年200ピン以上の高機能なSoC、FPGAが主流となってきており、ハードウエア開発のレベルも高度化しています。
そのようなをICを使用した開発では、回路図が肥大化するため工夫を凝らして回路図の可読性を上げたりする必要が出てきます。
そこで多くの電子回路CADでは、分割シンボルが備えられており機能ごとの回路を書けるようになっています。

フリーで使えるKiCadでも分割シンボル機能があり今回はそのシンボルの作成方法を紹介します。*1

f:id:gsmcustomeffects:20211117040912p:plain
分割シンボルを使った回路例

分割シンボルの作成方法

通常通りシンボル作成画面を開きます。
f:id:gsmcustomeffects:20211117043146p:plain
今回はNXPのMIMXRT1166DVM6AというSoCを例として作成します。
ポイントは箇条書きで示しました。

  • パッケージのユニット数は2(後から変更可能)
  • ユニットは交換不可にチェック*2

最後にOKをクリックしてウィザードを閉じます。
このあとは通常のシンボル作成と同じように作業する形になります。
ユニットの切り替えは上部プルダウンから行うことが可能です。
f:id:gsmcustomeffects:20211117045929p:plain
f:id:gsmcustomeffects:20211117053432p:plain

Tipsなど

途中でシンボルのユニット数を増やしたい場合

ユニット数の変更はプロパティで行うことができます。*3
ユニットを減らす場合は、末尾のユニットから削除されるので注意が必要です。(例:ABCDのうちCを消したい場合はコピー機能で移動してから行う)
f:id:gsmcustomeffects:20211117050901p:plain

ピンテーブルの活用

200ピンを超えてくるとシンボル作成にもミスが出てきます。
ピンテーブル機能で一覧を確認できますのでしっかりとチェックするようにして下さい。
その他DRCで重複ピンの洗い出しもできますので利用するようにしてください。
f:id:gsmcustomeffects:20211117051237p:plain

複製機能の活用

回路図を書き始めて大幅にシンボル構造を変えたいなというときは複製機能でバックアップを取ることをお勧めします。
f:id:gsmcustomeffects:20211117052518p:plain

まとめ

今回はKiCadの分割シンボルを作成する方法を紹介しました。
まずはメーカー公式評価ボードと同じように作成して回路図を書きながらまとまりがいいようにピン感覚矩形の大きさ等を編集していくのがいいと思います。

あと過剰なシンボル分割は可読性を下げるのでほどほどにするのがいいです。
個人的にはA4サイズにこだわらずA3回路で書いた方がいいパターンもあるので頭の片隅に置いておくとよいしれません。

*1:分割シンボルの作成は、通常部品作成手順と重複する部分もありますのでまずは通常のシンボル作成方法を理解した上で行ってください。

*2:この際入れ忘れるとアノテーションを行った際に回路シンボルが勝手に置き換わってしまうので注意してください

*3:上のオペアンプと歯車アイコンで開けます。