G2020_MCP23017_I/Oエキスパンダー

20241214

15:49

G2020_lpc812_MCP23017_io_expander_report

 

 LPC共通関数_解凍してLPCフォルダに

 

 

16bit I2C I/Oエキスパンダー MCP23017: 半導体 秋月電子通商-電子部品・ネット通販

 

 

 3.5.1 I/O DIRECTION REGISTER

 

データ I/O の方向を制御します。

 ビットが設定されると、対応するピンは

 入力。ビットがクリアされると、対応するピンが

 出力になります

 

3.5.2 INPUT POLARITY REGISTER

 

このレジスタを使用すると、ユーザーは極性を設定できます。

 対応する GPIO ポート ビット。

 ビットが設定されている場合、対応する GPIO レジスタ ビットは

 反転した値をピンに反映します。

 

IP<7:0>: 入力ピンの極性反転を制御します<7:0>

 1 = GPIO レジスタ ビットは、入力ピンの反対の論理状態を反映します。

 0 = GPIO レジスタ ビットは入力ピンと同じ論理状態を反映します。

 

3.5.3  INTERRUPT-ON-CHANGE  CONTROL REGISTER

 

各ピンの変更時割り込み機能。

 ビットが設定されている場合、対応するピンが有効になります。

 変更時の割り込み。 DEFVAL INTCON

 ピンが存在する場合は、レジスタも設定する必要があります。

 変更時割り込みが有効

GPINT<7:0>: 汎用 I/O 変化時割り込みビット <7:0>

 1 = 変化時割り込みイベントの GPIO 入力ピンを有効にします。

 0 = 変化時割り込みイベントの GPIO 入力ピンを無効にします。

 

3.5.4  DEFAULT COMPARE REGISTER  FOR INTERRUPT-ON-CHANGE

 

デフォルトの比較値は、

 DEFVALレジスタ。有効な場合 (GPINTEN および

 INTCON) を使用して DEFVAL レジスタと比較します。

 関連するピンの反対の値により、

 割り込みが発生する

DEF<7:0>: デフォルトからの変更時割り込み用に構成されたピンの比較値を設定します <7:0>

(1)

 関連するピンのレベルがレジスタ ビットと逆の場合、割り込みが発生します。 (2)

  1: INTCON を参照してください。

 2: INTCON および GPINTEN を参照

 

 3.5.5   INTERRUPT CONTROL REGISTER

INTCON レジスタは、関連するピンの接続方法を制御します。

 値は変更時割り込み機能で比較されます。

 ビットが設定されている場合、対応する I/O ピンが比較されます

 DEFVAL レジスタ内の関連するビットに対して。もし

 ビット値がクリアされている場合、対応する I/O ピンが比較されます

 以前の値に対して。

IOC<7:0>: 変更時割り込み <7:0> に関して関連するピン値を比較する方法を制御します。

 1 = ピンの値が DEFVAL レジスタの関連ビットと比較されます。

 0 = ピン値が前のピン値と比較されます。

 

 3.5.6   CONFIGURATION REGISTER

IOCON レジスタには、次のようないくつかのビットが含まれています。

 デバイスの構成:

 BANK ビットはレジスタのマッピング方法を変更します

 (詳細については、表 3-4 および 3-5 を参照してください)

  BANK = 1 の場合、各レジスタに関連付けられている

ポートは分離されています。に関連付けられたレジスタ

PORTA はアドレス 00h 0Ah にマッピングされ、

PORTBに関連付けられたレジスタがマップされます

10hから0Ahまで。

  BANK = 0 の場合、A/B レジスタはペアになります。のために

たとえば、IODIRA はアドレス 00h にマップされ、

IODIRB は次のアドレス (アドレス

01h)。すべてのレジスタのマッピングは 00h 15h です。

 BANK ビットを変更するときは注意が必要です

 バイトが変更された後にアドレスマッピングが変更されるため、

 デバイスに記録されます。アドレスポインタが指す場合があります

 ビットが変更された後、無効な位置にコピーされます。

 たとえば、デバイスが次のように構成されている場合、

 内部アドレス ポインタを自動的にインクリメントします。

 次のようなシナリオが発生します。

 • バンク = 0

 • アドレス 0Ah (IOCON) 80h を書き込み、

