MCP23S17 - 16-Bit I/O Expander with Serial Interface

Chip Overview

The mbed LPC1768 chip has 26 pins used for digital input and output. All of these pins have other hardware associated with them, so space needed for all-purpose input and output pins can dwindle quickly.

From MCP23S17 datasheet http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf

The MCP23S17 device family provides 16-bit, general purpose parallel I/O expansion for SPI applications. The MCP23X17 consists of multiple 8-bit configuration registers for input, output and polarity selection. The system master can enable the I/Os as either inputs or outputs by writing the I/O configuration bits (IODIRA/B). The data for each input or output is kept in the corresponding input or output register. The polarity of the Input Port register can be inverted with the Polarity Inversion register. All registers can be read by the system master. The 16-bit I/O port functionally consists of two 8-bit ports (PORTA and PORTB). . There are two interrupt pins, INTA and INTB, that can be associated with their respective ports, or can be logically OR’ed together so that both pins will activate if either port causes an interrupt. The interrupt output can be configured to activate under two conditions (mutually exclusive): 1. When any input state differs from its corresponding Input Port register state. This is used to indicate to the system master that an input state has changed. 2. When an input state differs from a preconfigured register value (DEFVAL register). The Interrupt Capture register captures port values at the time of the interrupt, thereby saving the condition that caused the interrupt. The Power-on Reset (POR) sets the registers to their default values and initializes the device state machine. The hardware address pins are used to determine the device address.

Registers

/media/uploads/Shizler/reg_table_.png

Register Descriptions

/media/uploads/Shizler/registers.png

Pinout Guide

From MCP23S17 datasheet http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf /media/uploads/Shizler/chip_pins_.png /media/uploads/Shizler/pinout.png

Wiring guide for demo code

MCP23S17 -> mbed

SI       -> p5
SO       -> p6
SCK      -> p7
CS       -> p20
Vss      -> 3V
Vdd      -> GND
A0       -> GND //A0, A1, A2 of the MCP23S17  are tied to ground on the breadboard, so the 8-bit address for writes is 0x40
A1       -> GND
A2       -> GND

GPA0     -> GPB0 //This will allow testing by writing to A0 from the mbed and then reading B0
             

Program Files

Import programMCP23S17

v 0.4

Sample Code

This code will ensure that the chip is working while giving you some insight into the use of the MCP23S17 class 
and several of the functions within.

This will alternate writing '1' and '0' to PORT_A[0]
PORT_A[0] is hardwired to PORT_B[0]
Therefore, reading in PORT_B[0] and letting that value control an LED on the mbed chip should result in a blinking LED.

This demo code taken from http://developer.mbed.org/users/4180_1/code/MCP23S17_Basic_IO_Demo/

Simple demo

/* MCP23S17 - drive the Microchip MCP23S17 16-bit Port Extender using SPI
* Copyright (c) 2010 Romilly Cocking
* Released under the MIT License: http://mbed.org/license/mit
*
* version 0.4
*/
#include "mbed.h"
#include "MCP23S17.h"
// Create SPI bus
SPI spi(p5, p6, p7);
// 

char Opcode = 0x40;
 
// Next create a MCP23S17
// mbed p20 is connected to ~chipSelect on the MCP23S17
MCP23S17 chip = MCP23S17(spi, p20, Opcode);
 
DigitalOut led1(LED1); // mbed LED1 is used for test status display
 
int main() {
//
//  Set all 8 Port A bits to output direction
    chip.direction(PORT_A, 0x00);
//  Set all 8 Port B bits to input direction
    chip.direction(PORT_B, 0xFF);
    led1=0;
//  Start Loopback test sending out and reading back values
//  loopback test uses A0 and B0 pins - so use a wire to jumper those two pins on MCP23S17 together
    while (1) {
        // write 0xAA to MCP23S17 Port A
        chip.write(PORT_A, 0xAA);
        wait(.5);
        // read back value from MCP23S17 Port B and display B0 on mbed led1
        led1 = chip.read(PORT_B)& 0x01;
        // write 0x55 to MCP23S17 Port A
        chip.write(PORT_A, 0x55);
        wait(.5);
        // read back value from MCP23S17 Port B and display B0 on mbed led1
        led1 = chip.read(PORT_B)& 0x01;
        // led1 should blink slowly when it is all working
    }
}

Class and Function Documentation

Import library

Public Member Functions

MCP23S17 (SPI &spi, PinName ncs, char writeOpcode)
MMCP23S17.
void direction (Port port, char direction)
Pass PORT_A or PORT_B in for port; direction is 8 bit value to set bits in port; '0' - Output, '1' - Input; Updates IODIRA/B.
void configurePullUps (Port port, char offOrOn)
Pass PORT_A or PORT_B in for port; offOrOn is 8 bit value to set bit in port; '1' - Pullup enabled, '0' - Pullup disabled; Updates GPPUA/B.
void interruptEnable (Port port, char interruptsEnabledMask)
Pass PORT_A or PORT_B in for port; interruptsEnabledMask represents 8 bits in the GPINTEN register; each bit that is set to '1', then it is enabled for Interrupt-on-change; NOTE: defaultValue AND interruptControl MUST BE SETUP FOR THIS TO WORK.
void interruptPolarity (Polarity polarity)
polarity is 8-bit value used to update IPOLA/B.
void mirrorInterrupts (bool mirror)
Passing TRUE into this funtion causes an interrupt on either port to cause both pins on both ports to activate; passing in a FALSE causes an interrupt on any port to only activate its respective pin; Updates IOCON[6].
void defaultValue (Port port, char valuesToCompare)
Pass PORT_A or PORT_B in for port; valuesToCompare represents 8 bits in either DEFVAL register; these registers will be used by their respective ports for an interrupt-on-change setting i.e.
void interruptControl (Port port, char interruptContolBits)
Pass PORT_A or PORT_B in for port; interruptContolBits represents 8 bits in INTCON register; '1' - the corresponding I/O pin is compared against the associated bit in the DEFVAL register, '0' - bit value is compared against its previous value.
char read (Port port)
Pass PORT_A or PORT_B in for port; Returns 8 bits from port.
void write (Port port, char byte)
Pass PORT_A or PORT_B in for port; Writes 8 bits of byte to port.

/media/uploads/Shizler/chip.png


Please log in to post comments.