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 件のコメント:
コメントを投稿