inter integrated circuit 2 icfreeplanets.ship.jp/electric/souzoukougaku/h27/day4/h27...i2c inter...

23
I 2 C I nter I ntegrated C ircuit 2(データとクロック)IC間の通信を行う.(注,実際にはGNDも必要) たくさんのデバイスがあっても,2つの線だけで接続できる. それぞれのデバイスには,アドレス(7bit = 128個)が割り振られて,識別できる. バス上には一つのマスターデバイスが存在 (マスターデバイスは動的に変更できるが,通常はマイコンをマスターとして固定して使う) USBなどと比べて)通信規則が単純なので,マイコンやセンサーなどの小さいデバイス間の通信 に適している. 誤り検出,訂正の仕組みがないので,大きなノイズがのる可能性のある長距離伝送にはあまり向かない

Upload: others

Post on 14-Oct-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2CInter Integrated Circuit

2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

たくさんのデバイスがあっても,2つの線だけで接続できる.それぞれのデバイスには,アドレス(7bit = 128個)が割り振られて,識別できる.バス上には一つのマスターデバイスが存在  (マスターデバイスは動的に変更できるが,通常はマイコンをマスターとして固定して使う)(USBなどと比べて)通信規則が単純なので,マイコンやセンサーなどの小さいデバイス間の通信に適している.誤り検出,訂正の仕組みがないので,大きなノイズがのる可能性のある長距離伝送にはあまり向かない

Page 2: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2C,マスタとスレーブマスタ- バス上に(同時には)1つのみ存在が許される,唯一絶対の存在

クロック(SCL)は常にマスターが駆動 ー>通信のタイミングはすべてマスタが支配するデータ通信の相手は,初めにマスタが指定する.この指定されたデバイスのみがマスターとデータを送(受)信する.指定されなかったデバイスは,通信が終わるまで何もしない(通信に燗する動作は).

スレーブ その他大勢.それぞれ個別の名前(=アドレス)を持っていて,自分と他人を区別できる.マスタからご指名があったら,その要求(送信か受信)にしたがってデータを通信する

(1)通信相手と通信方向を指定

Page 3: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2C,マスタとスレーブマスタ- バス上に(同時には)1つのみ存在が許される,唯一絶対の存在

クロック(SCL)は常にマスターが駆動 ー>通信のタイミングはすべてマスタが支配するデータ通信の相手は,初めにマスタが指定する.この指定されたデバイスのみがマスターとデータを送(受)信する.指定されなかったデバイスは,通信が終わるまで何もしない(通信に燗する動作は).

スレーブ その他大勢.それぞれ個別の名前(=アドレス)を持っていて,自分と他人を区別できる.マスタからご指名があったら,その要求(送信か受信)にしたがってデータを通信する

(2)データを送信,または受信

他のデバイスは何もしない

Page 4: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2Cの通信信号通信開始信号 通信終了信号

通信の最小単位(1バイト)

最初の1バイトでアドレスと送受信方向を指定 2バイト目からは,実際のデータの送受信

Page 5: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DH

http://akizukidenshi.com/img/goods/C/K-06791.jpg

MEMS 3軸加速度センサ(3-axis Accelerometer)

Page 6: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DHデータシート, STMicroelectronics NV

Page 7: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

S

LIS3DHの使い方

Address(0x18) W Register address

LIS3DHのレジスタへの数値の書き込みProtocol to write data to the register of the LIS3DH.

LIS3DH datasheet

Data P0

Start Stop

Page 8: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

S

LIS3DHの使い方

Address(0x18) W

LIS3DHのレジスタへの数値の書き込みProtocol to write data to the register of the LIS3DH.

LIS3DH datasheet

Data P

Ex.)

0x20 … CTRL_REG_1

0 1 0 1 0 1 1 1

Data rate = 100 HzNormal modeAll X, Y and Z axis enabled

Register address0

0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0

Page 9: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DHの使い方LIS3DHのレジスタからのデータの読み込みProtocol to read data from the register of the LIS3DH.

S Address(0x18) W

Data P...

Sr Address(0x18) R

レジスタアドレスのセットSet register address

読み込みスタートStart reading

レジスタのデータData from the register

Register address0

Repeated start

Page 10: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DHの使い方LIS3DHのレジスタからのデータの読み込みProtocol to read data from the register of the LIS3DH.

S Address(0x18) W

Data P

Sr Address(0x18) R

レジスタアドレスのセット (0x08 = OUT_1_L)Set register address

