PCA 9555 i2C Verständnisfrage!

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

Hallo Jan,

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

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

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

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

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