はじめに
前回はUARTについて、通信の仕組みやTX/RX、ボーレートなどについてまとめました。
今回はその続きとして、SPIについて整理してみます。
SPIについては、
- 同期式通信
- UARTより高速
- クロックがある
くらいの理解はしていたのですが、
実際にどのようなタイミングでデータを送っているのかなどはわかってませんでした。
現在携わっているPJでもSPIは登場するので、ちゃんと理解してみようと思います。
SPIとは?
SPIは「Serial Peripheral Interface」の略で、マイコンと外部デバイスを接続するためによく使われるシリアル通信です。
例えば、
- センサー
- Flashメモリ
- ADC
- DAC
- ディスプレイ
などとの通信に使用されます。
SPIの大きな特徴は、
クロック信号を使う同期式通信
であることです。
UARTはクロックを使用しない非同期通信でした。
一方SPIでは、Master側がクロックを生成し、そのタイミングに合わせてMasterとSlaveがデータを送受信します。
SPIで使用する信号
SPIでは主に以下の4つの信号を使用します。
- SCLK
- MOSI
- MISO
- CS
それぞれの役割は以下の通りです。
| 信号 | 役割 |
|---|---|
| SCLK | 通信のタイミングを合わせるクロック |
| MOSI | MasterからSlaveへデータを送る |
| MISO | SlaveからMasterへデータを送る |
| CS | 通信するSlaveを選択する |
SCLK
SCLKは通信のタイミングを決めるクロック信号です。
基本的にはMaster側が生成します。
MasterとSlaveはこのクロックを基準にして、
いつデータを読み取るか
を判断します。
MOSI
MOSIは Master Out Slave In の略です。
その名前の通り、
Master → Slave
へデータを送るための信号です。
例えばMasterがセンサーにコマンドを送る場合、MOSIを使用します。
MISO
MISOは Master In Slave Out の略です。
こちらは逆方向で、
Slave → Master
へデータを送ります。
例えばセンサーの測定結果をMasterが受け取る場合などに使用されます。
CS
CSは Chip Select の略です。
複数のSlaveが接続されている場合に、
今回通信するデバイス
を選択するために使用します。
一般的にはCSがLowになったデバイスが選択されます。
SPIは全二重通信
SPIの特徴の一つが、
送信と受信を同時に行える
ことです。
MOSIとMISOが別々の信号線になっているため、
- Master → Slave
- Slave → Master
の通信を同時に行えます。
例えばMasterが8bit送信する間、Slaveからも8bit受信します。
そのためSPIでは、
データを送信しているだけのつもりでも、同時にデータを受信している
ということになります。
SPI通信の流れ
SPI通信は、基本的に以下のような流れで行われます。
- CSをLowにしてSlaveを選択する
- SCLKを動かす
- MOSIとMISOでデータを送受信する
- 必要な通信が終わったらCSをHighにする
CSをLowにしている間だけ通信が有効になるデバイスも多いため、CSは単純なデバイス選択だけではなく、
通信の開始・終了
にも関係しています。
複数のデバイスを接続する場合
SPIでは複数のSlaveを接続できます。
この場合、
- SCLK
- MOSI
- MISO
は複数のSlaveで共有できます。
一方で、CSは基本的にデバイスごとに用意します。
例えばSlave Aと通信する場合は、
CS_AだけをLowにする
ことでSlave Aを選択します。
Slave B、CはCSがHighのまま待機します。
この仕組みにより、同じSPIバスに複数のデバイスを接続できます。
ただし、デバイスが増えるほどCS用のGPIOも必要になるというデメリットがあります。
SPI Modeとは?
SPI通信では、
クロックのどのタイミングでデータを読み取るか
をMasterとSlaveで合わせる必要があります。
ここで使用されるのが、
- CPOL
- CPHA
です。
CPOL
CPOLはクロックのアイドル状態を決めます。
- CPOL = 0:通信していないときLow
- CPOL = 1:通信していないときHigh
CPHA
CPHAはデータを読み取るタイミングを決めます。
CPOLとCPHAの組み合わせで、SPI Modeが決まります。
| SPI Mode | CPOL | CPHA |
|---|---|---|
| Mode 0 | 0 | 0 |
| Mode 1 | 0 | 1 |
| Mode 2 | 1 | 0 |
| Mode 3 | 1 | 1 |
MasterとSlaveでSPI Modeが違うと、データを読み取るタイミングがズレてしまいます。
その結果、
送った値と違う値を受信する
といった問題が発生する可能性があります。
SPI通信がうまくいかない場合は、まずSPI Modeを確認することが重要です。
SPIのメリット・デメリット
メリット
SPIには以下のようなメリットがあります。
- 比較的高速な通信が可能
- 送信と受信を同時に行える
- クロックがあるため通信タイミングを合わせやすい
- Flashメモリやディスプレイなど高速な通信が必要なデバイスに向いている
デメリット
一方で、
- UARTやI2Cと比較すると配線が多い
- デバイスが増えるとCSも増える
- SPI Modeなどの設定を合わせる必要がある
といった特徴もあります。
UART・I2C・SPIの違い
ざっくり比較すると以下のようになります。
| UART | I2C | SPI | |
|---|---|---|---|
| 通信方式 | 非同期 | 同期 | 同期 |
| クロック | なし | あり | あり |
| 主な信号 | TX / RX | SDA / SCL | SCLK / MOSI / MISO / CS |
| 同時送受信 | 可能 | 基本的には半二重 | 全二重 |
| 複数デバイス | 基本的には1対1 | 得意 | 可能 |
| 通信速度 | 比較的低速 | 中程度 | 比較的高速 |
| 配線 | 少ない | 少ない | 多め |
それぞれ得意な用途が異なります。
- UART:デバッグやPCとの通信
- I2C:センサーなど複数デバイスとの通信
- SPI:Flashやディスプレイなど高速な通信
といった使い分けが多いと思います。
まとめ
今回SPIについて調べてみて、
特に重要だと感じたのは以下の4点です。
- SCLK:通信のタイミングを決める
- MOSI:Master → Slave
- MISO:Slave → Master
- CS:通信するSlaveを選択する
SPI通信で問題が発生した場合も、
- CSは正しく制御されているか
- SPI Modeは一致しているか
- クロック周波数は適切か
- MOSI/MISOは正しく接続されているか
といった形で確認できます。
アプリケーション側から見ると、SPI通信はAPIやドライバ経由で簡単に扱えることが多いですが、
その下では実際にSCLK、MOSI、MISO、CSといった信号が動いている
ことを理解しておくと、通信トラブルが発生したときの切り分けにも役立つと思います。
次は実際にArduinoやESP32などを使ってSPI通信を動かしてみると、さらに理解が深まりそうです。



