I2C通信(TWI)


i2c

最近マイコンに搭載されているI2C通信(AVRではTWI)のテスト


I2C通信は、信号ライン2本で可能なシリアル通信で1対1以外に1対多なども可能な有用な通信

基本的な通信処理をテスト

I2C通信

シリアル通信で1対1以外に、1対多なども可能な有用な通信。いろんなところで解説されているので ほかも参考に。

 

I2C通信は、

USARTのように1-1の通信以外にマスターとスレーブとなった2つが通信でき、スレーブ側には複数も可能。

 

通信のデバイスが局になってアドレスを設定出来るので、
いっぱいデバイス(局)をつないでおいて、送りたい局へ送るという2局通信、 また一斉に送る通信もできる。

 

通信は双方向、信号線は2本でよいというのも手軽に使えそうで魅力を感じます。

I2c通信ブロック局接続

 

通信形式自体が複雑なのでこういうタイプの通信が初めてだと通信形式の理解はわかりにくいです。

LANのようにパケットがライン上を駆け巡り、つながっている局のどこに渡るかわからない通信形式は、方式を読んで理解するより簡単なところから使ってみるのが良さそうです。

 

AVRで I2C通信

AVRはI2Cと同様のTWI(Two Wired Interface)の機能をもつチップがありTWIでI2Cができる。

 

AVRはmega8シリーズ、ATmega8/48/88 などにTWIの機能が備わっています。これを使うとハードの設定機能に頼ってI2C通信ができる。
ATtiny2313にはTWIの機能はなし。

TWIがないチップ種類でも、信号パルスの通信規格から自分でパルスを作る、または汎用通信設定機能USIなどで半手動(実際は半分以上)で、がんばれば通信できますが、I2Cの形式の通信を理解するまではTWI機能で設定して慣れた方がいいと思います。(最初から手動or半手動でやらない方が無難です)

 

AVRのTWI(Two Wired Interface)の特徴

  • バイト単位、割り込みでのI2C通信。
  • アドレスは7ビット、128個までの局が可能。
  • 400kHzまでのデータ速度
  • I2C規約互換

 

I2C通信の形

信号ライン(バス)は2本で、いくつものデバイスを通信ラインにつなげて、ブラさっがっている、どこと-どこでも通信ができる有用な通信。

I2c通信ブロック局接続

 

通信信号ラインは2本(SDA,SCL)ですが、注意はプルアップされたライン(R1,R2)で接続される。

 

ぶら下がった(つながっている)デバイス(局)のなかでマスターとスレーブ間が通信をする。マスター、スレーブは設定で決めますが、固定ではなく、動的に変更できます

 

どれかがまず、マスター(主人)になり、通信の主導権を握る。そしてスレーブ(奴隷)になったものがそれに従うという通信方法。

 

マスターは通信の主導権を持ち、自分から送るか、スレーブに指示して送らせるか、など通信の形を決める

 

  • マスター送信  → スレーブ受信
  • マスター受信  ← スレーブ送信

 

マスター(主人)は通信の主導権を持ちますが、マスターは(主人)ですが、

王様とは違うので、王様ゲームのように
自分と関係ない ”DはBにデータを送れ” というように、自分が関わらない通信は作れません。

 

  • マスターが通信を終了して降りれば、他がまたマスターとなり通信ができる。
  • マルチマスターという用語がありますが、同時に2つはマスターとはなれない。
  • マスターから放送局みたいに一斉送信(ジェネラルコール)も可能

 

一対一の通信の流れ

 

I2C通信、まず1対1通信方法の流れ。

 

I2C通信それそれの段階の手続きの簡単流れです。
パルス状態も考えると複雑になるので考えず、TWIの機能設定で通信を作る方法の説明です。

 

データシートを元に

マスター送信動作 → スレーブ受信動作  の簡単な流れ
 (用語はデータシートから)

 

【マスター側】

  1. マスターが開始条件を送出(逆に言うと開始条件を送出でマスターになる)
  2. 続くアドレスパケット送出( SLA_ )で、送信( SLA_W )か受信( SLA_R )動作か決まる
    SLA_W でマスター送信動作 MT
    SLA_R でスレーブ受信動作 MR
  3.  

  4. 受信したスレーブ局から応答
    応答があれば、続いて
  5. データ送信
    受信したスレーブ局から応答
  6. 終了条件送出で 通信終わり、バス解放(するとまだどこかがマスターになって通信が可能)

 

