SPI(Serial Peripheral Interface)は、マイコンとその周辺IC間の高速データ転送に広く用いられる同期式全二重通信インタフェースです。この通信規格はケーブルを介した通信はほぼ行われず、基板内のIC間通信で使うことがメインです。以下で詳しく解説します。
CPUとデバイスとの間の基板間通信では今も頻出する通信です。知らないといきなり詰むこともあるくらい大切な分野ですので、ぜひ最後までお読みください!
SPI通信の基本構成
信号線
SPI通信では、以下の4種類の信号線を使って通信を実現しています。
- MOSI (Master Out Slave In):マスターからスレーブへデータを送信する信号線
- MISO (Master In Slave Out):スレーブからマスターへデータを送信する信号線
- SCLK (Serial Clock):マスターが生成するクロック信号
- CS (Chip Select) または SS (Slave Select):スレーブデバイスを選択するための信号線。Loが選択状態(ローアクティブ)
特にデバイス側では、入力するポートを「SDI」、出力するポートを「SDO」とされることがあります
本記事においてはCS(SS)については以下「SS」で統一します。
通信が常に1対1で行われるような構成でも、SS信号は必要です。
接続方式
接続方式(トポロジ)は、2種類あります。が、ほぼ標準方式しか使いません。デイジーチェーン方式は特殊なケースだと思ってください。
標準方式
SS信号以外をバス接続し、SS信号を個別に配線する方式です。
SS信号で選択したデバイスと常に1対1通信をするため、ソフトウェアの制御はシンプルで済みます。ただしデバイスの数の分だけSS信号が個別に必要になり、ハードウェアのコストは大きくなります。
デイジーチェーン方式
デバイス数に伴って通信に必要なクロックが増え、制御も難解になりますが、デバイス数が膨大なときにハードウェア的なコストを大きく下げることができる方式です。限られたケースでしか使えませんが、一応紹介だけしておきます。
スレーブに順番が発生します。最初のデバイスにMOSIからデータが送られ、以降はバケツリレーのようにデータがデバイスを移っていって最後にマスターに戻ってくるという「数珠つなぎ」になっています。全てのデバイスのデータを取得する際に、クロックあたりのデータ効率はこちらの方が良いのもメリットです。
コマンドで動作するデバイスのとき、全デバイスが同じコマンドを受け取ることしかできない等、融通は効きません
SPI通信の伝送速度
規定上の上限は特にありませんし、100Mbpsを超える通信速度を出すことも可能です。
しかし、通信速度を決めるにあたっては次の点を考慮し、1M~数十Mbps程度にするのが一般的です。
- 信号の整合性やノイズ耐性
- 配線長、基板設計の制約
いずれも、最大値を攻めるのではなく設計にかかるコストと、「本当にそんな速さが要るのか」の見極めが重要になります。また、1Mbpsも必要ない場合はI2C(配線コストがより安い)で済むかもしれないので検討してみると良いでしょう。
1対1通信のみ、IC間の距離が近い、1Mbpsも要らない、のであればUARTでもいけます
-
-
I2Cバスとは?初心者にもわかる(はずの)基礎知識と使い方
I2C(アイ・スクエア・シー)バスは、電子機器やマイコンの間で通信を行うための標準的な規格の一つです。そのシンプルな設計と効率的な通信方式から、多くのデバイスで採用されています。本記事では、初心者にも ...
SPI通信の動作モードとタイミング
4つの動作モード
SPI通信には、クロックに関する2つのパラメータがあり、これらの組み合わせで4種類の動作モードがあります。モード設定は通信開始前に行っておく必要があります。
- CPOL(クロック極性):クロックがHiのときにアイドル状態か、Loのときにアイドル状態かを決めるパラメータ。前者が1、後者が0
- CPHA(クロック位相):クロックの立ち上がりエッジで動作か、立ち下がりエッジで動作かを決めるパラメータ。前者が0、後者が1
「アイドル状態」は、通信をしていないときのことをいいます。CPOLが1だと、通信していないときはクロック信号がHiになります。アイドル状態はSS信号をアクティブ(Lo)にすることで解除されますが、そこからのクロック信号の駆動はCPOLの設定を意識していないと、デバイスがクロック信号のエッジを誤認識するので注意が必要です。
「立ち上がりエッジ」は信号がLo→Hiに変化、「立ち下がりエッジ」は信号がHi→Loに変化することをいいます。
以降、「立ち上がりエッジ」は「⇧」、「立ち下がりエッジ」は「⇩」と表現します。
SPIモード | CPOL | CPHA | アイドル状態 | データのサンプリング |
---|---|---|---|---|
0 | 0 | 0 | クロックがLo | クロック ⇧ |
1 | 0 | 1 | クロックがLo | クロック ⇩ |
2 | 1 | 0 | クロックがHi | クロック ⇧ |
3 | 1 | 1 | クロックがHi | クロック ⇩ |
「データのサンプリング」というのは、データ信号線の状態を読み取ることです。CPHAが0ならクロックの「⇧」のタイミングでデータ信号線の状態を読み取ります。マスターもスレーブも、このタイミングは一緒です。CPHAが0のとき、クロックの「⇩」でデータのシフトが行われます。(CPHAが1なら、この逆の動作です)
このとき読み取ったデータ信号の状態が、シフトレジスタに順次反映されていきます。「データのシフト」というのはこの逆で、シフトレジスタにあるデータがデータ信号線に反映され、同時にシフトレジスタの内容が文字通り「シフト」します。この動きについての詳細は後述します。
なおデータ信号は、常にHiが1でLoが0と解釈されます。
接続する全デバイスを同じSPIモードで動かすか、電気回路で整合を取る必要があります
モード毎の信号タイミング
実際にモード毎の動作の違いを理解するために、信号タイミングの例を以下で解説します。
☝️図の見かた
- 図中にある「nSS」という信号名は、SS信号のことです。このように先頭に「n」を付けるのは、Loレベルのときに意味を持つ信号1であることを意味しています。つまりSS信号はLoレベルのときに「スレーブを選択している」という意味を持っていることになります。(相手側スレーブでは、Loになったときに「自分と通信する」ことを認識します)
- データ信号のところにある「M0~M2」はマスター側、「S0~S2」はスレーブ側内のシフトレジスタの内容を指しており、番号はビット番号です。つまり「M0」はマスター側シフトレジスタの最下位ビットのことです。
- 斜線部は「Don't care」です。この期間の信号線は「何でもいい」ことになっています。読み取りを行ってはいけない期間です。
- 「Hi-Z」(ハイインピーダンスを意味します)とある期間は誰も信号線を駆動していないということになります。この期間も読み取りを行ってはいけません。
「Don't care」と「Hi-Z」は一見同じに見えますが、電気回路的には明確に区別する必要があります。詳細はここでは割愛します。
クロック信号はマスターが駆動するため、MOSIの方がMISOより変化が早いことがありますが、ここでは同一としています。
SPIモード0
SS信号がHiのとき(アイドル時)のクロック信号はLoで始まります。橙色の破線で信号線をサンプリング、青色の破線でシフトレジスタの内容をシフトし、信号線に反映します。(信号線は実際に反映されるまでに遅延があり、図では大げさに描いています)
モード0のとき、最初のクロック信号の⇧で信号線をサンプリングしなくてはいけないため、SS信号がLoになったタイミングで最初のデータを信号線にセットすることになっています(赤破線)。クロック信号の⇧があまり早すぎるとデータが間に合わないので、SS信号をアクティブ(Lo)にしてからクロック信号を出力し始めるまでは遅延が必要です。
SPIモード1
SS信号がHiのとき(アイドル時)のクロック信号はLoで始まります。橙色の破線で信号線をサンプリング、青色の破線でシフトレジスタの内容をシフトし、信号線に反映します。(信号線は実際に反映されるまでに遅延があり、図では大げさに描いています)
モード0とクロック信号の形は一緒ですが、サンプリングとシフトのタイミングが逆になっていることに注意が必要です。最初のクロック信号の⇧でデータが用意されるため、SS信号のアクティブ時はモード0のときのようにデータ信号を駆動しません。
SPIモード2
SS信号がHiのとき(アイドル時)のクロック信号はHiで始まります。橙色の破線で信号線をサンプリング、青色の破線でシフトレジスタの内容をシフトし、信号線に反映します。(信号線は実際に反映されるまでに遅延があり、図では大げさに描いています)
ちょうどモード0とクロック信号が反転している動きになります。モード0と同様、最初のサンプリングのタイミングに間に合わせるため、SS信号がアクティブになったとき(赤破線)にMOSIやMISO信号に最初のデータを用意することになっています。
SPIモード3
SS信号がHiのとき(アイドル時)のクロック信号はHiで始まります。橙色の破線で信号線をサンプリング、青色の破線でシフトレジスタの内容をシフトし、信号線に反映します。(信号線は実際に反映されるまでに遅延があり、図では大げさに描いています)
モード1とクロック信号が反転している動きになります。モード2とはタイミングが逆になっていますが、最初のクロック信号の⇩で信号への反映(シフト)が行われるため、モード1と同様、SS信号のアクティブ時点ではデータ信号は駆動されません。
データのシフト
SPI信号は送信側、受信側ともに8bitのシフトレジスタを持っています。デバイスによっては12bitや16bitのときもあり、デバイス毎に差異があると通信制御が面倒になります。以下では8bitのものについて解説します。
説明を簡単にするため、マスターとスレーブが1対1の通信を行う場合を例にしたものを見てみましょう。
SPI通信は「全二重」ですが、これは送信と受信でデータ線が独立しているという意味です。UARTのイメージでSPIを動かすと面食らうので、どんなイメージなのかをまずご覧ください。
マスターとスレーブそれぞれにあるシフトレジスタは、図のようなイメージで接続されます。マスターからシフトした最下位ビットはMOSIを通してスレーブのSDIからスレーブのシフトレジスタに取り込まれます。それと同時にスレーブの最下位ビットもシフトされてSDOを通してマスターのMISOからマスターのシフトレジスタに取り込まれます。これがSPI通信における全二重通信です。
デイジーチェーン接続のときは、あるスレーブのSDO信号が次のスレーブのSDIに接続されるので、順繰りにビットがシフトされていくのがおわかりになるかと思います。
それではSPIモード0の動作を、順を追って動きを見てみましょう。スレーブ側はコマンドを必要とするタイプではない場合を想定しています。
step.1 SS信号をアクティブにし、マスターとスレーブが持つ8bitデータをシフト
SS信号をアクティブ(Lo)にした段階で、マスターとスレーブの内部のシフトレジスタに8bitデータが用意されます。それと同時に、双方のシフトレジスタがシフトされ、MOSI信号にはM0の状態が、MISO信号にはS0の状態が反映されます。
step.2 マスターがクロック信号をHiに駆動し、マスターとスレーブが信号線を読み取る
このときが「サンプリング」タイミングで、マスターもスレーブも、入力信号線の状態を読み取り、それぞれのレジスタの最上位に取り込みます。
step.3 マスターがクロック信号をLoに駆動し、内部レジスタをシフトさせる
ここでレジスタがまたシフトされ、そのときの最下位ビットが信号線に反映されます。
step.4 8bit分、STEP2とSTEP3を繰り返す
以降は8bit分のクロック信号をマスターが発生させると、一連のデータ通信を終えます。終わったときのそれぞれのシフトレジスタは図のようになります。
この時点で、マスター内にあった8bitとスレーブ内にあった8bitがすっかり入れ替わった格好になっていることに注意してください。
step.5 マスターがSS信号を非アクティブ(Hi)にして通信完了
マスターがSS信号をHiにしたとき、それぞれの内部の8bitレジスタの中身が、データとして確定します。
注意が必要なのは、スレーブ側がコマンドを扱うタイプだったとき、マスターからの8bitデータを受け取って初めて「やるべき事」を知ります。なので、マスター側は、もう8bit分のクロック駆動を行わないと、本来欲しかったデータが得られないということです。この8bit分のズレを正しく制御するのが大切です。
デバイスには、特に命令や指示を必要とせず、いわゆる「データの垂れ流し」をするタイプもあります。センサーやADC(A-D Converter)などがそれにあたります。この場合は最初の8bit通信で受け取ったデータに既に意味を持っているので、無駄な通信をしなくても済みます。
デバイスによってデータをどう出力するかが違うので、データシートをよく読みましょう
基板設計とノイズ対策
SPI通信は高速での信号駆動をするため、その安定化を図るためにいくつかの一般的な対策があります。
この内容はやや高度ですので、電気回路の基礎を理解している前提になっています
プルアップ抵抗
いずれの信号線も10kΩ程度のプルアップ抵抗を設けます。これはノイズ対策というよりは信号線の安定化を目指す設計です。
SPI通信の信号線はプッシュプルで駆動されることが多いですが、起動時のような不安定な場合に信号線の状態を固定することで安定化させたり、駆動を速やかに行うことが目的です。
ダンピング抵抗
高速に駆動される信号では、LoからHiにしたときやその逆のときに、リンギングと呼ばれる現象が発生することがあります。それを低減するため、数十Ω程度の抵抗を信号線に直列に接続します。この抵抗値は計算で求まり、このように信号線の抵抗値を調整することを「インピーダンスマッチング」といいます。
基板の配線設計
MOSI、MISO、SCLK信号は同期を取るためにそれぞれの配線長を等しくする必要があります。信号線の長さが違うと信号間でズレが生じることがあります。ただし、比較的遅い速度のときはあまり厳密に考える必要はありません。
また、信号線の配線はなるべく直線的になるように配慮する必要があります。
グラウンドプレーンの利用
多層基板の場合、全ての信号線の直下にはグラウンドプレーンを広げておく必要があります。これも信号線の安定性の向上やノイズの抑制につながります。
まとめ
本記事では、SPI通信の基本構成から伝送速度、動作モード(CPOL/CPHAによる4種のモード定義)まで、そして実際の基板設計時の注意点(ノイズ対策、配線パターン、グランドプレーン設計など)を詳しく解説しました。
SPI通信は、高速かつ全二重通信が可能なため、ディスプレイ制御、フラッシュメモリへのアクセス、センサーデータの高速収集など、データ量が多くリアルタイム性が要求されるアプリケーションに最適です。一方、I²Cは配線数の少なさと多くのデバイスを同一バス上で管理できる点、UARTは非同期通信により柔軟なボーレート設定が可能な点が評価されています。設計者は、各通信規格の特性とシステム全体の要求に応じて最適な通信方式を選定する必要があることに注意してください。
- 正しくは信号名の上に線を付記するのですが、そのような文字装飾ができない場合に「n」を付けることで区別しています。 ↩︎