STM32をレジスタで制御する①~Lチカ~

はい、前回の予告(?)にあったように、STM32をレジスタで制御したい!っていう記事の第一回です。
とはいえまだまだ分からないことが多いし、今回は簡単なGPIOの制御です。
ちなみに私がレジスタ制御を勉強している理由としては、

  • なんとなく

  • HALでコード書くの飽きた

  • LLってある程度レジスタ絡んでくるし、HALより情報が少ない(気がする)

  • なんとなく

とまあこんな感じです。
真ん中二つは実質建前(?)で「なんとなく」がきっかけです。

コーディングの準備

私はcubeIDEを使用、こちらのサイトを参考(ほぼそのまま)にしました。
レジスタ制御をしたい方はこちらのサイトにあるように環境を整えるといい感じにできます。
また、レジスタの操作を間違えると二度と書き込みができないマイコンが完成するらしいので、cubeProgrammerも用意しました。

また、レジスタ制御するために使用するマイコン(今回私はSTM32F334K8T6を使用)のデータシート、リファレンスマニュアルもSTのページから入手しました。
※よく使われるSTM32F303K8T6とピン配置、プログラムともに互換性があると思います、しらんけど
そして、最低限の周辺回路を実装した簡易ボードを使用しました。

さあ、Lチカをしよう!

長い前置きは終わりにして、さっそくコードを書きましょう。
まずはcubeMXが生成したコードを全削除します、ちょっと悲しいけど。
これがこれからレジスタ制御をするときのmain.cの最小構成になります。

今回使用するマイコンはSTM32F334K8T6なので、stm32f3xx.hをインクルードしています(使用するマイコンに応じて書き換える)。
さて、リファレンスマニュアルを見ながらコーディングしていきましょう。

GPIOの初期化

今回はPB1を使用してLチカをします。
STM32マイコンは初期状態では省電力モードになっており、各GPIOのポートにはクロックが供給されていません。
そのため、まずはポートにクロックを供給してあげる必要があります。

RCC_AHBENRレジスタの18ビット目を1にすることでPORTBにクロックが供給されます。
レジスタには下のようにアロー演算子でアクセスし、ビット演算を用いて特定のビットを0、1、反転といった操作をしていきます。
右辺のかっこは必要ありませんが、私はこっちのほうが見やすく感じるので、レジスタの勉強の間はかっこを多用しています。

RCC -> AHBENR |= (1 << 18);

さて、クロックを供給できたので次は入出力の設定をしましょう。

PB1を出力モードにするには、2ビット目を1に、3ビット目を0にセットするとよさそうですね。
こんな感じで書いてみました。

GPIOB -> MODER |= (1 << 2);
GPIOB -> MODER &= (~(1 << 3));

これで初期化は終わりかと思ったのですが、どうやらSTM32のアウトプットは出力スピードを設定できるそうなので、これもやっておきましょう(しなくてもいいのかな、未検証です)。

よくわかんないのでLow speedにしておきましょう(適当)。
じゃあ初期値のままでいいのか、まあせっかくだしコードにしておきましょう。
使わないピンもあるけど、そのまま0を入れて全ピンLow speedにセットしました。

GPIOB -> OSPEEDR = 0;

これで初期化は完了です。
結構めんどくさい…、ほかのマイコンってどうなんでしょうか。

GPIO出力

あとは出力するだけです。
もうちょっと頑張りましょう!

このレジスタの出力したいビットを1にするとHIGH、0にするとLOWにできるようです。
また、delayやHAL_Delay関数なんて便利なものはまだないので、for文で適当に待機させましょう。

おめでとうございます、これでレジスタ制御でのLチカのプログラムは完了です!
下の動画が書き込んで動作させた様子になります(動画貼れない?っぽいので𝕏の投稿で勘弁してください)。
for文で適当にdelayさせたのでまあ、雑ですね。

まとめ

レジスタ制御シリーズ(になる予定)の第一弾、Lチカが無事できてほっとしました。
GPIOの出力はさすがに簡単でしたね。
次はGPIOの入力をやってみようかな、さすがにまだUARTはわからないです。
ちょっと先人たちが投稿している記事より分かりにくいし、長くなりましたが、まあ進捗報告ってことで許してください。
質問、誤った情報がある場合は教えていただけると嬉しいです。
それでは、ありがとうございました、おやすみなさい。

この記事が気に入ったらサポートをしてみませんか?