読み込みスタートStart reading

X-軸の計測値(の下位8bit)Least significant byte of X-axis acceleration

Register address0

Repeated start

0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1

Page 11: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

レジスタアドレスの自動更新Auto increment of register address

S Address(0x18) W Sr Address(0x18) R

レジスタアドレスのセット (0x08 = OUT_1_L)Set register address

読み込みスタートStart reading

Register address0

0 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1

Data P

OUT_1_L(0x08)の値

Data Data ...

OUT_1_H(0x09)の値

OUT_2_L(0x0A)の値

一つ読み出すことに,レジスタのアドレスが一つづつ増える.→ 連続してデータを読み出せるRegister address is automatically increased

ここを1にすると

Page 12: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2C通信用関数

int i2c_start(){ i2c_wait_idle(); I2C1CONbits.SEN = 1; while(I2C1CONbits.SEN) ; if(I2C1STATbits.BCL) return ERR_I2C_BUS_COLLISION; //Bus collision return 0;

I2Cバスが空いているか調べる(is I2C bus idle?)

Startを送信する(Send Start condition)

もし,他のデバイスが同時にスタータを送信したら,衝突が生じる (Bus collision ?)ー>エラー (Return error code)

Start送信が終わるのを待つ(Wait Start condition ends)

int i2c_stop(){ I2C1CONbits.PEN = 1; while(I2C1CONbits.PEN)

;}

Stopを送信する(Send Stopt condition)

Stop送信が終わるのを待つ(Wait Stop condition ends)

Start コンディション送信用関数(Function for start condition)

Stop コンディション送信用関数(Function for stop condition)

Page 13: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2C通信用関数

int i2c_write(unsigned char data){ I2C1TRN = data; while(I2C1STATbits.TBF) ; i2c_wait_idle(); if( I2C1STATbits.ACKSTAT){ //Ack?? //If NACK received

I2C1CONbits.PEN = 1; //Stop condition while(I2C1CONbits.PEN) ;

return ERR_I2C_SLAVE_NAK; }}

1byte 送信用関数(Function for 1 byte transmission)

送信したいデータをレジスタ(I2C1TRN)に入れる(Copy transmit data into the register “I2C1TRN”)

送信が終わるのを待つ(Wait to finish the data transmission)

スレーブからAckが帰ってきたか確認(Slave returns “ACK”?)

もしNAKなら,スレーブはデータを受け取れていないー>エラーを返す(If “NAK” returns, the slave device didn't receive the data → return error code )

Page 14: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2C通信用関数

int i2c_read(unsigned char *data){ i2c_wait_idle();

I2C1CONbits.RCEN = 1; //Enable the receiver while( ! I2C1STATbits.RBF) ;

i2c_wait_idle();

*data = I2C1RCV;}

1byte 受信用関数(Function for 1 byte receive)

受信動作を開始(Start receiving the data from slave device)

受信が終わるのを待つ(Wait to complete receiving)

受信レジスタのデータを読み込む(Read the data from “I2C1RCV” register)

Page 15: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2C通信用関数(例1)

S Address(0x18) W Data P

Ex.) 0 1 0 1 0 1 1 1

Register address0

0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0

例えば,以下のような通信をしたいときには,以下の関数のような処理をすれば良い.(When you want to send the data as below, the procedure is like below)

int ST_putc(BYTE addr, BYTE reg, BYTE data){ int ret;

if( ret= i2c_start() ) return ret;if( ret= i2c_write( addr | I2C_WR) ) return ret;if( ret= i2c_write( reg ) ) return ret;if( ret= i2c_write( data ) ) return ret;i2c_stop();return 0;

}

Page 16: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

I2C通信用関数(例2)

int ST_getc(BYTE addr, BYTE reg, BYTE* data){int ret;if( ret = i2c_start() ) return ret; if( ret = i2c_write( addr | I2C_WR ) ) return ret;if( ret = i2c_write( reg ) ) return ret;if( ret = i2c_rep_start() ) return ret;if( ret = i2c_write( addr | I2C_RD ) ) return ret;i2c_read(data);i2c_master_nak();i2c_stop();

return 0;

}

S Address(0x18) W

Data P

Sr Address(0x18) RRegister address0

読み込みを終了するときは,マスターはNAKを送信する.(When finish reading the data, master send “NAK”)

Page 17: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

void InitI2C(){ I2C1BRG = 157; //100 kHz @ Fcy = 16MHz I2C1CON = 0x00;

I2C1CONbits.DISSLW = 0; //Slew rate controle(0:enable, 1:disable) I2C1CONbits.I2CEN = 1; //Enable I2C module

}

I2Cジュールの初期化(I2C module initialize)

通信速度の設定(Data transfer rate)

Page 18: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DH用関数

int LIS3DH_is_new_data(){BYTE data;ST_getc(LIS3DH_I2CAddr, LIS3DH_STATUS_REG, &data);if( data | 0x0f){

return (int)data;}else{

return 0;}

}

加速度データが準備できているか調べる(Inquire whether the data is available)

LIS3DH レジスタアドレス(Register address of LIS3DH)

I2Cのアドレス(Register address of I2C)

変数dataに結果を読み込む(read to a variable “data”)

変数dataが0x0fならデータが準備出来ている(If “data=0x0f”, data is available)

詳しくはデータシート参照(Refer the data sheet)

LI3DHデータシートより

この関数は myI2C.cで定義されている.(This function is defined in MyI2C.c)

Page 19: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DHから加速度データを読み出す関数Function to read acceleration

//Return data: short acc[3]int LIS3DH_read_Acc(short acc[]){

void* data;int len;int i, ret;BYTE reg_start;

reg_start = LIS3DH_OUT_X_L;data = acc;Len = 6;

if( ret = i2c_start() ) return ret;

if( ret = i2c_write( LIS3DH_I2CAddr | I2C_WR ) ) return ret;

if( ret = i2c_write( reg_start | 0x80 ) ) return ret;

if( ret = i2c_rep_start() ) return ret;

if( ret = i2c_write( LIS3DH_I2CAddr | I2C_RD ) ) return ret;

//Data readfor(i=0; i<len; i++){

i2c_read( (BYTE*)(data)+i );if(i<len-1){

i2c_master_ack();}else{

i2c_master_nak();}

}

