STM32 SPIで通信する Mbed編

STM32 SPIで通信する Mbed編

今回はMbedを使ってSPIによる通信を行ってみます。

HALを使ったSPIの記事を こちら に書きましたが今回はMbedを使います。

投稿時の開発環境を記しておきます。

PC:Windows10 OS
IDE: STM32CubeIDE Version1.3.0
Board: STM32Nucleo-F401RE

SPI通信の概要

SPIはシリアル・ペリフェラル・インターフェースの略です。
I2Cと同じようにマイコンと周辺デバイスを(一般的には)プリント基板上で通信するための手段です。

I2Cではデータバスが1本で送信と受信が兼用になっていますが、SPIは別々です。
別ということは全2重通信が可能なので、その分通信速度は速いことになります。

・モトローラが開発した通信方式
・SCK, MISO, MOSI, SSの4本の通信ラインを使って双方向で通信が可能
・通信速度はI2Cに比べて高速
・マスタとスレーブが存在する

SPIについては こちら を見て頂ければと思います。

スレーブとなるターゲット

STM32(をマスタ)で制御し、スレーブのデバイスは以下のものを使ってみました。

気圧センサーモジュール

価格は600円でネットを使って購入しました。

メーカーはSTマイクロです。デバイスのデータシートは こちら です。

接続

下表のとおりに接続します。

このモジュールは I2C か SPI のどちらで接続するのか選択することができます。
今回はSPIで接続するので5番ピンをチップセレクトの信号とつなぎます。
割り込みは使わないのでINT端子は接続していません。

なおSPIで通信する場合、裏面のJ1, J2の半田ジャンパーはオープンにする必要があります。

使用するプロジェクト

Mbedを使うためには以下の記事の手順でプロジェクトを構築する必要があります。

STM32CubeIDEでMbedを動かしてみる その1
STM32CubeIDEでMbedを動かしてみる その2
STM32CubeIDEでMbedする Ticker編

コーディングしてみる

MbedによるSPIの使い方は こちら のサイトを参考にしました。

タイマーが初期化されている必要があるので maini()関数の中の SystemClock_Config()より後にコードを書きます。

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN 2 */
#define WHO_AM_I 0x0f
#define CTRL_REG1 0x20
#define WAKE_UP 0x90
#define P_ADRS 0x28

  int err, l, m, h;
  char buf[16];
  uint32_t press;

  SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK);

  spi.format(8, 0);

  spi.frequency(1000000);

  DigitalOut cs(PA_4);

  buf[0] = WHO_AM_I | 0x80;	// Who am I ?

  cs = 0;

  int ret;
  spi.write(buf[0]);
  ret = spi.write(0x00);

  cs = 1;

  if (0xbd == ret)
  {
    err = 0;
  }
  else
  {
    err = 1;
  }

  buf[0] = CTRL_REG1;	// Control Register1
  buf[1] = WAKE_UP;

  cs = 0;
  spi.write(buf[0]);
  spi.write(buf[1]);
  cs = 1;

  HAL_Delay(3000);

  buf[0] = P_ADRS | 0xc0;

  cs = 0;
  spi.write(buf[0]);
  l = spi.write(0);
  m = spi.write(0);
  h = spi.write(0);
  cs = 1;

  press = h << 16 | m << 8 | l;
  press /= 4096;

  /* USER CODE END 2 */

コードの解説

HALを使ったSPIの記事でも書いた通り、気圧センサーの仕様はモード3になっていますがモード0でないと正しく動作しませんでした。

Mbedを使うとコンストラクタ内で初期設定を行ってくれるので手間がかからず楽チンです。

チップセレクトには DigitalOutクラスで GPIO(PA4) を定義しています。

WHO_AM_I というレジスタの値を読んで、 0xbd であればデバイスを認識できているとのことです。
コントロールレジスタ1に WAKE_UP(0x90) を書いてパワーダウンモードを解除します。

気圧の計測値は 0x28 (P_ADRS), 0x29, 0x2a のレジスタから読み込みます。

P_ADRS | 0xc0 とすることでアドレスをオートインクリメントして次々と読むことができます。

ただしmbedのSPIでは連続してリードする関数がなかったのでwrite()関数を繰り返して読みました。

読んだ値を 4096 で割ることで単位 [hPa]の気圧を得ることができます。

気圧は 1013[hPa]でした。

Mbedカテゴリの最新記事