Friday, August 22, 2014

SPIについてお勉強

Raspberry PI SPIによるアナログ―デジタル変換について

SPI

そもそもSPIって何ぞ? wiringPiを作った人のサイトで解説されてた。助かる(;ω;

SPI Serial Peripheral Interface

モトローラによって開発された同期型のシリアルクロック、双方向バス(マスター/スレーブ)のインターフェース。

データはクロック信号(Wire1)に同期して送信(Wire2)される。また、データを受信するワイヤ(Wire3)があり、最後にチップセレクトとして動作する4本目のワイヤ(Wire4)がある。送信/受信それぞれにワイヤとピンが用意されるからfull-duplexである。4本のワイヤを使うので4-wireバスとも言われる。

master/slave方式により、バス上に存在するデバイスではどれでも他のデバイスにデータ転送を行うことができる。チップセレクトワイヤは複数存在することができ、同じSPIバス上で複数のデバイスと接続できる。

Raspberry PIはマスターモードのみ実装されており、2つのチップセレクトピンを持っているため、2のSPIデバイスを同時に制御できる。(ただ、いくつかのデバイスは独自のサブアドレススキームを持っていることがあり、この場合はもっと多くのデバイスを設置できる。)

SPIについて覚えておかなければならないのは、バイトデータを受信するために、バイトデータを送信しなければならない点にある。

MCP3002 2channel, 10-bit analog to digital converterの例。

このチップはSPIクロックを内部ロジックを動かすために利用している。MCP3002には4bit長のコマンドのみで十分だが、帰ってくるデータ長は最後のコマンドビットの後ろから数え始めて10bitだ。従って実際に通信するときは2byteのデータを送り、2byteの結果を得ることになる。データは5bit目から始まって10bit後ろまで続いている。従ってクロックが動作している間、MCP3002との間では2byteを送り、2byteの結果を取得、この結果から10bitぶんのデータビットを取得する必要がある。


ここまで読んでrubyのpi_piperで書かれたサンプルコードの意味が分かった。

PiPiper::Spi.begin do |spi|
    raw = spi.write [0b01101000,0]
    value = ((raw[0]<<8) + raw[1]) & 0x03FF
end

spi経由でMCP3002に送っているのはコマンドビットである4bitのみ。上の例だと1001(先頭ビットは0固定)。6bit目からは返信されてくるデータビットのためにダミーバイトを11bit送っている。

データの送受信が同時に実行されているから、結果はrawに入ってくる。最初のバイトの先頭4byteは意味がないので8bit左シフトした上で不要な部分を論理積(0x3FF)で排除し。raw[0]ってやると16bit長のデータが得られるっぽいな。ruby内部でint型は16bitだからってことか。

No comments:

Post a Comment