Go Down

Topic: PCA 9555 i2C Verständnisfrage! (Read 2439 times) previous topic - next topic

Jan_A

Hi!
Bin relativ neu in der Arduinoprogrammierung, daher entschuldigt bitte meine Unwissenheit!!!
Mit der Suche hatte ich bis jetzt leider keinen Erfolg.

Habe folgende Verständnisfrage: und zwar hab ich diesen Code auf http://www.neufeld.newton.ks.us/electronics/?p=241 im Internet gefunden:

/******************************************************************************
*  i2c_gpio
*  Keith Neufeld
*  May 26, 2008
*
*  Prototype I2C interface to TI 9535 and 9555 GPIO expanders.
*
*  Arduino analog input 5 - I2C SCL
*  Arduino analog input 4 - I2C SDA
*
******************************************************************************/

#include <Wire.h>


//#define DEBUG_GPIO


//  I2C device address is 0 1 0 0   A2 A1 A0
#define DIP_ADDRESS (0x4 << 3 | 0x0)
#define LED_ADDRESS (0x4 << 3 | 0x7)


void setup() {
 
#ifdef DEBUG_GPIO
  Serial.begin(9600);
  //Serial.println(DIP_ADDRESS); delay(2000);
#endif

  Wire.begin();
  gpio_write(LED_ADDRESS, 0xffff);
  gpio_dir(LED_ADDRESS, 0x0000);
}


void loop() {
  int bits;
 
#ifdef DEBUG_GPIO
  Serial.println(0xff & gpio_read(DIP_ADDRESS));
#endif

  bits = gpio_read(DIP_ADDRESS) & 0x0f;
  //  mirror direction of bits for output display
  gpio_write(LED_ADDRESS,
      (
        ((bits & 1) << 3) | ((bits & 2) << 1) |
        ((bits & 4) >> 1) | ((bits & 8) >> 3)
      ) << 12);

#ifdef DEBUG_GPIO
  delay(200);
#endif
}


#define REGISTER_INPUT (0)
#define REGISTER_OUTPUT (2)
#define REGISTER_CONFIG (6)

int gpio_read(int address) {
  int data = 0;
 
  //  Send input register address
  Wire.beginTransmission(address);
  Wire.send(REGISTER_INPUT);
  Wire.endTransmission();
 
  //  Connect to device and request two bytes
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
 
  if (Wire.available()) {
    data = Wire.receive();
  }
  if (Wire.available()) {
    data |= Wire.receive() << 8;
  }
 
  Wire.endTransmission();
 
  return data;
}

void gpio_dir(int address, int dir) {
  //  Send config register address
  Wire.beginTransmission(address);
  Wire.send(REGISTER_CONFIG);
 
  //  Connect to device and send two bytes
  Wire.send(0xff & dir);  //  low byte
  Wire.send(dir >> 8);    //  high byte

  Wire.endTransmission();
}

void gpio_write(int address, int data) {
  //  Send output register address
  Wire.beginTransmission(address);
  Wire.send(REGISTER_OUTPUT);
 
  //  Connect to device and send two bytes
  Wire.send(0xff & data);  //  low byte
  Wire.send(data >> 8);    //  high byte

  Wire.endTransmission();
}


Und zwar geht es um folgenden abschnitt:

1   void gpio_dir(int address, int dir) {
2  //  Send config register address
3   Wire.beginTransmission(address);
4  Wire.send(REGISTER_CONFIG);
5
6  //  Connect to device and send two bytes
7  Wire.send(0xff & dir);  //  low byte
8  Wire.send(dir >> 8);    //  high byte


Vllt kann mir einer erklären was das 0xFF in Zeile 7 zu bedeuten hat!
Kann ich das nicht einfach weglassen???
Wenn ich das richtig verstehe ist doch Byte & 0xFF = Byte!?!?

Schon mal danke im vorraus!
LG Jan


spaceball

Hallo Jan,

ich bin zwar nicht der Arduino Ober-Checker, aber ich probiers mal (falls es jemand besser weiß, bitte korrigieren)  ;)

dir ist als Interger (16 Bit) definiert und kann deshalb mittels 2 Bytes (a 8 Bit) dargestellt werden.
Davon bilden die ersten 8 Bits das "high byte" und die zweiten 8 Bit das "low byte".
Bei I2C werden nun die 2 Byte separat als einzelne Byte gesendet; in diesem Fall eben zuerst das "low byte" und dann das "high byte".
Um nun die 2 separat herauszufiltern, wir die die 2 Bytes mittels "0xFF & " und "dir >>8" aus der integer Zahl "dir" herausgefiltert.
siehe:
http://www.arduino.cc/playground/Code/BitMath

Gruß Reinhard

Jan_A

Hallo Reinhard!

Danke das hilft!!!!
Hab vor nach dem pcf8574 geschaut und da is es nur ein Byte, da hab ich mich dann wohl irgendwie an dem Byte festgebissen!!

Muss zugeben das mich diese ganzen Funktionen like gpio_dir ein bisschen verwirren!
Dann kann ich doch auch schreiben:

void gpio_dir(int address, int dir) {
  //  Send config register address
  Wire.beginTransmission(address);
  Wire.send(REGISTER_CONFIG);

  //  Connect to device and send two bytes
  Wire.send(lowByte(dir));  //  low byte
  Wire.send(highByte(dir));    //  high byte

spaceball

Hallo Jan,
ich hab zwar noch nicht diese Funktion ausprobiert, sollte aber funktionieren .
Gruß Reinhard

Jan_A

Hallo nochmal!!
Könnt nochmal Hilfe gebrauchen!!
Was macht den dieser Abschnitt:

void loop() {
  int bits;

#ifdef DEBUG_GPIO
  Serial.println(0xff & gpio_read(DIP_ADDRESS));
#endif

  bits = gpio_read(DIP_ADDRESS) & 0x0f;
  //  mirror direction of bits for output display
  gpio_write(LED_ADDRESS,
      (
        ((bits & 1) << 3) | ((bits & 2) << 1) |
        ((bits & 4) >> 1) | ((bits & 8) >> 3)
      ) << 12);

#ifdef DEBUG_GPIO
  delay(200);
#endif

Wahrscheinlich is es wieder irgendwas banales, aber ich raffs einfach nicht!!
Was ich rausbekommen hab(wenn ichs richtig verstandn hab) ist das #ifdef was mit dem Präprozessor zu tun hat.
Hab in einem anderen code sowas ähliches gefunden; 

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  gpio_dir(LED_ADDRESS, 0x0000);//set P0  IO output
}

int bits=0;
 
void loop()
{


  bits %=8;

  Serial.println(bits);
  gpio_write(LED_ADDRESS,bits); //write data
  bits++;
  delay(1000);

versteh ich aber genauso wenig.

Vllt hat ja einer Lust mir das zu erklären!?

JAN


Go Up