SPI

SPIはコンピューター同士でデータをやり取りする通信方式です。

よく使われるUARTと違う点は

  • クロックと信号線というのが別にあるため、安定した高速通信ができる
  • SPIでは送受信ではなくデータを”交換”する通信。1バイト送信したら相手から1バイト必ず受信する。
  • 通信には親子関係があり、子は自分から送信できない。親の好きなタイミングで通信が始まる。

通信には親子関係があり、コンピューターとの通信よりもセンサーとの通信によく使われます。マイコンからSPIを使いセンサーに何をしてほしいかを伝えて、代わりにデータを受け取るといった形です。親は自分の好きなタイミング通信できるためプログラムも簡単で、しかもかなり高速な通信ができるのも魅力です。

通信する相手とは3つの線でつなぎます(obnizではこの方法のみです)。親がデータをやり取りするタイミングを送るためのCLK。そして親から子へデータを送るためのMOSI(Master Out Slave In という意味です)。逆に親がデータを受け取るためのMISOです。子からデータを受け取る必要がない場合はMISOを繋がないこともあります。

初期設定

使えるSPIはデバイスによります。例えばobniz Boardには2つあり、spi0とspi1です。ioとspiは別のもので、spiのclkやmosiなどそれぞれを、12あるioのうちどれかで使えるようにして利用します。

obniz.getFreeSpi()で使用されていないspiを取得できます。spi.start()でspiを設定します。利用するioと周波数を設定します。例えば、io0をmosiに、io1をmisoに、io2をclkとし、周波数を100kHzとする場合は以下のようになります。

var spi = obniz.getFreeSpi();
spi.start({mode:"master", mosi:0, miso:1, clk :2, frequency:100000}); 

もし確実に使っていないspiがわかっている場合は、obniz.getFreeSpi()を使わず直接使うことも可能です。

obniz.spi0.start({mode:"master", mosi:0, miso:1, clk :2, frequency:100000}); 

modeはobnizをmaster(親)にして自分からデータを送れるようにすると設定します。現在masterモードにのみ対応しています。
frequencyは通信周波数となります。clkでmasterから送り出される周波数です。相手と通信できる速度を選択します。また、利用できる周波数はデバイスとioの駆動方法によります。多くの場合、push-pull3vであれば、2Mhzなど、より高速な通信が可能です。

mosi,miso,clkそれぞれのioの駆動方法プルアップダウンはこのように変更できます。また、mosi,miso,clkは最低どれか1つを指定する必要がありますが、全てを利用する必要はありません(mosiとclkのみでmisoを利用しないという設定が可能です。)

var spi = obniz.getFreeSpi();
spi.start({mode:"master", mosi:0, miso:1, clk :2, frequency:100000, drive:"3v", pull:null}); 

driveで駆動方法を、pullでプルアップダウンを変更できます。指定できるものはそれぞれio.drive()io.pull()で指定できるものと同じです。

設定が完了したら通信が可能となります。

終了

開始したspiはspi.end()で終了します。

var spi = obniz.getFreeSpi();
spi.start({mode:"master", clk :0, mosi:1, miso:2, clock:1000000});
spi.write([0x12, 0x98]);
spi.end();

Articles