|
|
|
|
|
AN #139 - Using MCP23016 |
|
Small project was made based on the MCP23016 datasheet and App Note AN-245 from MicroChip.
Writen by Roland van Leusden ( his website )
The MCP23016 is a 16 port I2C IO expander |
|
This small project was made based on the MCP23016 datasheet and App Note AN-245 from MicroChip. |
You can find the shematic of the circuit in the
application note, the pcb layout I made is below. The application note
also contains example code for interfacing with a PIC. |
|
Bascom example First showing a "chaser" effect on the leds, then configure 1 port as input and display it on the second port. |
|
From the Microchip website: |
|
The Microchip MCP23016 is a 16-bit input/output
expander designed to provide embedded systems with
general purpose remote I/O expansion through an
I2C™ serial port. The fully bi-directional 16 I/Os default
to inputs and can be configured as inputs or outputs.
Additionally, there are four sets of registers that are
programmable and provide for configuration (input or
output control), output value, and polarity (active low
or high). The MCP23016 open drain interrupt (INT)
output is activated when any input state differs from
its corresponding input port register state. By sending
an interrupt signal on the interrupt logic of the master,
this remote slave device informs the master that
there is incoming data on the port without having to
communicate via the I2C bus. |
- 16-bit I/O port expander with interrupt
- 3 hardware address pins allow user to use up to 8 of these devices on the same I2C/SMBus
- 25mA source/sink capability per I/O
- I2C and SMBus compatible interface (0 to 400kHz clock frequency)
- 16 programmable bi-directional I/Os compatible with most processors
- Outputs can directly drive LEDs (Source and sink current 25mA)
- Polarity inversion register to configure the polarity of the input port data
- Internal power on reset (POR)
- Open-drain interrupt output activated when input changes state
- Low supply current
- Specified over Industrial temperature range -40°C to +85°C
Some downloads :


