- I2C通信プロトコルとは何ですか?
- I2C通信はどのように機能しますか?
- I2C通信はどこで使用しますか?
- XC8コンパイラを使用したPIC16F877aを搭載したI2C
- I2Cヘッダーファイルを使用したプログラミング:
- プロテウスシミュレーション:
PICマイクロコントローラーは、組み込みプロジェクト向けにマイクロチップが提供する強力なプラットフォームであり、その汎用性により、多くのアプリケーションへの道を見つけることができ、フェーズはまだ進行中です。PICチュートリアルをフォローしている場合は、非常に基本的なものから始めて、PICマイクロコントローラーに関する幅広いチュートリアルをすでにカバーしていることに気付くでしょう。これまで、コミュニケーションポータルのようなもっと興味深いものに入ることができる基本をカバーしてきました。
組み込みアプリケーションの広大なシステムでは、マイクロコントローラーだけですべてのアクティビティを実行することはできません。情報を共有するために他のデバイスと通信する必要があるある段階で、これらの情報を共有するためのさまざまなタイプの通信プロトコルがありますが、最も使用されるものはUSART、IIC、SPI、およびCANです。各通信プロトコルには、独自の長所と短所があります。IICの部分に焦点を当てましょう。これは、このチュートリアルで学習する内容だからです。
I2C通信プロトコルとは何ですか?
用語IICは「の略インター集積回路」。通常、I2CまたはI squared Cとして、あるいは2線式インターフェースプロトコル(TWI)として示される場所もありますが、すべて同じ意味です。I2Cは同期通信プロトコルです。つまり、情報を共有する両方のデバイスが共通のクロック信号を共有する必要があります。情報を共有するためのワイヤーは2本だけで、そのうちの1つはコック信号に使用され、もう1つはデータの送受信に使用されます。
I2C通信はどのように機能しますか?
I2C通信は、フィリップスによって最初に導入されました。前に述べたように、2本のワイヤーがあり、これらの2本のワイヤーは2つのデバイス間で接続されます。ここでは、一方のデバイスをマスターと呼び、もう一方のデバイスをスレーブと呼びます。通信は、2つのマスターとスレーブの間で常に発生する必要があります。I2C通信の利点は、複数のスレーブをマスターに接続できることです。
完全な通信は、これら2つのワイヤ、つまりシリアルクロック(SCL)とシリアルデータ(SDA)を介して行われます。
シリアルクロック(SCL):マスターによって生成されたクロック信号をスレーブと共有します
シリアルデータ(SDA):マスターとスレーブ間でデータを送受信します。
いつでもマスターだけが通信を開始できます。バスには複数のスレーブがあるため、マスターは異なるアドレスを使用して各スレーブを参照する必要があります。アドレス指定されると、その特定のアドレスを持つ軟膏のみが情報を返信し、他の軟膏は終了します。このようにして、同じバスを使用して複数のデバイスと通信できます。
I2C通信はどこで使用しますか?
I2C通信は、短距離通信にのみ使用されます。それはそれをスマートにするために同期されたクロックパルスを持っているので、それは確かにある程度信頼できます。このプロトコルは主に、マスターに情報を送信する必要があるセンサーまたはその他のデバイスと通信するために使用されます。マイクロコントローラが最小限のワイヤのみを使用して他の多くのスレーブモジュールと通信する必要がある場合に非常に便利です。長距離通信をお探しの場合はRS232をお試しください。より信頼性の高い通信をお探しの場合は、SPIプロトコルをお試しください。
XC8コンパイラを使用したPIC16F877aを搭載したI2C
十分な紹介がありますので、それに取り掛かり、マイクロコントローラーを使用してI2C通信を実行する方法を学びましょう。このチュートリアルでは、XC8コンパイラを使用したPIC16F877aのI2Cについてのみ説明していることを明確にする前に、プロセスは他のマイクロコントローラでも同じですが、わずかな変更が必要になる場合があります。また、PIC18Fシリーズのような高度なマイクロコントローラーの場合、コンパイラー自体にI2C機能を使用するためのライブラリーが組み込まれている場合がありますが、PIC16F877Aの場合、そのようなものは存在しないため、独自にビルドしましょう。ここで説明するライブラリは、PIC16F877Aが他のI2Cデバイスと通信するために使用できるダウンロード用のヘッダーファイルとして下部に提供されます。
いつものように、何かを始めるのに最適な場所はデータシートです。データシートでI2Cの詳細を探し、どのレジスタを設定する必要があるかを確認してください。データシートはすでにそれを行っているので、詳細には説明しません。以下では、ヘッダーファイルに存在するさまざまな関数と、プログラムでのそれらの責任について説明します。
void I2C_Initialize()
初期化関数は、I2Cプロトコルを使用することをマイクロコントローラーに通知するために使用されます。これは、SSPCONおよびSSPCON2レジスタに必要なビットを設定することで実行できます。最初のステップは、IICピンを入力ピンとして宣言することです。ここでは、ピンRC3とRC4をI2C通信に使用する必要があるため、これらを入力ピンとして宣言します。次に、MSSP制御レジスタであるSSPCONとSSPCON2を設定する必要があります。PICは、クロック周波数FOSC /(4 *(SSPADD + 1))のIICマスターモードで動作しています。その特定のレジスタがそのように設定されている理由を理解するには、以下のコメント行に記載されているデータシートのページ番号を参照してください。
したがって、次にクロック周波数を設定する必要があります。アプリケーションごとにクロック周波数が異なる可能性があるため、変数 feq_k を介してユーザーから選択を取得し、それを式で使用してSSPADDレジスタを設定します。
void I2C_Initialize(const unsigned long feq_K)//マスターとしてIICを開始 { TRISC3 = 1; TRISC4 = 1; // SDAピンとSCLピンを入力ピンとして設定 SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD =(_ XTAL_FREQ /(4 * feq_K * 100))-1; //クロック速度の設定pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
ボイドI2C_Hold()
次の重要な関数は、現在のI2C操作が完了するまでデバイスの実行を保持するために使用される I2C_hold 関数です。新しい操作を開始する前に、I2C操作を保持する必要があるかどうかを確認する必要があります。これは、レジスタSSPSTATおよびSSPCON2をチェックすることによって実行できます。SSPSTATには、I2Cバスのステータスに関する情報が含まれています。
プログラムには「and」と「or」の演算子が含まれているため、プログラムは少し複雑に見えるかもしれません。あなたがそれを壊すとき
SSPSTAT&0b00000100 SSPCON2&0b00011111
これは、SSPSTATの2番目のビットがゼロであり、同様に0から4までのビットがSSPCON2でゼロであることを確認していることを意味します。次に、これらすべてを組み合わせて、結果がゼロであることを確認します。結果がゼロの場合、プログラムは続行されます。そうでない場合は、 while ループで使用されるため、ゼロになるまでプログラムは保持されます。
void I2C_Hold() { while((SSPCON2&0b00011111)-(SSPSTAT&0b00000100)); //レジスタでこれをチェックして、IICが進行中でないことを確認します }
ボイドI2C_Begin()およびボイドI2C_End()
I2Cバスを使用してデータを書き込んだり読み取ったりするたびに、I2C接続を開始および終了する必要があります。I2C通信を開始するには、SENビットを設定する必要があり、通信を終了するには、PENステータスビットを設定する必要があります。これらのビットのいずれかを切り替える前に、前述のように関数I2C_Holdを使用して、I2Cバスがビジーであるかどうかも確認する必要があります。
void I2C_Begin() { I2C_Hold(); //プログラムを保持しますI2Cはビジーです SEN = 1; // IICを開始pg85 / 234 } void I2C_End() { I2C_Hold(); //プログラムを保持しますI2Cはビジーです PEN = 1; // IICを終了しますpg85 / 234 }
ボイドI2C_Write()
書き込み関数は、マスターモジュールからサルブモジュールにデータを送信するために使用されます。この機能は通常、I2C開始機能の後に使用され、その後にI2C終了機能が続きます。IICバスに書き込む必要のあるデータは、変数データを介して渡されます。次に、このデータはSSPBUFバッファレジスタにロードされ、I2Cバスを介して送信されます。
通常、データを書き込む前にアドレスが書き込まれるため、書き込み機能を2回使用する必要があります。1回はアドレスの設定用で、もう1回は実際のデータの送信用です。
void I2C_Write(unsigned data) { I2C_Hold(); //プログラムを保持しますI2Cはビジーです SSPBUF = data; // pg82 / 234 }
unsigned short I2C_Read()
知っておく必要のある最後の関数は I2C_Read 関数です。この関数は、現在I2Cバス上にあるデータを読み取るために使用されます。これは、スレーブにバスに値を書き込むように要求した後に使用されます。受信した値は SSPBUF にあり、その値を操作のために任意の変数に転送できます。
I2C通信中、マスターによって要求されたデータを送信した後のスレーブは、確認応答ビットである別のビットを送信します。このビットもマスターによってチェックされ、通信が成功したことを確認する必要があります。ACKDTビットの確認応答を確認した後、ACKENビットをセットして有効にする必要があります。
unsigned short I2C_Read(unsigned short ack) { unsignedshort着信; I2C_Hold(); RCEN = 1; I2C_Hold(); 着信= SSPBUF; // SSPBUF I2C_Hold();に 保存されたデータを取得します ACKDT =(ack)?0:1; // ackビットが ACKEN = 1を 受信したかどうかを確認します。// pg85 / 234リターン着信; }
つまり、これらの機能は、I2C通信をセットアップし、デバイスからデータを読み書きするのに十分なはずです。また、I2C通信で実行できる機能は他にもたくさんありますが、簡単にするために、ここでは説明しません。データシートをいつでも参照して、
PIC16F877AI2C通信用のヘッダーファイルを含む完全なコードはリンクからダウンロードできます。
I2Cヘッダーファイルを使用したプログラミング:
I2C通信がどのように機能し、そのために作成されたヘッダーファイルをどのように使用できるかを学習したので、ヘッダーファイルを使用してI2C行にいくつかの値を書き込む簡単なプログラムを作成しましょう。次に、このプログラムをシミュレートし、これらの値がバスに書き込まれているかどうかを確認します。
いつものように、プログラムは以下に示すように構成ビットを設定し、クロック周波数を20MHzに設定することから始まります。
#pragma config FOSC = HS //オシレーター選択ビット(HSオシレーター) #pragma config WDTE = OFF //ウォッチドッグタイマーイネーブルビット(WDT無効) #pragma config PWRTE = ON //パワーアップタイマーイネーブルビット(PWRT有効) # pragma config BOREN = ON //ブラウンアウトリセットイネーブルビット(BOR有効) #pragma config LVP = OFF //低電圧(シングルサプライ)インサーキットシリアルプログラミングイネーブルビット(RB3はデジタルI / O、HVオンプログラミングにはMCLRを使用する必要があります) #pragma config CPD = OFF //データEEPROMメモリコード保護ビット(データEEPROMコード保護オフ) #pragma config WRT = OFF //フラッシュプログラムメモリ書き込みイネーブルビット(書き込み保護オフ;すべてのプログラムメモリEECONコントロールによって書き込まれる可能性があります) #pragma config CP = OFF //フラッシュプログラムメモリコード保護ビット(コード保護オフ) #define _XTAL_FREQ 20000000
次のステップは、先ほど説明したヘッダーファイルを追加することです。ヘッダーファイルの名前は PIC16F877a_I2C.hで 、上記のリンクからダウンロードできます。ヘッダーファイルがプロジェクトリストのヘッダーファイルに追加されていることを確認してください。プロジェクトファイルの構造は次のようになります。
ヘッダーファイルがプロジェクトファイルに追加されていることを確認した後、メインCファイルにヘッダーファイルをインクルードします。
#include
while ループ内で、I2C通信を開始し、I2Cバスにいくつかのランダムな値を書き込んでから、I2C通信を終了します。私が選んだランダムな値はD0、88、FFです。任意の値を入力できます。ただし、シミュレーションで検証するため、これらの値を覚えておいてください。
while(1) { I2C_Begin(); I2C_Write(0xD0); I2C_Write(0x88); I2C_Write(0xFF); I2C_End(); __delay_ms(1000); }
完全なプログラムは、あなたがそれを使用するか、ここからプログラムの完全なzipファイルをダウンロードすることができ、ページの下部に見つけることができます。プログラムを入手したら、それをコンパイルしてシミュレーションの準備をします。
プロテウスシミュレーション:
Proteusには、I2Cバス上のデータを読み取るために使用できるI2Cデバッガーと呼ばれる優れた機器があるので、それを使用して回路を構築し、データが正常に書き込まれているかどうかを確認しましょう。完全な回路図を以下に示します。
マイクロコントローラーをダブルクリックして、プログラムによって生成された16進ファイルをロードします。次に、プログラムをシミュレートします。I2Cバスに関するすべての情報を表示するウィンドウポップアップが表示されます。プログラムのウィンドウを以下に示します。
書き込まれているデータをよく見ると、プログラムで書き込んだデータと同じであることがわかります。値はD0、88、およびFFです。値は1秒ごとに書き込まれるため、時間も次のように更新されます。青い矢印は、マスターからスレーブに書き込まれていることを示しています。そうでない場合は、反対方向を指します。送信されるデータの詳細を以下に示します。
これはI2Cができることのほんの一瞥であり、複数のデバイスに対してデータの読み取りと書き込みを行うこともできます。I2Cプロトコルで動作するさまざまなモジュールをインターフェイスすることにより、今後のチュートリアルでI2Cについて詳しく説明します。
あなたがプロジェクトを理解し、それから何か役に立つことを学んだことを願っています。疑問がある場合は、以下のコメントセクションに投稿するか、フォーラムを使用して技術的なヘルプを参照してください。
完全なコードを以下に示します。ここからすべてのコードを含むヘッダーファイルをダウンロードできます。