トップページ | 組込みソフト | Raspberry SPI 制御コード |
Raspberry SPI 制御コード 2014/6/8 | |||||||||||||||
Raspberry PiでSPIインターフェースを使うためのコードを公開します。SPIで何ができるか? インターフェースがGND, MISO(SDO), MOSI(SDI), CE(CS), SPC(CLK)の5本の線で繋げばいいのでI2Cより2本多いです。 I2Cと同様にセンサーや、LCD、メモリなどがありいろいろ遊べます。 I2Cの通信速度は最大5Mb/です。しかし、SPIは未定義ですが、Raspberry PiにカラーグラフィックLCDを接続したときは18MHzで動作しました。未定義ということは、遅いのも速いのもありということです。 Raspberry Piで使えるSPIデバイスは2つまでです。 このコードのウリは、 SPIの使い方がわかりやすくなっています |
|||||||||||||||
Raspberry Piでの設定 | |||||||||||||||
SPIモジュール(spi-bcm2708)を「ブラックリスト」からを外しておくことが必要です。(SPIモジュールは前科者なのか?) sudo vi /etc/modprobe.d/raspi-blacklist.conf 変更前 spi-bcm2708 変更後 #spi-bcm2708 #をつけてコメントにします。 sudo vi /etc/modules spidev を最後の行に付け加えます。 リブートします。 sudo reboot これでSPIが動きます。 |
|||||||||||||||
ダウンロード | |||||||||||||||
ソースフィルはエクリプスでコンパイルして動作確認しています。 SPI.cpp SPI.h spi_app.cpp(サンプルプログラム) |
|||||||||||||||
使ってみたI2Cデバイス | |||||||||||||||
大気圧センサー 秋月電子通商 LPS331使用 高精度大気圧センサーモジュール I2Cで試したデバイスです。SPIでも使えます。 注意: SDO(4番ピンを10kΩ)でプルアップしてください。これをやらなないとセンサーからの信号が取得できません。 |
|||||||||||||||
SPIはI2Cにはないモードというのがある | |||||||||||||||
SPIにはモードというのがあります。
これを間違えると動作しません。センサーの添付資料には記載がありませんでした。わからないときは4つですので0から3まで試してください。 ちなみに大気圧センサーはモード3でした。 |
|||||||||||||||
制御の仕方は2つある | |||||||||||||||
ただデータを送るだけ Raspberry PiにカラーグラフィックLCDを接続したときは、インターフェースがシフトレジスタだけだったのでデータの流れは、 Raspberry Pi ->LCD だけです。 LCD->Raspberry Pi はありません。 これ実装した関数は、 int WriteOnly(int len, char* lpOut) です。 センサーに送って、受ける センサーに、 温度のデータを要求(送信) 温度データを取得(受信) というプロセスです。 これ実装した関数は、 int WriteRead(int len, char* lpOut, char* lpIn) です。 もうひとつ受信だけをする というのも考えられますが、それはないように思います。マスターとスレーブに分けられる場合、マスターが何か指令を出してスレーブが応答する。これが基本ですので、マスターが何もしないでただ待っているというのはなさそうです。 |
|||||||||||||||
プログラムの解説 | |||||||||||||||
仕様書をみると次のようになっています。1バイト送信、1バイト受信のタイミングチャートです。 R/W:1 アドレス送信後、受信しろ 0 アドレス送信後、送信しろ MS: 0 1バイトだけ 1 複数バイト これではわかりにくいので実例を! 大気圧センサーは、レジスタ0x20に0x90を書き込まないと計測を開始しません。これはただ データを送るだけ です。 char buf[8], rx[8]; コードは、 buf[0] = 0x00 + 0x20; buf[1] = 0x90; spi.WriteOnly(2, buf); となります。 オシロスコープの観測波形は SPIはクロックです。16個のパルスになります。 SDIはセンサーから見て入力、マスターから見て出力になります。0x20の信号が観測されました。 SDOはセンサーから見て出力、マスターから見て入力です。同一値を出しているのか無応答なのか判別はできません。 次に1バイト受信です。 コードは、 buf[0] = 0x80 + 0x2b; spi.WriteRead(2, buf, rx); 引数の2は次のようになります。 レジスタ指定て1バイト、センサーからの送信データで1バイト。合計2バイトということです。 l = rx[1]; rx[0]ではなくrx[1]に受信データがはいります。 rx[0]は0xffになるようです。 オシロスコープの観測波形は、 0x80 + 0x2b の信号が観測されます。buf[1]は0にした結果なので、次の8ビットは0です。 最初SPC8ビット送信後に、センサーが温度の下位ビットを送信しているのが観測されます。 大気圧センサーは大気圧データが3バイトで構成させています。レジスタのアドレスも0x28から連続しています。 buf[0] = 0xc0 + 0x28; buf[1] = 0x00; spi.WriteRead(4, buf, rx); MSのビットを1にしたので0xc0になっています。0x28から3バイトを取得します。 引数の4は次のようになります。 レジスタ指定て1バイト、センサーからの送信データで3バイト。合計4バイトということです。 オシロスコープの観測波形は、 クロックが4バイト出ています。 2バイト目からセンサーが気圧データを送ったのが観測できます。この値を計算すると986hPaになります。 |