How to control a MCP23017 16 bit I/O Extender?

erdc

Member
Now that I can successfully control a PCF8574, does anyone know how to control the 16 I/O MCP23017 chip? I have a project that would need either 12 PCF8574, or just six MCP23017 ICs. But this chip allows you to operate it in a two bank mode, so it is not as straight forward as the PCF8574 is.

I would like GPA ports to be outputs, and the GPB ports to be inputs. I did a search on this and it seems to take a form of;

i2cslave %01001100, i2cfast, i2cbyte
writei2c $10,($00) 'makes all GPB pins outputs
Pause 100
writei2c $00,($255) 'makes all GPA pins inputs
Pause 100
writei2c $06,($255) 'makes all GPA pins have pullups

But this does not produce any inputs or outputs for me. In the data sheet there is a reference to “IOCON – I/O EXPANDER CONFIGURATION REGISTER (ADDR 0x05)”. Do I need to deal with this to set up how I communicate to the chip?


Edited by - erdc on 20/02/2007 18:41:06

Edited by - erdc on 20/02/2007 18:42:05
 

andrewpro

New Member
My memory is a bit fuzzy as it's been a while, but you DO have to set the config registers. The chip jsut plain wont work without it. Well, it will, but it will go to default settings which, I'm rpetty sure, doesn't really do anything special. Just makes it safe to sit there.

in the config register (the datasheet will tell you exactly how):

Set data direction for each port.
set interupt behaviour


After that, you just set your outputs to what you want, and read your inputs when you want.

Just be aware that once the interrupt triggers, read the buffer addresses, not the pins themselves. It takes a snapshot of what exactly triggered the interrupt and what it looked like when it happened. If you read the pins themselves, they can change if you dont read it fast enough, and youll get invalid data.

--Andy P
 

erdc

Member
Thanks andypro. I tried to make the banks separate, and the address not to increment, and tried both enabling and disabling the slew rate, but with out any luck. If by chance you have the code to just set up the MCP23017 it would be greatly appreciated. All I need is just to “crack” into this chip to do what I want it to do.
 

andrewpro

New Member
ok, couple of questions:

1) why are you disabling the slew rate limiter? You really shouldn't need to.

2) what are you sending to the bank bit in iocon?

3) --Edited this one out, it's irrelevent.--

4) actually..what are you sending the whole way through. I dont want the code, just put in order all bytes your sending, and a little note as to what they're for.

Sounds like there is some kind of communication issue going on here. Something probably isn't being configured correctly. I'll help as best I can, but I wont give you the code. That would rob you of the experience of making it work =)

--Andy P

Edited by - andypro on 21/02/2007 18:20:36
 

andrewpro

New Member
If that's all your sending, then that's why it's not working the way you want it <img src="wink.gif" width=15 height=15 align=middle>

Ok...first off...slew rate: Ignore it. What this is used for is to control the waveshape (essentially) of fast connections, which we really dont have to worry about here.

Second: If you send just that byte, you wont be able to activate any outputs, as there arent any. The pins all default to inputs with the &quot;0&quot; polarity. You will need to address that.

Third: When you turn on the banking, you split the two halves into separate worlds, so to speak. This is fine, as long as your properly addressing things, and not overrunning the allowed addresses. If you set 0A, then send another byte, it will go to 0B which is invalid with banking on. Beware of things like this.

Fourth: You've turned off sequential access. This can be a double edged sword. The device will not auto increment. In picaxe world, this is a problem. If your going to send more than one byte at a time, you must send a restart, or a stop then start. The picaxe cannot do this. You MUST, after every command, make sure that you end the I2C communication, then start a new one. Every single byte. Or things will just keep overwriting the same byte over and over again and you can get lost pretty easily.


I would for now, go to basics. Just make sure you can get one thing at a time working. Start by trying to make everyhting outputs, and setting them all to 1. Send &quot;00000000&quot; to registers 0x00 and 0x10. Then send &quot;11111111&quot; to registers 0x09 and 0x19. This should turn on all the outputs. Then check em. Dont burn out the chip. ignore iocon for now, just to make sure youve got thigns going properly.