バンクビット

 • 書き込みが完了すると、内部アドレスが

現在、無効なアドレスである 0Bh を指しています。

BANKビットがセットされている場合

 

このため、BANKビットを変更する場合は、

 このレジスタへのバイト書き込みのみを実行することをお勧めします。

 MIRROR ビットは、INTA ピンと INTB ピンの制御方法を制御します。

 相互に機能します。

  MIRROR = 1 の場合、INTn ピンは機能します。

OR をとります。これにより、どちらかのポートでの割り込みが発生します。

両方のピンをアクティブにします。

  MIRROR = 0 の場合、INT ピンは分離されます。

ポート上の割り込み条件により、

それぞれの INT ピンをアクティブにします。

 シーケンシャル オペレーション (SEQOP) は、

 アドレスポインタのインクリメント関数。もし

 アドレス ポインタが無効になっている場合、アドレス ポインタは無効になります。

 各バイトがクロックされた後に自動的にインクリメントされない

 シリアル転送中。この機能はこんなときに便利です

 継続的にポーリング (読み取り) または変更 (書き込み) する必要がある

 登録する。

 スルー レート (DISSSLW) ビットはスルー レートを制御します

 SDA ピンの機能。有効な場合、SDA スルー レート

 高から低まで走行するときに制御されます。

 ハードウェア アドレス イネーブル (HAEN) ビット

 上のハードウェア アドレス指定を有効/無効にします。

 MCP23S17のみ。アドレスピン (A2A1A0)

 HAEN ビットに関係なく、外部からバイアスする必要があります

 価値。

 有効 (HAEN = 1) の場合、デバイスのハードウェア アドレス

 アドレスピンと一致します。

 無効 (HAEN = 0) の場合、デバイスのハードウェア アドレス

 A2 = A1 = A0 = 0

 

オープンドレイン (ODR) 制御ビットは、

 オープンドレイン構成の INT ピン。このビットを設定する

 INTPOL ビットをオーバーライドします。

 

 割り込み極性 (INTPOL) は、割り込みの極性を設定します。

 INTピン。このビットは、ODR ビットがオンの場合にのみ機能します。

 クリアされ、INT ピンがアクティブ プッシュプルとして設定されます。

 

ビット7

 BANK: レジスターのアドレス指定方法を制御します。

 1 = 各ポートに関連付けられたレジスタは異なるバンクに分離されます。

 0 = レジスタは同じバンク内にあります (アドレスは連続しています)

 

ビット6

MIRROR: INT ピン ミラー ビット

 1 = INT ピンは内部接続されています

 0 = INT ピンは接続されていません。 INTA PORTA に関連付けられ、INTB PORTA に関連付けられます。

ポートB

 

ビット5

 SEQOP: シーケンシャル動作モードビット

 1 = シーケンシャル操作が無効になり、アドレス ポインタはインクリメントされません。

 0 = シーケンシャル操作が有効、アドレス ポインタがインクリメントされます。

 

 ビット4

 DISSLW: SDA 出力のスルーレート制御ビット

 1 = スルーレートが無効

 0 = スルーレートが有効

 

 ビット3

 HAEN: ハードウェア アドレス イネーブル ビット (MCP23S17 のみ) ( 1)

 1 = MCP23S17 アドレス ピンを有効にします。

 0 = MCP23S17 アドレス ピンを無効にします。

 

 ビット2

 ODR: INT ピンをオープンドレイン出力として設定します。

 1 = オープンドレイン出力 (INTPOL ビットをオーバーライドします。)

 0 = アクティブドライバー出力 (INTPOL ビットが極性を設定します。)

 

 ビット1

 INTPOL: このビットは INT 出力ピンの極性を設定します。

 1 = アクティブハイ

 0 = アクティブロー

 

 ビット0

 未実装: 0」として読み取られます。

 

 3.5.7  PULL-UP RESISTOR  CONFIGURATION REGISTER

GPPU レジスタは、

 ポートピン。ビットが設定されており、対応するピンが

 入力として設定されている場合、対応するポート ピンは

 100kΩの抵抗で内部プルアップ

 

 

