PIC12F1840 + I2C MCP23017 16b I/O Expander
Thursday - 20, November, 2014 (7:44 AM) 4 Comments
MCP23017 is a 16b I/O expander with I2C interface, it allows us to control 16 I/O pins independently by using only two pins from the uC using the I2C interface.
Features:
- 16b I/O
- High Speed I2C (Operating voltage)
- 100 KHz (1.8V – 5.5V)
- 400 KHz (2.7V – 5.5V)
- 1.7 MHz (4.5V – 5.5V)
- 3 Hardware address bits allowing up to 8 devices on bus (equivalent to 128 I/O)
- Configurable interrupt output pins (INTA and INTB can be configured to operate independently or together)
- Polarity inversion register
- External reset input
- Output current from one pin: 25mA
Pinout PDIP:
Function block diagram:
The I2C sequences to read or write a register from this device are:
The opcode (OP) is the same it has the device address; 7 bit length composed by the static address plus the physical address of the device (0100 A2 A1 A0) like it is shown below:
The list of registers and addresses are:
For this example we are going to configure both IO Ports to outputs and send some specific data to them so the only registers we need to care about are IODIRx (Direction) and GPIOx (Write and Read) as it is shown below:
The example consist on rotating a led on IOA and IOB will be a mirror of IOA so we must see the some rotation on both ports. There is a delay between rotations of 250mS
/* * Copyright (c) 2011-2014, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************* * By: Omar Gurrola * Company: https://proprojects.wordpress.com * Processor: PIC12 * Compiler: XC8 v1.32 * File Name: main.c * Created On: July 27, 2014, 10:38 AM * Description: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 07/27/14 Initial version *********************************************************************/ /** INCLUDES *******************************************************/ #include "pic12f1840_cbits.h" // Apropiate configuration bits header #include "main.h" #include "pic12f1840_i2c.h" #include "mcp23017.h" /** DEFINES ********************************************************/ /** PROTOTYPES *****************************************************/ #define SetClockTo32Mhz() OSCCONbits.IRCF = 0b1110; OSCCONbits.SPLLEN = 1 void delay_ms(uint16_t); /** GLOBAL VARIABLES ***********************************************/ /** CODE DECLARATIONS ****************************************/ void main(void) { SetClockTo32Mhz(); delay_ms(1000); // Wait for proteus to load simulation i2c_init(I2C_SPEED_STANDARD_100KHZ); mcp23017_init(0b001); // Init MCP23017 with the address 001 mcp23017_write_reg(MCP23017_REG_IODIRA, 0x00); // IOA configure as output mcp23017_write_reg(MCP23017_REG_IODIRB, 0x00); // IOB configure as output for (;;) { uint8_t value; for (uint8_t c = 1; c > 0; c = c << 1){ // Rotate bit mcp23017_write_reg(MCP23017_REG_GPIOA, c); // Write data to IOA value = mcp23017_read_reg(MCP23017_REG_GPIOA); // Read data from IOA mcp23017_write_reg(MCP23017_REG_GPIOB, value); // Write read data to IOB delay_ms(250); // Wait some ms between cycles } } } void delay_ms(uint16_t t_ms) { for (t_ms; t_ms > 0; t_ms--) { for (uint16_t c = 886; c > 0; c--); } }
Below you can see the schematic of the example simulated on proteus.
The circuit was armed on the breadboard and it is working as expected.
Well that’s all for today, happy programming and until next time.
References
- Microchip, “MCP23017/MCP23S17 16-Bit I/O Expander with Serial Interface”, 2007
http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf- I2C Info, “I2C Bus Specification”, 2014
http://i2c.info/i2c-bus-specification- Robot Electronics, “Using the I2C Bus”, 2014
http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html- HobbyTronics.co.uk, “Hi-Tech C I2C Master Example Code”, 07/2014
http://www.hobbytronics.co.uk/hi-tech-c-i2c-master- Adafruit, “Library for the MCP23017 I2C”, 07/2014
https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.cpp
Pingback: PIC12F1840 + I2C 24FC1025 EEPROM | ProProjects
Pingback: PIC12F1840 + I2C DS1307 RTC | ProProjects
Hello. That’s a simple and nice example. Would you mind sharing your project? I’m unable to make the MCP working and get some weird error messages in proteus, sometimes even crashing.
It’s now in my GitHub.