Quick Microchip I/O Extender question

GDSever

Member
I've been playing around in with a 28x1 and the MCP23008 and MCP23016 chips (in VSM for now), and have been successful getting the I2C bus to read inputs and activate the _INT_ pin when they change... but have been wholly unsuccessful getting the outputs (writes) to work.

Are the outputs on the MCP23016 like a darlington driver IC where it sinks current from the 5V rail, or like an output from a PICAXE where the load is tied between the IC output and the ground rail?

I've tried it both ways, and neither worked - so it is entirely possible I'm missing something in my code too.

Thanks in advance!
 

westaust55

Moderator
Suggest that you post your programs so we can see what you are doing.

Presume that you are setting up the direciton registers for outputs.

From the datasheet:
The IODIR register controls the direction of the pins
(input or output). More specifically, the IODIR registers
simply enables/disables the output driver. When the
driver is activated (IODIR = 0), the pad is driven to the
state in the latch register (OLAT). When deactivated
(IODIR = 1), the driver is high impedance.

I have not used these chips but from the datasheets, but looking at the MCP23008:

IODIR is register $0 controlling direction of each of the 8 bits.
To set bit 0 as an output, you need to write $01 to register $0.

then write to GPIO (register $09) which internally transfers the data to OLAT (register $10)
so writing $01 to Register $09 should bring pin 0 high.



Also have you had a look at this thread by BCJKiwi.
Has a code sample for the MCP230016

http://www.picaxeforum.co.uk/showthread.php?t=8098
 
Last edited:

GDSever

Member
Ack. Sounds like there might be more register config I need to do. I have read the datasheet more than once, but I'm obviously missing something... Right now I am just trying to read several inputs of GP1 and then set corresponding LEDs on GP0 - a very simple I/O test to make sure I understand the I2C commands.

I had looked at the code in that other thread, however BCJKiwi is using the HI2C commands which I am not - I potentially have a DS1307 on the same I2C bus, so I was trying to stick with the lower speed I2C commands. I'll look thru them again and see if I can pull out an extra register config command I missed along the way...

Here is the code I am working with now, which will change if I figure out what I'm doing wrong....
Code:
' MCP23016 registers
Symbol GP0 = $00
Symbol GP1 = $01
Symbol OLAT0 = $02
Symbol OLAT1 = $03
Symbol IPOL0 = $04
Symbol IPOL1 = $05
Symbol IODIR0 = $06
Symbol IODIR1 = $07
Symbol INTCAP0 = $08
Symbol INTCAP1 = $09
Symbol IOCON0 = $0a
Symbol IOCON1 = $0b

' I2C Pins and MCP23016 interrupt trigger
Symbol SDA = pin4
Symbol SCL = pin3
Symbol MCPInt = pin5
Symbol MCPAddr = %01000010

setint %00000000,%00100000  ' Interrupt when input pin 5 goes low

pause 1000        ' wait for MCP23016 to boot

GoSub ConfigureMCP23016

Main:

        sertxd (#b0)
        pause 100
        '
        GoTo Main
        

Interrupt:

    setint %00000000,%00000000  ' Disable our interrupt while we process things
        
    ' Select the MCP23016 chip on the I2C bus
    i2cslave MCPAddr, i2cslow, i2cbyte
    
    ' Read our states from GP1
        i2cread GP1, (b0)
        pause 10
        
        ' Output the state to the first bus
        i2cwrite OLAT0, (b0)
        pause 10
        
        ' Re-enable our interrupt.
        setint %00000000,%00100000  ' Interrupt when input pin 5 goes low

        Return

ConfigureMCP23016:

     ' Select the MCP23016 chip on the I2C bus
    i2cslave MCPAddr, i2cslow, i2cbyte
    
    ' Set GP0 to all writes / outputs ($00), GP1 to all reads / inputs   ($FF)
    i2cwrite IOCON0, (%00000000, %11111111)
    pause 10
    
    ' set a "off" state on everything
    i2cwrite OLAT0, (%00000000, %00000000)
    pause 10
    
    ' Set the interrupt bit to occur when any of the GP1 states change
    i2cwrite INTCAP1, (%11111111)
    pause 10
    
    i2cread GP1, (b0)
    pause 10
        
    Return
 

GDSever

Member
well, one of my problems is definitely using IOCON0 instead of IODIR0... But that wasn't the whole problem.
 

westaust55

Moderator
Have not got much time (and untested) but here is a start:

headers with some comments (in red) to make easier to follow:
Code:
' MCP23016 registers
Symbol GP0 = $00       [COLOR="Red"]; read write here for port 0[/COLOR]
Symbol GP1 = $01       [COLOR="red"]; read write here for port 1[/COLOR]
Symbol OLAT0 = $02
Symbol OLAT1 = $03
Symbol IPOL0 = $04     [COLOR="red"]; polarity for input on GP0 invert if 1[/COLOR]
Symbol IPOL1 = $05     [COLOR="red"]; polarity for input on GP1 invert if 1[/COLOR]
Symbol IODIR0 = $06    [COLOR="red"]; direction register 0[/COLOR]
Symbol IODIR1 = $07    [COLOR="red"]; direction register 1[/COLOR]
Symbol INTCAP0 = $08   [COLOR="red"]; interrupt data capture register for GP0 – read only[/COLOR]
Symbol INTCAP1 = $09   [COLOR="red"]; interrupt data capture register for GP1 – read only[/COLOR]
Symbol IOCON0 = $0a    [COLOR="red"];  Interupt action (bit0=1 for fast sample)[/COLOR]
Symbol IOCON1 = $0b    [COLOR="red"];  just a shadow of IOCON0[/COLOR]
initialise routine: (mods in red)
Code:
ConfigureMCP23016:

     ' Select the MCP23016 chip on the I2C bus
    i2cslave MCPAddr, i2cslow, i2cbyte
    
    ' Set GP0 to all writes / outputs ($00), GP1 to all reads / inputs   ($FF)
    i2cwrite [COLOR="Red"]IODIR0[/COLOR], (%00000000, %11111111) [COLOR="red"]; GP0 =Out GP1=In[/COLOR]
    pause 10
    
    [COLOR="red"]i2cwrite IOCON0, (%00000000)   ; normal sample rate for interrupt[/COLOR]
     pause 10

    ' set a "off" state on outputs
    i2cwrite [COLOR="red"]GP0, (%00000000)[/COLOR]
    pause 10
    
    ' Set the interrupt bit to occur when any of the GP1 states change
    [COLOR="red"][B]; [/B][/COLOR] i2cwrite INTCAP1, (%11111111) [COLOR="red"][B]; cannot write – this is read only[/B][/COLOR]
    pause 10
    
    i2cread GP1, (b0)
    pause 10
    return
 
Last edited:

GDSever

Member
After doing some more reading on the HI2C commands, I realize that they aren't just limited to high speed. I've rewritten the program to use hi2cout and hi2cin, and I like it better - but my PicaxeVSM program is still not setting the outputs on the MCP23016... So I wonder if its a VSM problem.

I'll post something over in that forum and see if anyone has insight.
 
Top