I2C で MCP23017 を接続し、GPIO を追加。I2Cの使用方法を確認する。
構成:
動作確認時の攻勢を上図に示す。
・MCP23017 を I2C で接続。
・A2~A0 は '1' に設定。(デバイスアドレス 0x21)
・GPA7 に スイッチ、GPA0,GPB7 に LED を接続。
I2C 制御方法:
I2C を使用する場合、wire ライブラリを使用する。
主な関数は、
Wire.begin() ; で I2C マスタとして初期化。
Wire.beginTransmission(address); で デバイスに送信開始。
Wire.write(value) ; で データを送信。
Wire.endTransmission() ; で送信終了。
Wire.requestFrom(address, count) ; で デバイスにデータを要求。
Wire.available() ; で受信可能なバイト数を取得。
Wire.read() ; でデータを受信。
I2C のライト/リード手順は、
ライト
1. アクセスするレジスタアドレスを送信。
2. アクセスするデータを送信。
リード
1. アクセスするレジスタアドレスを送信。
2. リード要求を送信。
3. データを受信。
の順に行う。 詳細は、例を参照。
例:スイッチをON したら 2秒毎に LED が交互に点灯し、スイッチ OFF で両方消灯。
/* * i2c_test */ #include <Wire.h> byte MCP23017 = 0x21 ; // slave address byte IODIRA = 0x00 ; // IODIRA Register Address byte IODIRB = 0x01 ; // IODIRB Register Address byte GPPUA = 0x0C ; // GPPUA Register Address byte GPPUB = 0x0D ; // GPPUA Register Address byte GPIOA = 0x12 ; // GPIOA Register Address byte GPIOB = 0x13 ; // GPIOA Register Address void I2C_BWR(byte TGT, byte REGADR, byte DATA) { Wire.beginTransmission(TGT); // transmit to device #TGT Wire.write(REGADR); // send REG address (REGADR) Wire.write(DATA); // send write data (DATA) Wire.endTransmission(); // end transmit } byte I2C_BRD(byte TGT,byte REGADR) { byte data = 0 ; Wire.beginTransmission(TGT); // transmit to device #TGT Wire.write(REGADR); // send REG address (REGADR) Wire.endTransmission(); // end transmit Wire.requestFrom(TGT, 1); // request 1 byte from slave device #TGT data = Wire.read(); // receive 1 byte return data ; } void setup() { byte DATA = 0 ; // for data byte error = 0xff ; Wire.begin(); Serial.begin(115200); // while (!Serial); // Leonardo: wait for serial monitor Serial.println("\nI2C test"); // set direction IOA,IOB I2C_BWR(MCP23017,IODIRA,0xFE) ; // set IOA0 : output I2C_BWR(MCP23017,IODIRB,0x7F) ; // set IOB7 : output I2C_BWR(MCP23017,GPPUA,0x80) ; // set IOA7 : PullUp } void loop() { byte DATA ; DATA = I2C_BRD(MCP23017,GPIOA) ; if ( (DATA & 0x80) == 0x00 ) { I2C_BWR(MCP23017,GPIOA,0x01) ; // set IOA0 = H I2C_BWR(MCP23017,GPIOB,0x00) ; // set IOB7 = L DATA = I2C_BRD(MCP23017,GPIOA) ; Serial.print("REG GPIOA : 0x"); Serial.println(DATA, HEX); DATA = I2C_BRD(MCP23017,GPIOB) ; Serial.print("REG GPIOB : 0x"); Serial.println(DATA, HEX); delay(2000); // wait 2 seconds for next I2C_BWR(MCP23017,GPIOA,0x00) ; // set IOA0 = L I2C_BWR(MCP23017,GPIOB,0x80) ; // set IOB7 = H DATA = I2C_BRD(MCP23017,GPIOA) ; Serial.print("REG GPIOA : 0x"); Serial.println(DATA, HEX); DATA = I2C_BRD(MCP23017,GPIOB) ; Serial.print("REG GPIOB : 0x"); Serial.println(DATA, HEX); delay(2000); // wait 2 seconds for next } else { I2C_BWR(MCP23017,GPIOA,0x00) ; // set IOA0 = L I2C_BWR(MCP23017,GPIOB,0x00) ; // set IOB7 = L delay(4000); // wait 4 seconds for next } }
以下、覚書など。
( 行# 8 )
デバイスのアドレスを定義。
( 行# 9~14 )
各レジスタのアドレスを定義。
( 行# 18,23 )
1バイトライト用の関数。
送信開始 - レジスタアドレス送信 - データ送信 - 送信終了
の順に処理。
( 行# 25,34 )
1バイトリード用の関数。
送信開始 - レジスタアドレス送信 - 送信終了 - データ 1バイト要求 - データ受信
の順に処理。
setup 処理:
( 行# 41 )
I2C マスタとして初期化。
( 行# 49 )
IOA の 入出力を設定。IOA0 を出力に設定。 (他は入力)
( 行# 50 )
IOB の 入出力を設定。IOB7 を出力に設定。 (他は入力)
( 行# 51 )
IOA の プルアップを設定。IOA7 をプルアップ有効に設定。 (他は無効)
Loop処理:
( 行# 59 )
IOA の 状態をリード。
( 行# 60~84 )
スイッチが ON の場合の処理。
"IOA0 を ON, IOB7 を OFF" した後、2秒待って "IOA0 を OFF, IOB7 を ON" して 2秒待つ。 (デバッグ用に シリアルに GPIO の値を表示 )
( 行# 85~88 )
スイッチが OFF の場合の処理。
"IOA0 を OFF, IOB7 を OFF" した後、4秒待つ。
0 件のコメント:
コメントを投稿