PU<7:0> 各ピンの弱いプルアップ抵抗を制御します (入力として構成されている場合)

 1 = プルアップが有効

 0 = プルアップは無効

 

 3.5.8   INTERRUPT FLAG REGISTER

 

INTF レジスタは、割り込み条件を反映します。

 を介して割り込みが有効になっているピンのポート ピン

 GPINTEN レジスター。セットされたビットは、

 関連するピンにより割り込みが発生しました。

 このレジスタは読み取り専用です。このレジスタへの書き込みは、

 無視されました

INT<7:0>: ポートの割り込み条件を反映します。割り込みが発生した場合にのみ変更が反映されます。

GPINTEN<7:0> に従って有効になります。

 1 = ピンによって割り込みが発生しました。

 0 = 割り込みは保留されていません

 

 3.5.9   INTERRUPT CAPTURED REGISTER

INTCAP レジスタは、GPIO ポート値をキャプチャします。

 割り込みが発生した時刻。レジスターは

 読み取り専用で、割り込みが発生した場合にのみ更新されます。

 が発生します。レジスタは、

 割り込みはINTCAPまたはGPIOの読み取りによってクリアされます。

 

ICP<7:0>: ピン変化による割り込み時のポート ピンのロジック レベルを反映します<7:0>

 1 = ロジックハイ

 0 = ロジックロー

 

 3.5.10   PORT REGISTER

 

GPIO レジスタはポートの値を反映します。

 このレジスタから読み取ると、ポートが読み取られます。これに書き込む

 register は出力ラッチ (OLAT) レジスタを変更します。

 

GP<7:0>: ピン <7:0> のロジック レベルを反映します。

 1 = ロジックハイ

 0 = ロジックロー

 

3.5.11   出力ラッチレジスタ (OLAT)

 

OLAT レジスタは出力へのアクセスを提供します。

 ラッチ。このレジスタから読み出すと、

 OLAT であり、ポート自体ではありません。このレジスタへの書き込み

 ピンを変更する出力ラッチを変更します。

 出力として設定される

 

OL<7:0>: 出力ラッチ <7:0> のロジック レベルを反映します。

 1 = ロジックハイ

 0 = ロジックロー

 

 

 

 

アドレス調査

 

 

 

A0

A1

A2

I2Cアドレス

 

0

0

0

0x40

 

1

0

0

0x42

 

0

1

0

0x44

 

1

1

0

0x46

 

0

0

1

0x48

 

1

0

1

0x4A

 

0

1

1

0x4C

 

1

1

1

0x4E

 

 

 

入力定義

 

 

入力関数のコード

 

 

 

 

// MPC32017 全入力初期設定

void        MCP23017_inp_init(uint8_t prm_bnk)

{

// prm_bnk 0-7

uint8_t buf_max = 16;

char snd_buf[16+2];

char rcv_buf[16+2];

uint32_t i2c_err;

uint8_t i2c_add;

 

if(Exp_23017_dat_max-1 < prm_bnk) return;        // バンクオーバーフロー

i2c_add = Exp_23017_add_tbl[prm_bnk/2];

if(i2c_add == 0) return; // アドレス未定義

 

if((prm_bnk % 2) == 0)

{

snd_buf[0] = 0x00;        // 入出力選択A

snd_buf[1] = 0xFF;        // 全点入力

i2c_err = LPC_i2c_snd_rcv(i2c_add,2,0,snd_buf,rcv_buf,buf_max);

if(i2c_err != 0) LPC_i2c_msg("A POL SET",i2c_err);

//lpc812_i2c_snd(prm_i2c_add,2,"A POL SET");

 

snd_buf[0] = 0x0C;        // 入力PULLUP

snd_buf[1] = 0xFF;

i2c_err = LPC_i2c_snd_rcv(i2c_add,2,0,snd_buf,rcv_buf,buf_max);

if(i2c_err != 0) LPC_i2c_msg("A PULLUP",i2c_err);

//lpc812_i2c_snd(prm_i2c_add,2,"A PULLUP");

}

else

{

snd_buf[0] = 0x01;        // 入出力選択B

snd_buf[1] = 0xFF;        // 全点入力

i2c_err = LPC_i2c_snd_rcv(i2c_add,2,0,snd_buf,rcv_buf,buf_max);

if(i2c_err != 0) LPC_i2c_msg("B POL SET",i2c_err);

//lpc812_i2c_snd(prm_i2c_add,2,"B POL SET");

 

snd_buf[0] = 0x0D;        // 入力PULLUP

snd_buf[1] = 0xFF;

i2c_err = LPC_i2c_snd_rcv(i2c_add,2,0,snd_buf,rcv_buf,buf_max);

if(i2c_err != 0) LPC_i2c_msg("B PULLUP",i2c_err);

//lpc812_i2c_snd(prm_i2c_add,2,"B PULLUP");

 

}

}

 

