Friday, 21 February 2020
Main Menu
Home Home
Shop Shop
News News
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login


If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News

AN #139 - Using MCP23016 Print
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 (
' 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
= &H40 'Write Adress: 0 1 0 0 A2 A1 A0 0

Dim Mcp23016_adress_r As Byte
= &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.  **


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

= &HFE '0 => Led is "on" FE => 11111110
= &HFE '0 => Led is "on" FE => 11111110

= 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 + 1 ' Increase the counter

Loop Until Counter_1 = 255 ' As long as the counter is not 255 keep writing & rotating

= &HFF '0 => Led is "on" FF => 11111111
= &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
= Msb ' Copy Msb to Lsb
Call I2c_mcp23016_write(&H02 , Lsb , Msb) ' Write Lsb to MCP23016
Wait 1


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