After that, try making one whole bank inputs, and trigger them. Then start worrying about interrupts if you need to. Then try to make only certain pins on a bank inputs, etc. Baby steps will see you through, and thoroughly reading the datasheet before, during, and after each step will give you the info you need to make the chip do exaclty what you want.

Good Luck
--Andy P
 

erdc

Member
I have more code than just that, but instead of us going thru 20 more posts trying to figure why my code won&#8217;t work, could you just send the bare minimum of code that will do all that for me? (i.e GPA ports to be outputs, and the GPB ports to be inputs.) That way any other person searching for same problem can find the solution in a timely manner. I just feel we are not going to solve this in a few more posts between us. And I have extensively have done searches here and on Google.

Thank you very much for your time to reply to my question, it is very much appreciated.
 

erdc

Member
OK I have the following code but neither porta or portb shows either a high or low.


i2cslave %01001100, i2cfast, i2cbyte
writei2c $05,(%00000000)
writei2c $00,(%00000000)
writei2c $10,(%00000000)
writei2c $09,(%11111111)
writei2c $19,(%11111111)

I am really interested in this chip andypro from reading your own thread entitled &quot;Say no to MCP23016, YES to MCCP23017!!&quot;
<A href='http://www.rev-ed.co.uk/picaxe/forum/Topic.asp?topic_id=3260&amp;forum_id=19&amp;Topic_Title=Say%2Bno%2Bto%2BMCP23016%252C%2BYES%2Bto%2BMCCP23017%2521%2521&amp;forum_title=No+new+posts+please%21+13' Target=_Blank>External Web Link</a> So I know I am still missing something here.
 

andrewpro

New Member
Whoa...Sorry! I completely forgot about this thread. Been rough at work. My appologies. Anyways..

It looks like you've got the right idea as to how to make it work, but you've got the wrong bank settings.

In the address 05 entry, you made everything 0. This includes the bank register. From the code you posted, It would appear your using the addressing chart for IOCON.Bank=1. This wont work, as changing the banking changes all the addressing of the chip. It pretty much shuffles the banks together like a stack of cards.

For IOCON.Bank=0 you should use the following:

0x00=IODIRA=%00000000 This sets port A to outputs

0x01=IODIRB=%00000000 This sets port B to outputs

0x12=GPIOA=%11111111 Makes all of port A high

0x13=GPIOB=%11111111 Makes all of port B high

If youve got the IOCON.Bank=0 and you want to change it back to 1, use 0x0A. I think you may be able to use B as well, as they're mirrored, but dont quote me on that.

This info is comming from the Data sheet I have, page 11, table 1-6. The one for bank=1 is on the previous page.

Also, what do you have pins 15, 16, and 17 tied to? Just want to double check that it's not the problems you've been having <img src="smile.gif" width=15 height=15 align=middle>

--Andy P

 
 

erdc

Member
Pin 15 = 0, Pin 16 = 1, Pin 17 = 1. So that should make the address call of i2cslave %01001100, i2cfast, i2cbyte.

I do not want to make the calling of the different banks complecated. (For you or me)So what you saying is that I should just have for the ICON 0x05 register as just %10000000?

And if so, then what whould else registers would I send to make this senario work?

Thanks for all the help so far Andy P!

 

andrewpro

New Member
well, it doesn't really matter. You can use either banking scheme you wish, but you MUST be consistent with the manner in which you use them.

If I were you I'd use the IOCON.bank=0. Just form a mental mapping standpoint, it will be easier as the banks wont be split up. It's just one address after another, working in pairs.

I'd give it a shot with what I gave you earlier, using IOcon.bank=0. Once you get that working, we can get more exotic and really explore the capabilities of the chip!

--Andy P
 

erdc

Member
That did the trick Andy P!

I want to thank you for your time and patience with me. I can now dig further into the data sheet to better understand this banking issue, since now at least I have some working knowledge on how it should perform.
 
Top