![Image](http://www.matrixmultimedia.com/images/Article_NoStudent.png)
Many microcontrollers are now available with huge numbers of I/O pins. The drawback for most people is that they are only available in unusable surface mount packages. So the 40-pin, 4 x 8-bit port maximum limit still applies. Multiplexing circuits can be used to share I/O lines between multiple signals, but the I/O characteristics of the multiplexers are generally inferior to those of the microcontroller, and the inter-wiring can become complicated.
Microchip have developed two I/O expander chips that can each add 16 I/O lines to an application, using a synchronous serial bus to communicate with the microcontroller. The MCP23017 (I2C/TWI bus) and MCP23S17 (SPI bus) require only 2 (SCL + SDA) or 4 (SDO + SDI + SCK + /CS) signal wires respectively to connect to the microcontroller. They also have a 3-bit external addressing facility (A0, A1, A2) that allows up to 8 devices, supplying 128 I/O lines, to share a single bus connection without any special arrangements (each with one of the 8 possible configurations of A2, A1, A0).
![Image](http://www.matrixmultimedia.com/images/Article_Bus_Img.bmp)
A disadvantage of this approach is that access to the expansion I/O is slower than that of the microcontroller - which has now been freed for the high speed operations. The fastest version of the device is the SPI bus (4-wire) MCP23S17 which requires the transfer of 3 data bytes to randomly access any one of its registers. Even with the maximum10MHz bus clock it will take several microseconds to read each port. This should still be adequate for the majority of I/O operations with signal frequencies of 100KHz or less.
As an alternative to polling the I/O expanders for input values, they can be configured to generate interrupts (requiring additional connections to the microcontroller) when change events occur, and to capture the I/O state at the instant the interrupt occurred, allowing the information to be retained until the microcontroller is able to retrieve it. For these operations each device can be treated as two 8-bit ports, or a single 16-bit port.
The expander ports provide most of the features expected from any microcontroller port: 25mA current source and sink, programmable pull-up resistors, interrupt-on-change mask registers, etc.
The device register address can be configured in one of two selectable maps. The chip can be programmed to allocate a separate block of addresses to the registers of each port. The default map, used in the example programs, has the registers of each port interleaved.
The example programs - one for I2C, the other for SPI - configure a single expander device with all Port A pins as inputs, and all Port B pins as outputs. The main program loop then polls the expander Port A every 100ms and sends the data out to the expander Port B.
The existing Flowcode SPI and I2Ccomponents include all the functions necessary to communicate with the I/O expanders at a byte level. The macros in the programs tidy-up the multi-byte communication processes and provide a simple 'address + data' interface to the main program, for any expander register, in read or write mode.
![Image](http://www.matrixmultimedia.com/images/Article_Reg_Table.bmp)