//        I/O エクスパンダ 全入力

void        MCP23017_red(uint8_t prm_bnk)

{

uint8_t buf_max = 16;

char snd_buf[16+2];

char rcv_buf[16+2];

uint32_t i2c_err = 99;

uint8_t i2c_add;

 

// prm_bnk 0-7

if(Exp_23017_dat_max-1 < prm_bnk) return;        // バンクオーバーフロー

i2c_add = Exp_23017_add_tbl[prm_bnk/2];

if(i2c_add == 0) return; // アドレス未定義

 

Exp_23017_dat[prm_bnk] = 0;                // 初期化

 

if((prm_bnk % 2) == 0)

{

snd_buf[0] = 0x12;

snd_buf[1] = 0x00;

i2c_err = LPC_i2c_snd_rcv(i2c_add,1,1,snd_buf,rcv_buf,buf_max);

}

else

{

snd_buf[0] = 0x13;

snd_buf[1] = 0x00;

i2c_err = LPC_i2c_snd_rcv(i2c_add,1,1,snd_buf,rcv_buf,buf_max);

}

 

if(i2c_err == 0)

Exp_23017_dat[prm_bnk] = (~rcv_buf[0]) & 0xFF;

else

LPC_i2c_msg("A INPUT",i2c_err);

 

}

 

//////////////////////////////////////

//        バンク単位のビット判定 (入力)

//////////////////////////////////////

uint8_t        MCP23017_bit_chk(

uint8_t prm_bnk,                // 0-7

uint8_t prm_chk_bit)        // 0-7

{

uint32_t        chk_dat = (1<<prm_chk_bit);

if((Exp_23017_dat[prm_bnk] & chk_dat) == chk_dat) return(1); else return(0);

}

 

 

プロジェクトの説明、入力テスト

 

 

uint8_t old_dat[8+1];

uint8_t i;

 

    // 誤動作防止のため、実装されていないバンクはアドレスゼロ設定必要

    Exp_23017_add_tbl[0] = 0x40;

    Exp_23017_add_tbl[1] = 0;

    Exp_23017_add_tbl[2] = 0;

    Exp_23017_add_tbl[3] = 0;

 

 

 

    // 16ビットすべて入力に設定する

    MCP23017_inp_init(0);        // バンク単位入力設定

    MCP23017_inp_init(1);        // バンク単位入力設定

 

    // 前回データの更新

    MCP23017_red(0); old_dat[0] = Exp_23017_dat[0];

    MCP23017_red(1); old_dat[1] = Exp_23017_dat[1];

 

MCP23017_red(0);        // バンク0 読み込み

MCP23017_red(1);        // バンク1 読み込み

 

if(old_dat[0] != Exp_23017_dat[0] || old_dat[1] != Exp_23017_dat[1])

{

// 変化がありました

UART_puts("PA (");

for(i=0;i<8;i++) UART_msg_dec("",MCP23017_bit_chk(0,i)," ");

UART_puts(")  PB (");

for(i=0;i<8;i++) UART_msg_dec("",MCP23017_bit_chk(1,i)," ");

UART_puts(")\r\n");

 

// 前回値更新

old_dat[0] = Exp_23017_dat[0];

old_dat[1] = Exp_23017_dat[1];

}

 

実験結果

 

 

 

 

処理速度を測ります