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バイトアクセスに変更。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * 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 件のコメント:

コメントを投稿