Help using the MCP23008
Dr_Acula
Posts: 5,484
I would be most grateful for the forum's collective wisdom using the MCP23008 I/O expander on the I2C bus.
ADDIT - solved post #5
A search on the forum gives this thread http://forums.parallax.com/showthread.php?135052-mcp23008-Sourcing-Voltage
Which finishes with
I was wondering if this author would be able to share the code, or if anyone else has written a driver?
There is a very nice MCP23016 driver in the obex here http://obex.parallax.com/objects/251/
And of course the datasheets http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf for the MCP23008 and http://ww1.microchip.com/downloads/en/DeviceDoc/20090C.pdf for the MCP23016
Please forgive my ignorance though, but my eyes tend to glaze over reading those microchip datasheets Exactly where are the differences highlighted between a MCP23008 and a MCP23016? Anyway... I find reading code tends to be far more useful. I found some C driver code http://rdpartyrobotcdr.sourceforge.net/documentation/_m_c_p23008-driver_8h.html and source code http://rdpartyrobotcdr.sourceforge.net/documentation/_m_c_p23008-driver_8h_source.html
So the Spin code for a MCP23016 is this
And to make things really simple, I don't even want to read pins, only write to pins. So all I really need is
1) Initialise the chip - default hardware address A0-A2 all low, which I think from the C code is #define MCP_I2C_ADDR 0x40 /*!< Default base address (A0-A2 tied to gnd) */
2) Send out a byte to the 8 pins.
3) Send another byte etc
Schematic is very simple - MCP23008 on the same I2C bus as the propeller eeprom.
It is a nice little chip - $1.20 from futurlec.
Any help would be most appreciated
ADDIT - solved post #5
A search on the forum gives this thread http://forums.parallax.com/showthread.php?135052-mcp23008-Sourcing-Voltage
Which finishes with
Well, apologies.. I was being totaly and utterly stupid.. I downloaded the i2c stuff from the object exchange and was using the MCP23016 Lib, which of course has different register addresses.... I was not setting a pin high, i was changing it to an input... how stupid of me!
Maybe to make up for my stupidity I should write a driver specificly for this IC
I was wondering if this author would be able to share the code, or if anyone else has written a driver?
There is a very nice MCP23016 driver in the obex here http://obex.parallax.com/objects/251/
And of course the datasheets http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf for the MCP23008 and http://ww1.microchip.com/downloads/en/DeviceDoc/20090C.pdf for the MCP23016
Please forgive my ignorance though, but my eyes tend to glaze over reading those microchip datasheets Exactly where are the differences highlighted between a MCP23008 and a MCP23016? Anyway... I find reading code tends to be far more useful. I found some C driver code http://rdpartyrobotcdr.sourceforge.net/documentation/_m_c_p23008-driver_8h.html and source code http://rdpartyrobotcdr.sourceforge.net/documentation/_m_c_p23008-driver_8h_source.html
So the Spin code for a MCP23016 is this
PRI MCP23016_Demo | counter, mcpstate, ackbit ' demo the MCP32016 i2c I/O Expander debug.str(string("Init....")) MCP23016Object.WriteIOregister0(i2cSCL,mcp23016addr,%0000_0000) MCP23016Object.WriteIOregister1(i2cSCL,mcp23016addr,%0000_0000) waitcnt(clkfreq*2 + cnt) repeat counter from 0 to 8 debug.str(string("Counting...")) debug.dec(counter) MCP23016Object.writeGP0(i2cSCL,mcp23016addr,counter) MCP23016Object.writeGP1(i2cSCL,mcp23016addr,8-counter) ' read GP0 state mcpState := MCP23016Object.ReadGP0(i2cSCL,mcp23016addr) debug.str(string(" GP0 State: %")) debug.bin(mcpState,8) ' read GP1 state mcpState := MCP23016Object.ReadGP1(i2cSCL,mcp23016addr) debug.str(string(" GP1 State: %")) debug.bin(mcpState,8) debug.putc("%") waitcnt(clkfreq*2+cnt) repeat counter from 0 to 8 debug.str(string("Counting...")) debug.dec(counter) case counter // 3 0 : ' case 0 debug.strln(string("set GP0 High, GP1 Low")) MCP23016Object.WriteGP0(i2cSCL,mcp23016addr,%1111_1111) MCP23016Object.WriteGP1(i2cSCL,mcp23016addr,%0000_0000) 1: ' case 1 debug.strln(string("set GP0 Low, GP1 High")) MCP23016Object.WriteGP0(i2cSCL,mcp23016addr,%0000_0000) MCP23016Object.WriteGP1(i2cSCL,mcp23016addr,%1111_1111) 2: ' case 2 debug.strln(string("set GP0 Low, GP1 Low")) MCP23016Object.WriteGP0(i2cSCL,mcp23016addr,%0000_0000) MCP23016Object.WriteGP1(i2cSCL,mcp23016addr,%0000_0000) ' read GP0 and GP1 state mcpState := MCP23016Object.ReadGP0(i2cSCL,mcp23016addr) debug.str(string("GP0 State: %")) debug.bin(mcpState,8) mcpState := MCP23016Object.ReadGP1(i2cSCL,mcp23016addr) debug.str(string(" GP1 State: %")) debug.bin(mcpState,8) debug.putc(13) waitcnt(clkfreq*2 + cnt)
And to make things really simple, I don't even want to read pins, only write to pins. So all I really need is
1) Initialise the chip - default hardware address A0-A2 all low, which I think from the C code is #define MCP_I2C_ADDR 0x40 /*!< Default base address (A0-A2 tied to gnd) */
2) Send out a byte to the 8 pins.
3) Send another byte etc
Schematic is very simple - MCP23008 on the same I2C bus as the propeller eeprom.
It is a nice little chip - $1.20 from futurlec.
Any help would be most appreciated
Comments
addit - note to myself http://www.nutsvolts.com/index.php?/blog/post/adding_more_digital_i_o_to_your_16_bit_microcontroller_experiments_part_2_t
this is the SPI version but it should be the same as SPI.
I've decided to use one of these chips on my "foot-controller" since it's due for a rebuild so adding input functions will come soon. These chips seem fairly simple in theory and the code seems to agree. Now to test the theory!