Help us understand the problem. What is going on with this article?

第2回 ArduinoによるI2C パラレスインターフェース(GPIO)の操作

第1回でArduino UnoにLucky Shieldをつなぎ、ライブラリ経由でアクセスできました。とはいえ、ライブラリ頼りでは、手を入れるときになにかと不便ですので、ちゃんとインターフェースを調べました。

第1回 Arduinoはじめました
第2回 ArduinoによるI2C パラレスインターフェース(GPIO)の操作

拡張GPIO

Arduinoにはもともとデジタルインターフェースが付いていますが、LEDやJoy stickなど繋ぎたいスイッチを増やすためにI2C GPIOが使われてますね。

CAT9555 I2C バスコントローラ

Lucky sheildのI2C GPIOにはCAT9555がつかわれてます。

device address は "0 1 0 0 A2 A1 A0"で、lucky ではA2 A1 A0='0'なので0x20となります。

コマンド dir レジスタ default
0 read input port 0 0x00
1 read input port 1 0x00
2 write output port 0 0xFF
3 write output port 1 0xFF
4 write Polality Inversion port 0 0x00
5 write Polality Inversion port 1 0x00
6 write Configuration port 0 0xFF 入力
7 write Configuration port 1 0xFF 入力

まず、setup()ではレジスタの6,7に入出力方向をセットする。

setup
#define ADDRESS      (uint8_t)0x20
#define INPUT_PORT0  (uint8_t)0x00
#define OUTPUT_PORT0 (uint8_t)0x02
#define CONFIG_PORT0 (uint8_t)0x06
#define CONFIG_PORT1 (uint8_t)0x07

#define LED1 (uint16_t)0x1000
#define LED2 (uint16_t)0x2000

Wire.beginTransmission(ADDRESS)
// REL2,REL1,LED2,LED1, PIR INT#,ALT INT,MAG INT,ACC_EN
//   O    O    O    O       I        I       I     O
Wire.write(CONFIG_PORT0,0x0E);

// OLED RES#,PB2,PB1, JOYC,R,L,D,U
//   O       I   I     I I I I I
Wire.write(CONFIG_PORT1,0x7F);
Wire.write(OUTPUT_PORT0,0x00);
Wire.endTrasnmission();

I2Cでの書き込み手順はデバイス番号、レジスタ、データと順番に書き込む。

RawWrite_8
// I2Cシーケンス : start,dev(ADDRESS),w,a,reg(INPUT_PORT0),a,stop
Wire.beginTransmission(ADDRESS);
Wire.write(OUTPUT_PORT0);
Wire.write(data);
Wire.endTrasnmission();

ただし、1バイトすべて書き込んでしまう。1ビットだけ変更する場合は、以下の手順を踏む必要がある。

1.レジスタの値を一旦読み出す
2.該当ビットを書き換えた値を作成
3.その値をレジスタに書き出す

I2Cの読み出し手順は、

RawRead_16
//step 1) 読み出しレジスタを0にセット
// I2Cシーケンス : start,dev(ADDRESS),w,a,reg(INPUT_PORT0),a,stop
Wire.beginTransmission(ADDRESS);
Wire.write(INPUT_PORT0);
Wire.endTrasnmission();
// step 2) 2バイトを連続読み出しする
// I2Cシーケンス : start,dev,r,a,1st_byte,a,2nd_byte,nak,stop
Wire.requestFrom(address,(byte)2);
if (Wire.available()) {
    data =Wire.read()<<8;//dataはuint16_t
}    
if (Wire.available()) {
    data |=Wire.read();//2byte目
}    

まとめ

  • setupにて入力、出力をセットする
  • 標準的なI2Cの手順でレジスタにアクセスする
  • ビット書き込みの場合は、先に1バイトreadし、該当ビットを操作した値を書き込む
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away