- SPI通信プロトコルとは何ですか?
- SPIプロトコルはどのように機能しますか?
- I2CとSPI通信の違い
- XC8コンパイラを使用したPIC16F877Aを使用したSPI:
- SPIヘッダーファイルの説明:
- メインプログラム説明:
- SPIデバッガーを使用したPICのシミュレーション:
PICマイクロコントローラーは、組み込みプロジェクト用にマイクロチップが提供する強力なプラットフォームです。その用途の広い性質により、多くのアプリケーションへの道を見つけることができましたが、まだ大きく成長していません。PICチュートリアルをフォローしている場合は、非常に基本的なものから始めて、PICマイクロコントローラーに関する幅広いチュートリアルをすでにカバーしていることに気付くでしょう。同じフローで、PICで使用可能な通信プロトコルとその使用方法を学習します。I2CについてはPICマイクロコントローラーですでに説明しました。
組み込みアプリケーションの広大なシステムでは、マイクロコントローラーだけですべてのアクティビティを実行することはできません。情報を共有するために他のデバイスと通信する必要があるある段階で、 これらの情報を共有するためのさまざまなタイプの通信プロトコルがありますが、最も使用されるものは USART、IIC、SPI、およびCANです。各通信プロトコルには、独自の長所と短所があります。 このチュートリアルで学習するのはSPIプロトコルなので、ここではSPIプロトコルに焦点を当てましょう 。
SPI通信プロトコルとは何ですか?
SPIという用語は「シリアルペリフェラルインターフェイス」の略です。これは、2つのマイクロコントローラー間でデータを送信したり、センサーからマイクロコントローラーにデータを読み書きしたりするために使用される一般的な通信プロトコルです。また、SDカード、シフトレジスタ、ディスプレイコントローラなどとの通信にも使用されます。
SPIプロトコルはどのように機能しますか?
SPI通信は同期通信です。つまり、データを交換している2つのデバイス間で共有されるクロック信号の助けを借りて機能します。また、別のバスを使用してデータを送受信できるため、全二重通信です。SPI通信が動作するように5本のワイヤを必要とします。マスターとスレーブ間の簡単なSPI通信回路を以下に示します。
通信に必要な5本のワイヤは、SCK(シリアルクロック)、MOSI(マスター出力スレーブ入力)、MISO(マスター入力スレーブ出力)、およびSS(スレーブ選択)です。 SPI通信は、常にマスターとスレーブの間でのみ行われます。マスターには、複数のスレーブを接続できます。マスターはクロックパルスの生成を担当し、同じことがすべてのスレーブと共有されます。また、すべての通信はマスターによってのみ開始できます。
SCKピン(別名SCLシリアルクロック)は、マスターによって生成されたクロック信号をスレーブと共有します。MOSIピン(別名SDA –シリアルデータ出力)は、マスターからサルブにデータを送信するために使用されます。MISOピン(別名SDI –シリアルデータ入力)は、軟膏からマスターにデータを取得するために使用されます。上図の矢印に従って、データ/信号の動きを理解することもできます。最後に、SSピン(別名CS –チップセレクト)は、マスターに複数のスレーブモジュールが接続されている場合に使用されます。これを使用して、必要なスレーブを選択できます。以下の回路に、SPI通信用に複数のスレーブがマスターに接続されている回路例を示します。
I2CとSPI通信の違い
PICとのI2C通信についてはすでに学習しているため、I2Cがどのように機能し、RTCモジュールのインターフェイスにI2Cを使用できるようにどこで使用できるかを理解しておく必要があります。しかし今、すでにI2Cがあるのに、なぜSPIプロトコルが必要なのですか。その理由は、I2C通信とSPI通信の両方が独自の方法で利点であり、したがってアプリケーション固有であるためです。
I2Cはピンの数が少なく、バスに多数のスレーブが接続されている場合に非常に便利であるため、ある程度、I2C通信にはSPI通信よりもいくつかの利点があると見なすことができます。ただし、I2Cの欠点は、データの送受信に同じバスを使用しているため、比較的低速であるということです。したがって、プロジェクトのSPIプロトコルとI2Cプロトコルのどちらを使用するかを決定するのは、純粋にアプリケーションに基づいています。
XC8コンパイラを使用したPIC16F877Aを使用したSPI:
基本はこれで十分です。次に、MPLABXIDEとXC8コンパイラを使用してPIC16F877AマイクロコントローラでSPI通信を使用する方法を学びましょう。このチュートリアルでは、XC8コンパイラを使用したPIC16F877aのSPIについてのみ説明していることを明確にする前に 、プロセスは他のマイクロコントローラでも同じですが、わずかな変更が必要になる場合があります。また、PIC18Fシリーズのような高度なマイクロコントローラーの場合、コンパイラー自体にSPI機能を使用するためのライブラリが組み込まれている場合がありますが、PIC16F877Aの場合、そのようなものは存在しないため、独自にビルドしてみましょう。ここで説明するライブラリは、PIC16F877Aが他のSPIデバイスと通信するために使用できるダウンロード用のヘッダーファイルとして下部に提供されます。
このチュートリアルでは、SPI通信を使用してSPIバスからデータを読み書きする小さなプログラムを作成します。次に、Proteusシミュレーションを使用して同じことを確認します。SPIレジスタに関連するすべてのコードは、PIC16f877a_SPI.hと呼ばれるヘッダーファイル内に作成されます。このようにして、SPI通信が必要となる今後のすべてのプロジェクトでこのヘッダーファイルを使用できます。メインプログラム内では、ヘッダーファイルの関数を使用します。ヘッダーファイルと一緒に完全なコードはここからダウンロードできます。
SPIヘッダーファイルの説明:
ヘッダーファイル内で、PIC16F877aのSPI通信を初期化する必要があります。いつものように、開始するのに最適な場所はPIC16F877Aデータシートです。PIC16F8777aのSPI通信を制御するレジスタは、SSPSTATとSSPCONレジスタです。それらについては、データシートの74ページと75ページを参照してください。
SPI通信の初期化中に選択する必要のある多くのパラメータオプションがあります。最も一般的に使用されるオプションは、クロック周波数がFosc / 4に設定され、中央で実行され、クロックが理想的な状態で低に設定されることです。そのため、ヘッダーファイルにも同じ構成を使用しています。それぞれのビットを変更することで簡単に変更できます。
SPI_Initialize_Master()
SPI初期化マスター機能は、SPI通信をマスターとして開始するために使用されます。この関数内で、それぞれのピンRC5とRC3を出力ピンとして設定します。次に、SPI通信をオンにするようにSSPTATとSSPCONレジスタを構成します
void SPI_Initialize_Master() { TRISC5 = 0; // SSPSTAT = 0b00000000; // pg 74/234 SSPCON = 0b00100000; // pg 75/234 TRISC3 = 0; //設定スレーブモード用の出力として }
SPI_Initialize_Slave()
この機能は、SPI通信のスレーブモードで動作するようにマイクロコントローラを設定するために使用されます。スレーブモードでは、ピンRC5を出力として設定し、ピンRC3を入力として設定する必要があります。SSPSTATとSSPCONは、スレーブとマスターの両方で同じ方法で設定されます。
void SPI_Initialize_Slave() { TRISC5 = 0; // SDOピンは出力として宣言する必要があります SSPSTAT = 0b00000000; // pg 74/234 SSPCON = 0b00100000; // pg 75/234 TRISC3 = 1; //マスターモードの場合はinoutに設定します }
SPI_Write(charincoming)
SPI書き込み機能は、SPIバスにデータを書き込むために使用されます。変数incomingを介してユーザーから情報を取得し、それを使用してバッファレジスタに渡します。SSPBUFは連続するクロックパルスでクリアされ、データはビットごとにバスに送信されます。
void SPI_Write(charcoming) { SSPBUF =着信; //ユーザーが指定したデータをバッファに書き込みます }
SPI_Ready2Read()
SPI Ready to Read機能は、SPIバス内のデータが完全に受信されているかどうか、およびデータを読み取ることができるかどうかを確認するために使用されます。SSPSTATレジスタにはBFと呼ばれるビットがあり、データが完全に受信されるとセットされるため、このビットがセットされていないかどうかを確認し、SPIバスから何かを読み取るためにセットされるまで待つ必要があります。
unsigned SPI_Ready2Read() { if(SSPSTAT&0b00000001) return 1; それ以外の場合は 0を返します。 }
SPI_Read()
SPI読み取りは、SPIバスからマイクロコントローラーにデータを読み取るために使用されます。SPIバスに存在するデータはSSPBUFに格納されます。完全なデータがバッファに格納されるまで待機する必要があります。その後、変数に読み込むことができます。バッファを読み取る前に、SSPSTATレジスタのBFビットをチェックして、データの受信が完了していることを確認します。
char SPI_Read()//受信データを読み取る { while(!SSPSTATbits.BF); // BFビットが設定されるまで保持し、完全なデータが読み取られるようにします return(SSPBUF); //読み取ったデータを返します }
メインプログラム説明:
上記のセクションで説明した関数はヘッダーファイルにあり、メインのcファイルで呼び出すことができます。それでは、SPI通信が機能しているかどうかを確認するための小さなプログラムを作成しましょう。SPIバスにいくつかのデータを書き込み、プロテウスシミュレーションを使用して、同じデータがSPIデバッガーで受信されているかどうかを確認します。
いつものように、構成ビットを設定してプログラムを開始し、次に説明したヘッダーファイルを以下に示すようにプログラムに追加することが非常に重要です。
#include
上記でダウンロードしたzipファイルからプログラムを開いた場合、デフォルトでは、ヘッダーファイルはプロジェクトファイルのヘッダーファイルディレクトリ内にあります。それ以外の場合は、プロジェクト内にヘッダーファイルを手動で追加する必要があります。追加すると、プロジェクトファイルは次のようになります。
メインファイル内で、PICをSPI通信のマスターとして初期化する必要があります。次に、無限のwhileループ内で、ランダムな3つの16進値をSPIバスに書き込んで、シミュレーション中に同じ値を受信するかどうかを確認します。
void main() { SPI_Initialize_Master(); while(1){ SPI_Write(0X0A); __delay_ms(100); SPI_Write(0X0F); __delay_ms(100); SPI_Write(0X15); __delay_ms(100); } }
プログラムで使用されるランダム値は0A、0F、および15であり、これらは16進値であるため、シミュレーション中に同じ値が表示されることに注意してください。つまり、コードはすべて完了しています。これは単なるサンプルですが、同じ方法を使用して、他のMCUまたはSPIプロトコルで動作する他のセンサーモジュールと通信できます。
SPIデバッガーを使用したPICのシミュレーション:
プログラムの準備ができたので、プログラムをコンパイルしてシミュレーションを続行できます。Proteusには、 SPIデバッガー と呼ばれる便利な機能があり、SPIバスを介してデータを監視するために使用できます。そこで、同じものを使って、以下のような回路を作ります。
シミュレーションにはSPIデバイスが1つしかないため、SSピンを使用していません。使用しない場合は、上記のように接地する必要があります。16進ファイルをPIC16F877Aマイクロコントローラーにロードし、再生ボタンをクリックするだけで、プログラムをシミュレートできます。シミュレーションが開始されると、以下に示すようにSPIバス内のデータを表示するポップアップウィンドウが表示されます。
入ってくるデータを詳しく見て、それが私たちのプログラムで書いたものと同じであるかどうかを確認しましょう。
データは、プログラムで記述したのと同じ順序で受信され、同じものが強調表示されます。SPIプロトコルを使用して2つのPICマイクロコントローラーと通信するプログラムをシミュレートすることもできます。1つのPICをマスターとして、もう1つのPICをスレーブとしてプログラムする必要があります。この目的に必要なすべてのヘッダーファイルは、すでにヘッダーファイルに記載されています。
これはSPIができることのほんの一瞥であり、複数のデバイスに対してデータを読み書きすることもできます。SPIプロトコルで動作するさまざまなモジュールをインターフェースすることにより、今後のチュートリアルでSPIについて詳しく説明します。
あなたがプロジェクトを理解し、それから何か役に立つことを学んだことを願っています。疑問がある場合は、以下のコメントセクションに投稿するか、フォーラムを使用して技術的なヘルプを参照してください。
完全なメインコードを以下に示します。ここからすべてのコードを含むヘッダーファイルをダウンロードできます