Parts: 8bit IO Expander (PCF8574)
posted Dec 27th 2008 12:00am by Ianfiled under: parts, tool hacks

Sometimes a project has more sensors, buttons, or LEDs than your microcontroller has pins. The PCF8574 is an easy way to add 8 low-speed input or output pins to a microcontroller. A configurable address lets multiple PCF8574s exist on the same bus, so two microcontroller pins can control dozens of IO pins. We’ll show you how to use this chip below.

TI PCF8574 I2C 8bit IO expander (Mouser #595-PCF8574N, $1.86)
We found PCB footprints for this chip in i2c.lbr and micro-phillips.lbr on the Cadsoft Eagle library download page. The PCF8574 is controlled with the 2 wire I2C protocol, so we used our Bus Pirate universal serial interface to demonstrate this chip. The same basic operations will apply to any microcontroller.
The schematic shows our simple test circuit for the PCF8574, here’s the datasheet (PDF). We powered the chip with 5volts, and used a 0.1uF decoupling capacitor (C1) between the power and ground pins. R1 and R2 hold the I2C clock and data bus at 5volts. We’ll use an LED to test the chip’s output features; P0 is connected to LED1 through current limiting resistor R3 (330+ ohms). P6 and P7 are tied to known states so we can easily test the chip’s input capabilities.
The PCF8574’s I2C address is 0100xxxy, with three bits (x) determined by the state of the address pins A2-0, and a final bit (y) that sets the read (1) or write (0) mode. Many PFC8574s can share an I2C bus by using different address pin settings. Since we tied the address pins to ground, the write address is 01000000 (0×40).
Output
The LED on P0 is controlled by writing a 1 (on) or 0 (off) to bit 0 of the byte following the write address.
I2C>{0×40 0b00000001} <–command
210 I2C START CONDITION
220 I2C WRITE: 0×40 GOT ACK: YES<–write address
220 I2C WRITE: 0×01 GOT ACK: YES<–output value
240 I2C STOP CONDITION
I2C>
{ issues an I2C start condition, followed by the write address, 0×40. The output value, 0b00000001, sets P0 high and the remaining bits low. } sends the I2C bus stop condition, ending the transaction. When the corresponding bit is set high, the LED turns on.
To turn the LED off, repeat the sequence with the corresponding output bit set to 0.
I2C>{0×40 0b00000000}<–command
210 I2C START CONDITION
220 I2C WRITE: 0×40 GOT ACK: YES<–write address
220 I2C WRITE: 0×00 GOT ACK: YES<–output value
240 I2C STOP CONDITION
I2C>
With P0 now set to ground, the LED turns off.
Input
Pins set to output high can also be used as inputs (datasheet page 1). In the example, P6 is held high (+5 volts) and P7 is held low (ground), but these could also be buttons, sensors, or other digital logic. The other pins are left floating and don’t represent valid data.
I2C>{0×40 0b11000000}<–command
210 I2C START CONDITION
220 I2C WRITE: 0×40 GOT ACK: YES<–write address
220 I2C WRITE: 0xC0 GOT ACK: YES<–output value
240 I2C STOP CONDITION
I2C>
First, we set the desired input pins to output high by writing 1 to the corresponding bits in the output value. Bits 6 and 7 set P6 and P7 to output high.
Now, we can read the pin. We did this operation with the Bus Pirate’s output set to binary mode so that the pin values are immediately obvious.
I2C>{0×41 r}<–command
210 I2C START CONDITION
220 I2C WRITE: 0b01000001 GOT ACK: YES<–address
230 I2C READ: 0b01000000<–pin state
240 I2C STOP CONDITION
I2C>
{ issues an I2C start condition, 0×41 is the read address, and r reads one byte from the device. } sends the I2C bus stop condition, ending the transaction.
The reply, 01000000, represents the state of the input pins. The most significant bit is 0 because P7 is tied to ground. The next bit is 1 because P6 is held high The other bits (0) are garbage data.
This is far from the only IO expander IC. Have you used another chip?
Don’t forget to catch up on any parts posts you may have missed.





That’s an interesting IC, but I question its usefulness, when something like a PIC18F25J10 is $2.08 on mouser. With something like that, not only do you get 21 high speed gpios (vs the 8 this ic provides), but you can do processing on the input, which can make your life a lot easier, especially if the data is time-sensitive.
So, meh. For another $0.22, I’d rather get that.
Posted at 12:50 am on Dec 27th, 2008 by hex4def6