STM32でSPI通信をやってみる1(ポーリングでマイコン同士で通信編)

今回はCubeHALライブラリを用いてSPI通信をやってみる記事です。

STM32のSPIは全二重、半二重、単方向、マルチマスターモードなどいろいろ対応してますが今回は一般的な全二重でやってみようと思います。

f:id:gsmcustomeffects:20170510195127p:plain

Pin Name description
MOSI マウターアウトスレーブイン
MISO マスターインスレーブアウト
SCK シリアルクロック
NSS スレーブセレクトピン

NSSについて

SPIのスレーブセレクトピンなのでGPIOでHIGHとLOWを切り替えて使う簡単なものだがSTM32ではマルチマスターモードもあるので注意が必要
ここの設定をきちんとしないと動かないのでしっかりと理解しておくこと

SPIx_CR1レジスタのSSMビットを用いることでNSS動作の決定ができる。

f:id:gsmcustomeffects:20170510200342p:plain

説明がこれ

f:id:gsmcustomeffects:20170510200533p:plain

SSMを1にセットした場合SSIがNSSの値となりピンからの情報は無効となる。

次にNSSの方向の設定

f:id:gsmcustomeffects:20170510200836p:plain

ごちゃごちゃ書いてありますがマスターにしたい場合はSSM = 0、SSOE = 1とする。

上記の話は1対1の通信についてだ。

マルチスレーブの場合チップセレクトはGPIOで個別ケアすることになる。

f:id:gsmcustomeffects:20170513101917p:plain

実際こういう使い方のほうが多いので今回はGPIOでチップセレクトをする

マスター側:CubeMXでの設定

  1. 全二重に設定しNSSを無効
  2. PA4をGPIOに設定

f:id:gsmcustomeffects:20170513102617p:plain

SPIの詳細設定

f:id:gsmcustomeffects:20170513103116p:plain

今回はこのような設定にした。
クロック位相や方向は適宜設定してください。
特にSPIインターフェイスのセンサーデバイスなどを扱う場合ここの部分はスレーブに合わせます。
今回はマイコン同士の通信なのでおたがいあわせれば何でもいいということです

スレーブ側:CubeMXでの設定

  1. 全二重に設定しNSSをInputに設定

f:id:gsmcustomeffects:20170513171849p:plain

詳細設定
f:id:gsmcustomeffects:20170513171923p:plain

プログラム

ソースに関してはいたって簡単だ

uint8_t aTxBuffer[] = {0xA,0xB,0xC,0xD,0xE,0xF,0,0,0,0};
uint8_t aRxBuffer[10];

のようにバッファを定義して

マスター側

HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,0);
HAL_SPI_TransmitReceive(&hspi1,(uint8_t*)aTxBuffer,(uint8_t*)aRxBuffer,10,2000);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,1);
HAL_Delay(200);

スレーブ側

HAL_SPI_TransmitReceive(&hspi1,(uint8_t*)aTxBuffer,(uint8_t*)aRxBuffer,10,100);

動作例

こんな感じでできる
ポーリングなので適宜タイミング合わせる
STのsampleではスイッチをはなすまで無限ループして待ちを構成しています。

f:id:gsmcustomeffects:20170513220321p:plain

ロジアナではこうなっている(オカダに助けてもらった

f:id:gsmcustomeffects:20170513220715p:plain