【スレーブ側】

  1. スレーブの設定をする、自分の局アドレスを設定する。
    自分あてのSLA_を受け取ると、
    続く
    SLA_W でスレーブ受信動作
    SLA_Rで スレーブ送信動作
  2. スレーブ応答
    ・データを受ける
  3. スレーブ応答
    ・停止条件受け取り終了

 

というような流れ。

 

基本の流れ以外にも
どの局でも、放送局にも受信局にもなれるので、通信のタイミングによっては、待ってましたとばかりに一斉にみんながマスターになろうと同じ時期に名乗りを上げたりすると、調停がされたり、また通信の再送などもありますが、そういう処理は今回除外。

 

2C通信設定 手順

以下、データシートに従った設定と流れ。

 

AVRの機能を使ったTWIの設定、通信方法

通信にはI2Cは マスター(1つ) と スレーブ(1つかそれ以上)がいます。
マスターが開始条件を出して通信が始まり、マスターが終了条件を出して通信終わる。

 

通信が終了すると、通信ライン(バス)が解放される。するとまたどれかがマスターになって新たな通信ができる。

 

マイコンの機能を使い、レジスタに通信設定する方法ですが、データシートはじっくり読むと設定手順がまとめられています。


自分でも分類、設定表を作ることがあるのでその視点で見ると、この表、じっくり読むと、すごくうまく整理されて記述されていると思えてきます。

 

マスター送信動作、状態や応答について

 

マスター送信動作 ステータステーブル

I2Cstatabletable

 

Status Code (最左列) 
TWCRの設定によって(ステータスレジスタ)TWSRで 装置や通信状態を得ることができる。
それぞれの状態で、このStatus CodeをTWSRで得ることができ、ACK応答などが返る場合などは右側に記載
NextActionbyTWI (最右列)hariware 状態によってその応答などが記述されている。
ハード(装置)が、状態により通信規約で返すことになるACK、NACK信号など

 * ACK信号はマスターでもスレーブでも受信した方が出す信号。

 

マスター送信動作 通信の流れとステータス

 

マスターとスレーブのやりとりについての記述チャート

 

マスターのチャート。スレーブから応答がある場合を、色の抜いた枠で示されている。(各記号などはデータシート参照のこと)

 

チャートでは、つつがなく通信が進んだ場合が最上、
どっかで衝突、調停などスムーズにいかない場合、状態が移る遷移が下に。
それら各状態をStatus Cocd (TWSR) :$08 などのステータス値で得ることができる。

 

最上のチャートをステータスと併せた表

 

マスター送信動作
通信開始  アドレス:
送信先を流す 
→  アドレス宛先があれば
ACK返ってくる 
→  続いて
データ送出 
受信されると
ACK返ってくる
終了条件 
送出
 S SLA_W送出   Data A  
 状態 $08    $18    $28    

こんなスムーズにいかず、どっかで通信不良があると対応動作として通信の規約に従い状態が下に遷移

 

プログラム

テストとして通信段階に従い、通信とチェックを上から順に作っていきました。

 

マスター送信動作 → スレーブ受信動作 の設定で 1対1の通信 2局間の通信です。

 

I2C通信テスト プログラム

2局間 2つのチップ間で通信するので、当然ですが2つのチップが必要です。

 

  • 受信は受信用のAVRmaga8/48/88
  • 送信は送信用のAVRmaga8/48/88 に別々に書き込みます。

 

通信は一度だけ。
まずは先に受信チップを起動し、待機(受信待ち)する。
送信チップを起動すると、自動的に通信が始まる。

●回路

通信ラインは10kΩでプルアップされたPC4,PC5で接続

 

回路は受信、送信共に同じ

 

LED接続
通信の各段階はPB1 LEDで確認できます。
データの受け渡しは PD6,7 LED

 

●テストプログラム

送信側 プログラム

ファイル名





#include 	

