wiki:PCAL9555APW

I2C接続 GPIOエクスパンダ PCAL9555APWの使い方

PCAL9555APW I2C GPIOエクスパンダの 使い方の説明と、Arduino向けのサンプルスケッチのページです。

PCAL9555APWは、マイコンとI2C通信によって接続される、汎用I/Oポート拡張モジュールです。

特徴

商品ページより一部抜粋したものを載せます。

  • 動作電圧 1.65V~5.5V
  • 16ポート(8ポート×2グループ)の汎用I/Oのコントロールが可能
  • 各ポートは独立に入力・出力の設定が可能
  • I2C用プルアップ抵抗用のパターンあり(抵抗は未実装)
  • I2Cアドレス設定用はんだジャンパ×3あり
  • ICからの割り込み出力信号あり

使い方

本製品はI2C通信によって制御されます。 下に実体配線図を示します。

本製品にはI2C通信時のプルアップ用抵抗は実装されていません。

ピンヘッダと合わせて各自で実装してください。

プルアップ抵抗は基板裏面のR1とR2に1608サイズの10kΩ程度のチップ抵抗をはんだ付けしてください。

また、ArduinoのWireライブラリを使用する場合は内蔵プルアップが有効になりますので、プルアップ抵抗を省略してもかまいません。

通信方法

デバイスアドレスは、本製品における標準ではArduino向けの7bit表記で0x20です。

これは、基板上のジャンパA0,A1,A2を加工することで変更可能です。 販売時は3つともGND(0のシルク側)に接続されています。

送信

本デバイスには22個のレジスタが存在していますが、2個を1組とした11個の組として動作します。 11個のレジスタ種は後述する機能欄にて簡単に説明します。

デバイスアドレスを送信した後にコマンドバイトを送信します。 このコマンドバイトは、後続のデータをどのレジスタ種が受け取るのかを決定づけます。

レジスタ種間での自動インクリメントは行われません。 ある一つのレジスタにデータを送信した場合、次のデータはペアとなっているもう一つのレジスタに書き込まれます。

例えば、OUTPUT port registor1(コマンドバイト:0x03)にまずデータを送信した場合、 次のデータは、同じOUTPUT port registorであるOUTPUT port registor0(コマンドバイト:0x02)に書き込まれます。

データを書き込み続けると、同じレジスタ種内部でロールオーバーします。

例えば、先述の例に追加して更にデータを書き込むと、書き込み対象のレジスタに相当するコマンドバイトは 0x03->0x02->0x03->...という風にになります。

実際の通信の例を挙げると、このような状態になります。

  1. デバイスアドレス(0x20)送信
  2. OUTPUT port registor1を示すコマンドバイト(0x03)を送信
  3. 1つめのデータ送信
    これは、OUTPUT port registor1(コマンドバイト:0x03)に書き込まれます。
  4. 2つめのデータ送信
    これは、同じOUTPUT port registorであるOUTPUT port registor0(コマンドバイト:0x02)に書き込まれます。
  5. 3つめのデータ送信
    同じレジスタ種内部でロールオーバーします。この場合はOUTPUT port registor1(コマンドバイト:0x03)に書き込まれます。
    4つ目以降のデータも同様に同じレジスタ種内部で繰り返し書き込まれていきます。

受信

読みだす際にも、同様にコマンドバイトを設定する必要があります。

また、送信の時と同様に2個をペアとしたレジスタを読み込みます。

例えば、INPUT port registor1(コマンドバイト:0x01)からデータを読んだ場合、 次は、同じINPUT port registorであるINPUT port registor0(コマンドバイト:0x00)のデータを読みます。

データを読み込み続けると、同じレジスタ種内部でロールオーバーします。

通信を行うときは以上の点について注意する必要があります。

機能

簡単な説明をします。詳細についてはデータシートを参照してください。

INPUTレジスタ(0x00,0x01)

ICのピンの状態が反映されます。これはピンの入出力設定に左右されません。

OUTPUTレジスタ(0x02,0x03)

Configrationレジスタによって出力に設定されたピンは、このレジスタの内容が反映されます。 このレジスタから読みだした内容は、設定内容であり、実際の出力状態ではありません。

Polarity inversionレジスタ(0x04,0x05)

1にセットされたビットに対応するピンに関して、入力に設定されたピンの状態を反転してINPUTレジスタに反映させます。

Configurationレジスタ(0x06,0x07)

1にセットされたビットに対応するピンをハイインピーダンス入力に設定します。 0にセットした場合は出力です。

Output drive strengthレジスタ(0x40,0x41,0x42,0x43)

1ポートあたり2ビットの設定があります。出力に設定されたピンをドライブするために利用する回路の数を変更します。

Input latchレジスタ(0x44,0x45)

指定した入力ピンの状態変化を割り込みピンに反映させたり、INPUTレジスタに反映させたりします。

Pull-up/pull-down enable(0x46,0x47)

各ピンに対してプルアップ・プルダウンの有効・無効設定をします。

Pull-up/pull-down selection(0x48,0x49)

プルアップ・プルダウンが有効なピンに対して、プルアップかプルダウンを設定します。

Interrupt maskレジスタ(0x4A,0x4B)

割り込みを検出するかどうかの設定です。

Interrupt statusレジスタ(0x4C,0x4D)

割り込みが検出されたかどうかの状態を示します。

Output port configurationレジスタ(0x4F)

出力に設定されたポート(0,1ごと)に対して、オープンドレイン回路を利用するかプッシュプル回路を利用するかを設定します。

サンプルプログラム

PORT0,1の状態をArduinoIDEのシリアルモニタに表示し続けます。(GitHub)

/*******************************************************************************
// SWITCHSCIENCE wiki -- http://trac.switch-science.com/
// PCAL9555APW Arduino Sample
*******************************************************************************/
#include <Wire.h>

#define PCAL9555APW_ADDR 0x20 // in 7bit for Arduino

#define INPUT_REG     0x00
#define OUTPUT_REG    0x02
#define INVERS_REG    0x04
#define CONFIG_REG    0x06
#define OUTPUT_DRIVE  0x40
#define INPUT_LATCH   0x44
#define PULLUP_EN     0x46
#define PULLUP_SEL    0x48
#define INTRRPT_MASK  0x4A
#define INTRRPT_STAT  0x4C
#define OUTPUT_CONFIG 0x4F


void datasend(int,int,int *,int);
void dataread(int,int,int *,int);

void setup()
{
  Serial.begin(9600);
  Wire.begin();
}

void loop()
{
  int port_input[2]; //入力状態を取得する変数
  dataread(PCAL9555APW_ADDR, INPUT_REG, port_input, 2);
  Serial.print("port0:");
  Serial.print(port_input[0], BIN);
  Serial.print("\tport1:");
  Serial.println(port_input[1], BIN);
}

void datasend(int id,int reg,int *data,int datasize)
{
  Wire.beginTransmission(id);
  Wire.write(reg);
  for(int i=0;i<datasize;i++)
  {
    Wire.write(data[i]);
  }
  Wire.endTransmission();
}

void dataread(int id,int reg,int *data,int datasize)
{
  Wire.beginTransmission(id);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(id, datasize, false);
  for(int i=0;i<datasize;i++)
  {
    data[i] = Wire.read();
  }
  Wire.endTransmission(true);
}
Last modified 18 months ago Last modified on Feb 17, 2016 10:08:50 AM

Attachments (2)

Download all attachments as: .zip