I2Cを制御する

ee9king に投稿

ちょっと、この記事は古いです。。。だいぶ前に書いたものを持ってきたので。。

デジタルノギスの表示部を取り出そうと思い、小さい液晶を探した所、秋月さんにI2Cタイプの小型の物があり、それを使う事にしました。ところで、I2Cでどうやって使うのって所から始めました。う〜ん実は判っていたようでいざ使おうとすると、う〜んよくわからん。設定に有るいくつかの事が実際わからなかった。

I2C仕様書

http://www.nxp.com/documents/user_manual/UM10204_JA.pdf

数年前までは、philips(NXP)にライセンス料を払わないとI2Cを名乗れなかったのですが、ライセンスは切れているようですよ。

I2Cを動かす

秋月の説明書に有る、ここの部分

  • スレーブアドレスは、0xC7です。(アドレス0111110+0(R/W))
  • コントロールバイトで「データ、コマンドの指定」RSと「連続データの指定」Coを送信します。
  • コマンドの場合RS=0、データはRS=1になります。データを複数送る場合Co=1で、最終データはCo=0です。

特に最後の「データを複数送る場合Co=1で、最終データはCo=0です。」の部分。言っている事は判るのだが、データって0~FFまで有るわけだから、連続で送ったらコントロールかデータかなんて判らんやんか。これはつまり、最終データのときはCo=0としなはれということで、連続してデータを送る場合は、最後のデータを送りきったら、STOP状態を作ってのみ終了できるということ。と理解しておこう。下の表が参考になるのだろう。

  • 一つのバスに複数デバイスをぶら下げる事が出来るのと、MasterになったりSlaveになったりするので、SDA,SCLともOpenDrain。PullUpする必要がある。
  • データ列の最初にアドレスを指定する。
  • データは8bit、MSBファースト固定の模様
  • 8bitごとにACKを返す(Slave->Master)。ACKは1bit。Masterだけど、1bit受信する。
  • データ列の最初にStartビット(Start状態)、最後にStopビット(Stop状態)の遷移をもうける。
 Co  Description
0 Last control byte to be sent.
Only a stream of data bytes is allowed to follow.
This stream may only be terminated by a STOP condition.
最後の制御バイトが送信される。
データ·バイトのストリームのみをたどることができる。
このストリームはのみSTOP条件で終了させることができる。
1 Another control byte will follow the data byte unless a STOP condition is received.
STOP条件を受信しない限り、別の制御バイトはデータバイトに従います。

StartとStop

データ列の最初にStart状態があって、最後にStop状態があるということらしい。そのStartとStopを作り出すための手順がある。

ユーザマニュアルから、

  • START 条件とは、SCL が High のときの SDA の High から Low への遷移です。
  • START 条件は、シフト・レジスタの MSB を 0(ゼロ)にセットすることにより生成されます。
  • USIGE ビットおよび USIOE ビットをセットすると、出力ラッチがトランスペアレントになり、シフト・レジスタの MSB がただちに SDA に供給され、ラインを Low にします
  • USIGE をクリアすると、クロック供給ラッチ機能が再開され、データが SCL でシフト・アウトされるまで SDA 上で 0(ゼロ)を保持します。
void i2c_start(void){
  while(!(P1IN & BIT6));
  USISRL = 0;
  USICTL0 |= USIGE + USIOE;
  USICTL0 &= ~USIGE;
}
  • STOP 条件とは、SCL が High のときの SDA の Low から High への遷移です。
  • シフト・レジスタの MSB をセットし、USICNTx に 1をロードします。
  • USIGE ビットおよび USIOE ビットをセットすると、出力ラッチがトランスペアレントになり、USISRL の MSB は SDA をアイドル状態に解放します。USIGEをクリアすると、出力ラッチに MSB が格納され、出力は USIOE をクリアすることによりディスエーブルにされます。
void i2c_stop(void){
  USICTL0 |= USIOE;
  USISRL = 0;
  USICNT = 1;
  while(!(USICTL1 & USIIFG));
  USISRL = 0xff;
  USICTL0 |= USIGE;
  USICTL0 &= ~(USIGE + USIOE);
}


 

データを送る

データを送る場合は、最初のほうで説明があるように、RS=1になる。それで、連続してデータを送ることになるから、Co=0となる。

  1. Start状態
  2. Slaveアドレス送信
  3. Co=1,RS=0でコマンドSet指定(80h)
  4. Set DDRAM Addressコマンド(80h+Addr)
  5. Co=0,RS=1でデータSet指定(40h)
  6. データ、データ、、、、、
  7. Stop状態

途中で、DDRAMアドレスを変えるときは、Start状態からはじめる。。。。。う~ん、めんどい。

 

Tags

コメントを追加

Plain text

  • HTMLタグは利用できません。
  • ウェブページのアドレスとメールアドレスは自動的にリンクに変換されます。
  • 行と段落は自動的に折り返されます。