STM32でI2C Readしてみる
今回は、NucleoボードでHALを使ってI2CのReadを試してみる。手持ちの部品でI2Cに対応しているのが三軸ジャイロスコープ+三軸加速度センサーMPU6050が載ったモジュールGY-521しかないので、今回はこのモジュールI2CのReadを試してみる。
なおGY-521は以下のキットを買ったときについてきたもの。ベンダーのSunFounderのWebサイトに各種センサーの使い方の解説もあるのだが、5Vを入れるべきところに3.3Vを突っ込んでいたり、回路図接続に怪しい部分があるのであまりあてにならない。
ということで、GY-521の回路図とMPU6050のレジスタマップを読みながらI2Cアクセスを試してみる。GY-521の回路図とデータシートはaitendoのページにあったので、こちらを参考にさせて頂いた↓
https://www.aitendo.com/product/9549
MPU6050のレジスタマップは以下のTDKのページに置いてあったのでこちらを参照する↓
https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf
加速度センサーなのでセンサー値を読みとりたいところだが、今回はあくまでI2C Readの実験ということで、MPU6050のWho am Iレジスタ(0x75)をReadしてMPU6050のデバイスIDのデフォルト値0x68が読めるか確認してみる。
ちなみに私は以下の本を読みながら遊んでいる。STM32CubeIDEの細かい設定方法は書かないので、詳しくは以下の本を読んでください(丸投げ)。
開発環境
Windows 10
STM Nucleo-F401RE
Amazon Corretto 8
STM32CubeIDE (Version: 1.13.0)
I2Cの設定
Projectは「STM32 Project」からBoard SelectorでNucleo-F401REを選択して作成する。作成したら、iocファイルのPinout&ConfigurationでI2C1のModeをI2Cに設定する。I2Cのピンアサインはデフォルトのままでも良いのだが、ボード上にSCL/SDAと表示があってわかりやすいPB8/PB9に変更した。
ちなみにI2Cはプルアップが必要でSTM-32側で内部プルアップを設定することができるが、GY-521側で4.7kΩでプルアップされているので、今回はSTM-32側の内部プルアップは無しにする。完了したらGenarate Codeをする。
NucleoとGY-521の接続
Nucleo上に5V、GND、SCL/D15、SDA/D14と表示があるコネクタにジャンパー線をさしてGY-521と接続する。
GY-521上にもピンの表示があるので、以下のように接続する。
- Nucleoの5V – GY-521のVCC
- NucleoのGND – GY-521のGND
- NucleoのSCL/D15 – GY-521のSCL
- NucleoのSDA/D15 – GY-521のSDA
実際に接続したのが以下の図。NucleoからGY-521に5Vが供給されると緑色のLEDが光る。ちなみに、
STM Nucleo-F401REの回路図は以下を参照。
https://www.st.com/ja/evaluation-tools/nucleo-f401re.html#cad-resources
main.cの変更点
今回はHAL_I2C_Mem_Readを使ってサクッと実装する。今回はなるべくコード量を少なくやりたかったので、以下のようにデフォルトで生成されたmain.cにretの定義とHAL_I2C_Mem_Readの2行だけ追加。
/* USER CODE BEGIN 2 */ uint8_t ret = 0; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_I2C_Mem_Read(&hi2c1, 0x68<<1, 0x75, 1, &ret, 1, 1000); } /* USER CODE END 3 */
HAL_I2C_Mem_Readの詳細はググッて欲しいが、MPU6050のデバイスアドレス0x68(1bitシフトさせる必要があるので注意)、Who am Iレジスタのアドレス0x75、retのポインタを指定して、retにReadした値が入るようになっている。
プロジェクトをBuildしてdebugを実行し、HAL_I2C_Mem_Readの部分にブレークポイントを設定してretの中身を見てみる。すると、実行後のValueが0x68になっており、Who am Iレジスタ0x75をReadした値が読めていることがわかる。
ちなみに、何度かデバッグを実行しているとMPU6050が変な状態でハマることがあるようで、I2C Read値が読めなくなることがあった。その場合は、一度NucleoからUSBケーブルを抜き差しすることで復帰できた。