2018年12月14日金曜日

ESP32/arduino:I2CでMCP23017を接続_2

目的:
MCP23017 へのアクセスを 2バイト単位で行う。

内容:
2バイトアクセス用の関数を追加する。
ライト時、
 Wire.write((byte *)data,length) ; で データを送信。
リード時、
 Wire.requestFrom(address, count) ; で coount を 2 にしてデータを要求し、
 Wire.read() ; で2回 データを受信。

例:
前回「ESP32/arduino:I2CでMCP23017を接続」のアクセスの一部を2バイトアクセスに変更。

/*
 * 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 I2C_2BWR(byte TGT, byte REGADR, short DATA) {
  Wire.beginTransmission(TGT);         // transmit to device #TGT 
  Wire.write(REGADR);                  // send REG address (REGADR)
  Wire.write((byte *)&DATA,2);         // send write data (DATA)
  Wire.endTransmission();              // end transmit
}

short I2C_2BRD(byte TGT,byte REGADR) {
  byte data[2] ;
  Wire.beginTransmission(TGT);         //  transmit to device #TGT
  Wire.write(REGADR);                  //  send REG address (REGADR)
  Wire.endTransmission();              //  end transmit
  Wire.requestFrom(TGT, 2);            // request 1 byte from slave device #TGT
  data[0] = Wire.read();                  // receive 1 byte 
  data[1] = Wire.read();                  // receive 1 byte 
  
  return *(short *)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 ;
  unsigned short DT2 ;

  DATA = I2C_BRD(MCP23017,GPIOA) ;
  if ( (DATA & 0x80) == 0x00 ) {
    I2C_2BWR(MCP23017,GPIOA,0x0001) ;

    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);
    DT2 = I2C_2BRD(MCP23017,GPIOA) ;
    Serial.print("REG GPIO : 0x");
    Serial.println(DT2, HEX);
    Serial.println("");

    delay(2000);           // wait 2 seconds for next

    I2C_2BWR(MCP23017,GPIOA,0x8000) ;

    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);
    DT2 = I2C_2BRD(MCP23017,GPIOA) ;
    Serial.print("REG GPIO : 0x");
    Serial.println(DT2, HEX);
    Serial.println("");

    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
  }    
}

以下、覚書など。
  ( 行# 36~41 )
2バイトアクセス用ライト関数。
ショートバイトで受け取ったデータのポインタを バイトデータのポインタをとして
Wire.write() に与える。 length は 2

  ( 行# 43~53 )
2バイトアクセス用リード関数。
Wire.requestFrom(address, count) ; の count を 2 で実行後、2回 Wire.read() を実行。

 ( 行# 81,96 )
2バイトライト実行。
ライトデータは、
[15:8] に IOB (アドレス ***1),
[7:0] に IOA(アドレス ***0)
の値をセット。

  ( 行# 89~92, 104~107 )
2バイトリード実行。
シリアルモニタに出力。


0 件のコメント:

コメントを投稿