こんにちは。

Yukiです。今回はNucleo F303K8でLチカをしてみたいと思います。

今回はHALを使用しないで、レジスタ操作だけでやってみたいと思います。

HALを使用したLチカは、前回やったので、ぜひご覧ください。

 

 

 

 

  レジスタ操作の手順

 

STM32のレジスタ操作は、そこそこ癖が強いと個人的には思います。

(STM32CubeIDEなのかレジスタ定義ファイルの癖が強いのかは分かりませんが)

 

全てのレジスタは、構造体により構成されているらしく、アロー演算子を用いてGPIOx->MODERのように指定します。うーん。分かりにくい。

 

またPICのようにPORTAbits.PORTA1みたいに指定できないみたいなので、

(これはPICが異常な気もしますが)

 

ビットをセットする場合には

GPIOB->ODR |= (1 << 7)

のように記述する必要があります。この例だと、7ビット目をセットするという意味になります。

 

逆にビットをリセットするには

GPIOB->ODR &= (~(1 << 7))

とします。この例だと7ビット目をリセットするという意味になります。

 

反転させる場合には

GPIOB->ODR ^= (1 << 7)

のように書くことで7ビット目を反転させることが出来ます。

 

 

正直わかりにくいですね。この辺は、後日独自に関数化しようと思います。

(今現在ではArduinoのように出来たら良いなと思っています)

 

 

 

  Lチカのレジスタ操作

 

STM32マイコンは、それぞれの周辺機能にクロックを提供しないと、その周辺機能は使えないというトラップがあります。これ自体は、消費電力とかの関係で、まあアリだとは思うのですが、ポート関連にもいる?

 

まあ個人的な感想はこれくらいにしておいて、とにかくポート機能にクロックを提供してあげます。

これらの機能はペリフェラルクロック有効レジスタで設定できます。

今回は、PB3を使うので、RCC->AHBENRの18ビット目をセットしてあげます。

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

 

 

次に、PB3を出力にしてあげます。

入出力設定は、ポートモードレジスタで設定しますが、

00:入力モード

01:汎用出力モード

10:オルタネート機能モード

11:アナログモード

 

と設定しなければいけません。(めんどくさい)

ということで、設定してあげます。

ポートモードレジスタはGPIOB->MODERで設定できます。

PB3は7・6ビットに割り当てられているので、

GPIOB->MODER &= (~(1 << 7));

GPIOB->MODER |= (1 << 6);

 

ここまで来ると、ようやくLチカ出来るようになります。

ポートのHIGH/LOWはポート出力データレジスタで行います。

ポート出力データレジスタはGPIOB->ODRで、今回はPB3なので

HIGHにする場合は

GPIOB->ODR |= (1 << 3)

 

LOWにする場合は

GPIOB -> ODR &= (~(1 << 3))

 

ビット操作嫌いになりそう。

 

 

  ソースコード

 

あんまりきれいなソースコードじゃないので、参考程度にどうぞ

(自分のプログラムってカッコが多過ぎるらしいです)

 

なお、ソースコードは core\src\main.cに記述します。

それ以外のファイルは削除して良いらしいですが、削除したら、Warningが出るようになったので、やめました。

 

 

 

/*

 * main.c

 *

 *  Created on: 2023/06/05

 *  Project :Ltika2

 */

#include "stm32f3xx.h"

 

int main(void) {

              //ポートB有効

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

 

              //PB3 出力

              GPIOB->MODER |= (1 << 6);

              GPIOB->MODER &= (~(1 << 7));

 

              GPIOB->OSPEEDR = 0; //全てロースピード

 

              while (1) {

                            GPIOB->ODR |= (1 << 3); //PB3 ON

                            for (volatile int i = 0; i <= 100000; i++) {

 

                            }

                            GPIOB->ODR &= (~(1 << 3)); //PB3 OFF

                            for (volatile int i = 0; i <= 100000; i++) {

 

                            }

              }

}

 

 

 

 

 

  参考にした記事

 

正直私のやつの500倍くらい分かりやすくまとめてあります。

すごいです。ありがとうございます。

 

 

  余談

 

STM32のリファレンスマニュアル見にくいです。

リセット値も何故か16進数で上の方に書いてあるし、うーん。なにこれ。

 

リファレンスマニュアルに書いてあるレジスタ名を打ち込んでも通らないのってどうなのですかね。(RCC_AHBENRでは通らない。RCC->AHBENRで通る)

 

 

まあリファレンスマニュアルなので、しょうがないのかもしれませんが、せめて周辺機能の初期化については書いてあってほしかったというのが、私の願いですかね。

 

ペリフェラルクロックとか、ある事知らなくて、少し躓きました…。