今回はCubeHALライブラリを用いてSPI通信をやってみる記事です。
STM32のSPIは全二重、半二重、単方向、マルチマスターモードなどいろいろ対応してますが今回は一般的な全二重でやってみようと思います。
Pin Name | description |
---|---|
MOSI | マウターアウトスレーブイン |
MISO | マスターインスレーブアウト |
SCK | シリアルクロック |
NSS | スレーブセレクトピン |
NSSについて
SPIのスレーブセレクトピンなのでGPIOでHIGHとLOWを切り替えて使う簡単なものだがSTM32ではマルチマスターモードもあるので注意が必要
ここの設定をきちんとしないと動かないのでしっかりと理解しておくこと
SPIx_CR1レジスタのSSMビットを用いることでNSS動作の決定ができる。
説明がこれ
SSMを1にセットした場合SSIがNSSの値となりピンからの情報は無効となる。
次にNSSの方向の設定
ごちゃごちゃ書いてありますがマスターにしたい場合はSSM = 0、SSOE = 1とする。
上記の話は1対1の通信についてだ。
マルチスレーブの場合チップセレクトはGPIOで個別ケアすることになる。
実際こういう使い方のほうが多いので今回はGPIOでチップセレクトをする
マスター側:CubeMXでの設定
- 全二重に設定しNSSを無効
- PA4をGPIOに設定
SPIの詳細設定
今回はこのような設定にした。
クロック位相や方向は適宜設定してください。
特にSPIインターフェイスのセンサーデバイスなどを扱う場合ここの部分はスレーブに合わせます。
今回はマイコン同士の通信なのでおたがいあわせれば何でもいいということです
スレーブ側:CubeMXでの設定
- 全二重に設定しNSSをInputに設定
詳細設定
プログラム
ソースに関してはいたって簡単だ
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ではスイッチをはなすまで無限ループして待ちを構成しています。
ロジアナではこうなっている(オカダに助けてもらった