シリアル-ペリフェラル-インタフェース(SPI)は、フィリップスが独自の集積回路のためにI2Cシリアル-バスを考案したのと同じように、モトローラによってチップ同士の通信を可能にするために開発された。 これら二つのバスはほぼ同じ仕事をしていますが、どちらもほぼ同じように一般的になっており、多くの周辺機器はホストマイクロコントローラと この遍在性がimpsが両方をサポートする理由です。
SPIにはI2Cよりもいくつかの利点があり、特に高いデータ転送レートをサポートします。, SPIはまた、同時双方向通信を必要とするアプリケーションに特に適している二重機能を備えています。
一方、SPIは、バス上のすべてのデバイスで共有される少なくとも三つのワイヤと、コントローラデバイスに接続された各周辺機器に対していくつかのデバイス選択ラインを必要とします。 これに対して、I2Cは、バス上のすべてのデバイスを識別するために一意のアドレスを使用します。, これにより、SPIのアドレスレスアプローチよりも複数のデバイスでの作業が簡単になりますが、一部の開発者はアドレスデータではなくハードウェアを使
コントローラとペリフェラル
SPIはデバイスを”コントローラ”と”ペリフェラル”に分離します。 データ転送を同期させるためにタイミングパルスを送信できるのは一つのデバイスだけです。 コントローラとタイミングを同期させる他のすべては、補助周辺機器と見なされます。, コントローラ(現在はimpである必要があります)とその周辺機器はすべてデータを送受信できますが、すべてが動作するタイミングパターンを確立できるのはコントローラだけです。 固定タイミング方式のこの確立は、I2CのようなSPIを”同期”バスにするものです。
物理バス
impのSPI実装には、
- SCLK、コントローラからのシリアルクロック信号があります。
- COPIは’Controller Out,Peripheral In’の略です(古いデータシートではMOSIとラベル付けされることもあります)。,
- CIPO、’Controller In、Peripheral Out’(時には味噌とラベル付けされています)の略です。
- CS、’Chip Select’の略(SS、nSSまたはSYNCとラベル付けされることもあります)
COPIおよびCIPOはデータ転送ラインです。imp001およびimp002には専用のCSピンはありません。 Imp003およびupは、IMPピンmuxページに記載されているSPIバスの一部として専用のCSピンを提供します。
メモimp005は、その二つのSPIバスのそれぞれに専用のチップセレクトピンを提供します。 SpiBCADの場合はDピン、spi0の場合はCS0ピンです。, Imp APIメソッドchipselect()は、これらのチップセレクトピンのアサーションとデアサーションを制御するために使用できます(詳細については、メソッドのドキュメ
IMP上のSPI:四つまでの行は、単一の周辺機器に接続します
このアプローチは、SPIのモトローラの定義に従います:各バストランザクション—本質的にデータバイトのバッチ—, テキサス-インスツルメンツは、各バイトを特定の周辺機器に送信できるようにSPI仕様を変更しましたが、これには専用のCS回線が必要です。 このモードは現在どのimpでもサポートされていません。
Signalling
コントローラに単一の周辺機器が接続されていると仮定すると、コントローラがCSラインをローに引っ張ることによって通信が開始されます。 そのため、周囲には会話の準備をするように指示します。 これで、コントローラはSCLKラインに沿ってクロックパルスを送信し始めます。,
データのクロックインとアウト:impはコマンドを送信し、周辺はデータを返します
コントローラはCOPIラインでデータを送信し、ラインをハイに駆動して1またはローに0 ペリフェラルは信号を読み取ります—たとえば、センサー読み取りを送信するためのコマンドである可能性があります—そして、CIPOライン上でその情報を返し、再びラインをハイに保ち、1を信号にするか、0を送信するためにローに駆動します。, ラインを積極的にハイまたはローに駆動し、抵抗を接続することによってどちらか一方の状態に落ち着かせるという要件が、SPIがI2Cよりも高い速度をサポートできる理由です。 I2Cは、プルアップ抵抗がラインをハイ-レベルに戻しながら、送信時間を失います。
それにもかかわらず、impが起動またはスリープしているときにハイになり、手動でラインをハイに駆動できないようにするために、CSライン上にプルアップを持つことをお勧めします。 ラインを高く保つことは周辺装置がデータおよび時計ラインの不具合を無視することを保障する。,
コントローラが欲しいものを持っているとき、それはCSラインをもう一度高く駆動し、周辺機器は休むことができます。
imp SPIオプション
すべてのimpには、起動時にインスタンス化されるデバイスのハードウェアオブジェクトのプロパティとしてアクセスされる独立したSPIバスがいくつかあります。 各impのpin muxのテーブルはあなたがあなたのプロダクトで使用しているどのタイプのimpによって多くの選択があることを示します。 この資料はimp001を使用している、従って別のimpを使用すればpin muxのテーブルを参照するべきであることを前提としています。, Imp001の二つのSPIバスは両方ともバスの三線式実装であり、それぞれピン1、8および9、および2、5および7に接続されています。 ピン1および5はSCLK、8および7COPI、および9および2CIPOです。
spi1 <- hardware.spi257;spi2 <- hardware.spi189;
どちらかを使用するように設定することは、バスを実行する速度をimpに伝え、バスの動作方法を決定する定数のセットを提供することです。
spi1.configure(modeFlags, speed);
まず、速度。, This is simply an integer value giving the throughput in kiloHertz (kHz):
The specific SPI data rates available (in kHz) are as follows:
imp001, imp002 | imp003 | imp004m | imp005 | imp006 | |
spi189 | spi257 | spiEBCA spiLGDK |
spiAHSR spiGJKL |
spiBCAD spi0 |
spiXTUVW |
15,000 | 30,000 | 18,000 | 24,000 | The SPI data rates available range from 5KHz to 22.,8MHz The SPI is clocked by dividing 160MHz by any integer from 7 to 32,000 inclusive |
Min. 187KHz, max. 750KHz |
7500 | 15,000 | 9000 | 12,000 | ||
3750 | 7500 | 4500 | 6000 | ||
1875 | 3750 | 2250 | 3000 | All others | |
937.50 | 1875 | 1125 | 1500 | Min. 187KHz, theoretical max. 24MHz |
|
468.75 | 937.50 | 562.50 | 750 | ||
234.,375 | 468.75 | 281.25 | 375 | ||
117.1875 | 234.375 | 140.,g)エッジ | |||
MSB_FIRST | 最上位ビットを先に送信(デフォルト) | ||||
LSB_FIRST | 最下位ビットを先に送信 | ||||
NO_SCLK | SCLKピンは使用されていません | ||||
USE_CS_L | |||||
USE_CS_L | 専用チップセレクトピンの使用を有効にします(imp005のみ) |
これらは、論理or演算子|
を使用して組み合わせることができますが、いくつかは相互に排他的であるため、simplex_txとSIMPLEX_RXを組み合わせるべきではありません。, たとえば、clock_idle_lowとCLOCK_2ND_EDGEの両方を使用するには、configure()メソッドに単一の定数をパラメータとして入力する代わりに、|
記号で区切って両方を含めます。
spi1.configure(SIMPLEX_TX | MSB_FIRST | CLOCK_IDLE_LOW, 400);
ペリフェラルのデータシートで指定されている場合は、組み合わせが必要な場合がありますが、これは初心者にはすぐにわからないかもしれませんが、これは初心者にとってはすぐにはわからないかもしれません。 データシートでは、デバイスの”SPIモード”、またはそのCPOL(クロック極性)およびCPHA(クロック位相)値について説明することができます。, CPOLおよびCPHAは、データ信号の駆動およびサンプリングに使用されるクロック信号のエッジを決定します。
SPIモード
SPIモードは、個別のCPOL値とCPHA値ではなく、これらの組み合わせにインデックスを付けるだけです。 コントローラと周辺機器は、同じCPOL値とCPHA値を使用して通信する必要があり、したがって同じモードで通信する必要があります。, 複数の周辺機器は異なる構成を意味する可能性があるため、コントローラは特定の周辺機器と通信する必要があるたびに再構成する必要があります。,次の表:
データの読み取りと書き込み
SPIバスを設定したら、write()メソッドを使用してバイト文字列を周辺機器に送信します。
spi1.write("This is an LCD display");
文字列の使用はオプションです。
local blob = blob(4); // Create a four-byte blob...blob.writen(0xDEADBEEF, 'i'); // ...and write a 32-bit value to itspi1.write(blob);
文字列またはblobを読み取るかどうかにかかわらず、文字列またはblobを読み取ることができます。
文字列またはblobを読み取るかどうかにかかわらず、文字列またはblobを読み取る必要があります。
local bytes = spi1.readblob(8);local inputString = spi1.readstring(16);
パラメータとして渡される整数値は、それぞれblobに読み込まれるバイト数と文字列に入れられる文字数です。, もちろん、一つの文字が一つのバイトを占めるので、これら二つの方法は同等です。 後者は単にblobを文字列に変換します。
SPIバスの”全二重”の性質のため、書き込みと読み出しは常に同時に行われます。 これまで見てきた読み取りと書き込みコマンドでは、関心のあるデータとは反対方向に移動するデータは無視されるかゼロになります。 したがって、文字列を書くとき、たとえば、周辺機器からimpに到着するデータは無視されます。, 二つの読み取り操作のいずれかの間に、一致するサイズの’ダミー’ゼロバイトが周辺機器に書き込まれます。
この同時双方向通信を管理するために、imp APIには読み取りと書き込みを組み合わせた第四のメソッドがあります。
local inputString = spi1.writeread(outputString);
したがって、文字列outputStringがCOPIラインに沿って送信されているとき、変数inputStringはCIPO上に来るデータバイトで埋められています。 文字列またはblobを送受信できますが、入力と出力の両方が同じタイプである必要があります。, 出力blobが大きい場合でも、入力blobは同じサイズになります。 同様に、入力文字列と出力文字列は同じ長さになります。
全二重動作は、そのように動作することを期待しないデバイス—読み取りおよび書き込みの”ダミー”バイトを特定の非ゼロ値であることを必要とするデバイスでも使用することができます。 この要件は、通常のwrite()、readblob()、およびreadstring()メソッドを使用することを除外しますが、writeread()をその代わりに使用して、デバイスの優先ダミー値が使用されるようにすることができます。,
コード例
次のコードは、SPIを使用してホストマイクロコントローラと通信するアナログ-デバイセズのADXL345デジタル加速度計で動作します。 また、I2Cもサポートしており、チップをベースとしたこのAdafruitブレイクアウト-ボードのピンにはそれに応じてラベルが付けられます。 チップのデータシートは、アナログ-デバイセズのwebサイトから
コードの仕組み
imp001のspi257バスを使用し、リストの始めの近くにspiとしてエイリアスされています。 また、CSラインとしてピン8を別名で呼び出します。 関数spiWriteReg()は、これらがどのように使用されているかを示します。, 書き込みの取引により信号を切り替えるCS線ます。 次に、書き込みたいレジスタのアドレスは、Blobに書き込むことによってSquirrel32ビット符号付き整数から8ビット値に変換されます。 次に、このblobがSPIバスに書き込まれます。 ADXL345をそのレジスタに入れたい値で同じことを行い、CSラインを再びハイに設定してトランザクションの終了を通知します。,
Adafruit/Analog Devices ADXL345
関数spiReadReg()は同じように動作しますが、今回はソース-レジスタのアドレスを書き込んだ後にバスから値データを読み取ります。 ADXL345は、トランザクションを読み出し動作としてマークするためにビット7を設定する必要があり、ビット6は、単一バイト以上のセントバックが予想されることをチップに伝えるために設定する必要があります。,
プログラムが正常に起動するところで、IMPのSPIバスをADXL345チップの要件に一致するように構成します。 SPIモード3—ieを使用します。 cpolとCPHAの両方を設定する必要があります—そのため、configure()コールで同等のimpパラメータCLOCK_IDLE_HIGH|CLOCK_2ND_EDGEを使用します。 また、速度を100kHzに設定しました。 次に、ここでCSピンとして動作しているimpのピン8は、デジタル出力として設定され、ハイ-レベルに設定されます。
ADXL345の配線
プログラム内の他の機能は、SPIバスではなくADXL345自体を初期化します。, ADXL345が初期化され、コードはレジスタ-アドレス0x00
から値を読み込み、デバイスがバス上に存在することを確認します。 破片に一連の口径測定の読書が取られるようにする自己テストモードがある;これは私達が結果をし、貯える。 その後、関数loop()では、これらの値が加速度計からの最終的な読み取り値を調整するために使用されます。,
ADXL345は、x軸、y軸、z軸のサンプルを16ビット値としてそれぞれ8ビットのレジスタに保存します。loop()はspiReadReg()関数を使用して各値の二つの成分を取得し、最上位バイトに256を乗算し、結果に最下位バイトの値を加算することによってそれらを単一の値に変換します。