Here is the sample program :
'**********************************************************************
' Application Note: Using the MCP23016 I/O expander
'-----------------------------------------------------
'
' Program-ID.: AN245 MCP23016.bas.
' Date...... : 22 /
05 / 2005
' Description: Example program for I2C MCP23016 I/O expander
' write and read routines.
'
' Author : Roland
van leusden (sayang@zonnet.nl).
'
' Setup for the AT90S2313 using portd.6 for SDA and
Portd.5 for SCL.
' (Futurlec ET-JRAVR board)
' See AN245 page 9 from Microchip for MCP23016 shematic.
'
' This program provides an example for writing to and
reading from
' an I2C MCP23016 device wired for device 0 (AO,A1 and A2
all pulled
' to Gnd).
'
'
'**********************************************************************
$regfile = "2313def.dat" ' Change for your AVR.
$crystal = 4000000 ' 4 MHz Crystal.
$baud = 19200 ' Output at 19200 baud.
'**********************************************************************
'** Set up Data Direction Registers and ports - Do this
before defining I2C pins!
'**********************************************************************
' Port B
Portb = &B0000_0000 ' Set All Port Pins Low
Ddrb = &B1111_1111 ' Set Unused Pins As Outputs.
' Port D
Portd = &B0000_0000 ' All low - with push-pull output
Ddrd = &B1111_1111 ' with internal pullups.
'**********************************************************************
'** Define and initialize I2C pins **
'**********************************************************************
Config Sda = Portd.6 ' I2C Data.
Config Scl = Portd.5 ' I2C Clock.
'**********************************************************************
'**********************************************************************
'
'** Declare subroutines **
'**********************************************************************
'
' This subroutine writes data to the I2C MCP23016.
'
Declare Sub I2c_mcp23016_write(byval Cmd As Byte , Byval Lsb As Byte , Byval Msb As Byte)
'
' This subroutine reads data from the I2C MCP23016.
'
Declare Sub I2c_mcp23016_read
'**********************************************************************
'** Define working variables and constants **
'**********************************************************************
'
' Change the 3 "AD" bits to reflect the I2C
address of the device
' (corresponding to A0,A1 and A2)..
'
Dim Mcp23016_adress_w As Byte
Mcp23016_adress_w = &H40 'Write Adress: 0 1 0 0 A2 A1 A0 0
Dim Mcp23016_adress_r As Byte
Mcp23016_adress_r = &H41 'Read Adress: 0 1 0 0 A2 A1 A0 1
Dim Counter_1 As Byte
Dim Lsb As Byte
Dim Msb As Byte
'This is for the Microchip MCP23016 initialization, some
examples below
'Call I2c_mcp23016_write(&H04 , &Hff ,
&Hff) 'Invert All Input
Polarities
'Call I2c_mcp23016_write(&H0a , &H01 ,
&H01) 'Initialize Iares , For
Fast Input Scan Mode
'Call I2c_mcp23016_write(&H06 , &H00 ,
&HFF) 'Initiallize It So The
Lsbs Outputs Are & Msbs Are Inputs
'Call I2c_mcp23016_write(&H06 , &Hff ,
&Hff) 'Initiallize It So That
Both Lsbs & Msbs Are Inputs
'Call I2c_mcp23016_write(&H02 , &HFF ,
&HFF) 'Initiallize The Ouput
Latch
'Call I2c_mcp23016_write(&H06 , &H00 ,
&H00) 'Initiallize It So That
Both Lsbs & Msbs Are Outputs
'**********************************************************************
'** Actual work starts here. **
'**********************************************************************
Main:
Waitms 250 ' wait 250 ms for the MCP23016 powerup timer
Call I2c_mcp23016_write(&H02 , &HFF , &HFF) 'Initiallize The Ouput Latch
Call I2c_mcp23016_write(&H06 , &H00 , &H00) 'Initiallize It So That Both Lsbs & Msbs Are Outputs
Lsb = &HFE '0 => Led is "on" FE => 11111110
Msb = &HFE '0 => Led is "on" FE => 11111110
Counter_1 = 0
Do 'Chaser effect
Call I2c_mcp23016_write(&H02 , Lsb , Msb) 'Write Lsb & Msb to MCP23016
Rotate Lsb , Left , 1 'Rotate the bits
Rotate Msb , Left , 1
Waitms 100 'Wait 100ms
Counter_1 = Counter_1 + 1 ' Increase the counter
Loop Until Counter_1 = 255 ' As long as the counter is not 255 keep writing & rotating
Lsb = &HFF '0 => Led is "on" FF => 11111111
Msb = &HFF
Call I2c_mcp23016_write(&H02 , Lsb , Msb) 'All leds off
Call I2c_mcp23016_write(&H06 , &H00 , &HFF) 'Initiallize It So The Lsbs Outputs Are & Msbs Are Inputs
Do 'Read Msb and display on Lsb
Call I2c_mcp23016_read ' Read Msb
Print "Msb: " ; Msb ' Send value of Msb to serial port
Lsb = Msb ' Copy Msb to Lsb
Call I2c_mcp23016_write(&H02 , Lsb , Msb) ' Write Lsb to MCP23016
Wait 1
Loop
End 'end program
'**********************************************************************
'** Define Subroutines **
'**********************************************************************
Sub I2c_mcp23016_write(byval Cmd As Byte , Byval Lsb As Byte , Byval Data2 As Byte)
' Writes data to the I2C MCP23016.
I2cstart 'Generate A Start Condition
I2cwbyte Mcp23016_adress_w 'Transmit The "ADDRESS and WRITE" Byte
I2cwbyte Cmd 'Transmit The Command Byte
I2cwbyte Lsb 'Transmit First Data Byte
I2cwbyte Msb 'Transmit Second Data Byte
I2cstop 'Generate a STOP condition
Waitus 50 'Some delay may be necessary for back to back transmitions
End Sub
Sub I2c_mcp23016_read
' Read data from the I2C MCP23016
I2cstart 'Generate START condition
I2cwbyte Mcp23016_adress_w 'Transmit The "ADDRESS and WRITE" Byte
I2cwbyte &H00 'Transmit The Command Byte
I2cstop 'Generate a STOP condition
I2cstart 'Generate a START condition
I2cwbyte Mcp23016_adress_r 'Transmit ADDRESS
with READ command
I2crbyte Lsb , Ack 'Receive first DATA byte (LSB) and acknowledge
I2crbyte Msb , Nack 'Receive second DATA byte (MSB) and don't acknowledge
I2cstop 'Generate a STOP condition
End Sub
|
|
|
|
|
|
|