Issue
152 March 2003
Using
Rotary Encoders as Input Devices
THE
PCF8574
My
regular suppliers don’t carry Philips Semiconductors
devices; however, this device is now second-sourced
by Texas Instruments. I accidentally discovered this
as I was surfing the ’Net. Several days later, a few
samples of these devices landed on my doorstep courtesy
of the Texas Instruments sample program. As an extra
bonus, they’re available in DIP16 packages (amongst
others), which I find easier to handle.
The
PCF8574 is an 8-bit quasi-bidirectional port expander
(i.e., when a particular line is programmed as a zero,
it can sink up to 50 mA of current). Thus, it can be
used as an output port to drive LEDs. However, when
it’s programmed as a one, this output stage shuts off
and a weak pull-up to VCC remains. In this state, the
line can be used as in input. For example, if the line
is pulled to ground by a switch, the internal input
latch in the device will read a zero. Otherwise, it
will register a one.
The
PCF8574 communicates with the host via the I2C bus,
which is also referred to as the two-wire serial interface
(TWSI). The I2C bus is similar to the older SPI bus,
except that it also sends device addresses along its
data line and does away with the need for device-enable
lines. I won’t try to explain the I2C bus protocol in
this article. The TI PCF8574 application note cited
at the end of this article provides a good explanation.
By
choosing an I2C device to handle the front panel encoders
and switches, you only tie up a few of your microcontroller’s
I/O lines. You can hook up many other useful I2C peripherals
to this bus, too (e.g., flash EEPROM, real-time clock
chips, ADC, and DACs).
I
found the PCF8574’s real selling point to be its interrupt
on port change function, which I mentioned earlier in
reference to PIC microcontrollers. The PCF8574 includes
an exclusive OR block that senses whenever any of its
eight port lines have changed from the state at which
they were last read by the host via the I2C bus. The
change will assert a separate *INT pin on the device.
This
feature is important: the PCF8574 is a slave device
on the I2C bus and, normally, would not be able to notify
the host of a port pin change in a timely manner (i.e.,
the host, as the master device, would have to be constantly
polling the PCF8574 to determine whether or not any
changes had occurred). Often, this isn’t practical.
By including a dedicated *INT line, which can be connected
to the microcontroller’s *INT input, the PCF8574 essentially
provides the interrupt on port change function that’s
available on some microcontrollers but absent on AVR
devices.