//状態値
#define		START	0x08		//スタート状態値
#define		RECEIVE	0x60		//自分あての受信状態値

#define		MT_SLA_ACK	0x18	//アドレス:SLA_Wを正常送信チェック値
#define		MT_DATA_ACK	0x28	//データを正常送信チェック値


void wait( int );

int main(){

	unsigned char i;
	
	DDRB = 0x03;	//0b00000011;	//LED ピン 出力設定
	DDRD = 0xC0;	//0b1100 0000;	//LED ピン 出力設定

	TWBR = 0xFF;	//分周	2KHz

	PORTB = 0x02;	//0b00000001;	//初期値
	wait(1000);

	PORTB = 0x00;
	wait(1000);

		TWCR = 0xA4;						//①I2C開始条件送出

		while( !( TWCR & (1<< TWINT) ) );	//②結果待ち

		while( ( TWSR & 0xF8 ) != START );	//③送信可?

		TWDR = 0x80 ;					// あて先アドレス設定

		TWCR = ( 1<< TWINT )| ( 1<< TWEN ) ;		//アドレス送信開始
		while(  ! ( TWCR & ( 1<< TWINT ) ) );	//④あて先アドレス送信完了待ち

	PORTB = 0x02;	//送信先の応答待ち
		wait(1000);

		while(  ( TWSR & 0xF8 ) != MT_SLA_ACK );	//⑤アドレス:SLA_W 正常送信チェック

	PORTB = 0x00;	//送信先の応答確認受け取り 合図 LED消灯

			//データ送信
		i = 0xC0;		//送信データ
	PORTD = i;				//データ送信 合図
		wait(1000);

		TWDR = i;		//送信データセット

		TWCR = ( 1<< TWINT )| ( 1<< TWEN ) ;//送信開始
		while(  ! ( TWCR & ( 1<< TWINT ) ) );//⑥完了待ち

		while(  ( TWSR & 0xF8 ) != MT_DATA_ACK );	//⑦データ 正常送信チェック
	PORTD = 0x00;			//送信データ受け取り確認 合図 LED消灯

		TWCR = ( 1<< TWINT )| ( 1<< TWSTO )| ( 1<< TWEN ) ;	//I2C停止条件送出 バスの開放

	PORTB = 0x02;		//停止の目印

}

void wait( int time ){

	int j;
	unsigned char k;
	
	for ( j=0; j < time ;j++){
		for ( k=0; k<100 ;k++);
	}
}		 
       

 

受信側のプログラム
処理の流れ (ほほソースファイル同様です)

 

マスター送信動作 処理の簡単な流れ

 

  1. TWCR = START
    I2C開始条件 送出  TWCR.INT = 1 ?  送出完了? (TWINT=1まで待機)
    (TWSR & 0xF8 ) = START ? 開始条件完了?
  2. TWDR=アドレス 送信先アドレス設定
  3. TWCR=SLA_W  アドレス送信 SLA_W(アドレスデータ+R/W)
    TWCR.INT = 1 ?   送出完了? (TWINT=1まで待機)
    (TWSR & 0xF8 ) = ?MT_SLA_ACK    完了? 
  4. TWDR=データ データ設定
  5. TWCR= MT_DATA_ACK データ送信
    送出完了? (TWINT=1まで待機) (TWSR & 0xF8 ) =?
    MT_DATA_ACK   完了?
  6. TWCR= END I2C停止条件 送出

 

実行

先に受信チップを起動し、待機(受信待ち)する。
続いて送信チップを起動すると、自動的に通信が始まる。

 

通信データ
  • 送信データは、LED PD6, 7 で最初は送るとき点灯。
  • 送信終了するとLEDは消灯
  • そして、受信側にデータ移り、受信側LED PD6, 7点灯する。

 

通信段階合図LED

各段階で送信、受信側の合図LEDが点灯、消灯しながら通信が進む。
各段階の合図LEDの動作はプログラムソースで確認のこと。

 

  • 通信終了で 、送信側 合図LED 点灯
  • 受信側 合図LED 消灯

最後にこうならなかったら、終了信号の送受信がうまく処理できていない。

 

スポンサーリンク
  • facebook
  • twtter
  • google+
  • hatena