i2c_stop();

return ret;}

レジスタアドレスを設定(Register address setting)

データ受信開始(Start receiving)

Auto increment

1バイト受信(受信後,レジスタアドレスは+1される)(Read 1 byte, Register address will be increment)

Page 20: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DH_read_acc()

//Data readfor(i=0; i<len; i++){

i2c_read( (BYTE*)(data)+i );if(i<len-1){

i2c_master_ack();}else{

i2c_master_nak();}

}

i2c_stop();

return ret;}

short acc[3]

acc[0] acc[1] acc[2]

Address n n+1 n+2 n+3 n+4 n+5

void* data;:

data = acc;

data (ポインタ)が指し示す場所

①1回目(i=0)i2c_read( (BYTE*)(data)+i );

まずは,ここにデータが書き込まれる

Page 21: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

LIS3DH_read_acc()

//Data readfor(i=0; i<len; i++){

i2c_read( (BYTE*)(data)+i );if(i<len-1){

i2c_master_ack();}else{

i2c_master_nak();}

}

i2c_stop();

return ret;}

short acc[3]

acc[0] acc[1] acc[2]

Address n n+1 n+2 n+3 n+4 n+5

void* data;:

data = acc;

data+1 が指し示す場所

②2回目(i=1)i2c_read( (BYTE*)(data)+i );

次に,ここにデータが書き込まれる

これを len(=6)回繰り返すと,acc[3]にすべてデータが書き込まれる.

(注)shortみたいな多バイト変数の場合は,データの詰め込み方に注意(リトル/ビックエンディアン)例えば0x1234の2バイトデータは 0x12,0x34の順にメモリに配置される場合と,0x34, 0x12の順にメモリに配置される場合がある.(今回の場合は後者)LIS3DHからは,Lower Byte, Higher Byteの順で送ってくるので,上のようにしてやればうまく行く

Page 22: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)

加速度センサへの配線(追加分のみ)

PIC24FJ32GA002LIS3DH(モジュール)

GND

1

2

3

4

SCL

SDA

3.3V

2.4k

17

18http://akizukidenshi.com/img/goods/C/K-06791.jpg

LIS3DHモジュールデータシートより

※モジュールは裏面のAとCをはんだ付しておくこと

Page 23: Inter Integrated Circuit 2 ICfreeplanets.ship.jp/Electric/SouzouKougaku/H27/Day4/H27...I2C Inter Integrated Circuit 2線(データとクロック)でIC間の通信を行う.(注,実際にはGNDも必要)