Page 1 of 2

I/O expansion

Posted: Mon Sep 15, 2008 11:51 am
by Sean
Image

Many microcontrollers are now available with huge numbers of I/O pins. The drawback for most people is that they are only available in unusable surface mount packages. So the 40-pin, 4 x 8-bit port maximum limit still applies. Multiplexing circuits can be used to share I/O lines between multiple signals, but the I/O characteristics of the multiplexers are generally inferior to those of the microcontroller, and the inter-wiring can become complicated.

Microchip have developed two I/O expander chips that can each add 16 I/O lines to an application, using a synchronous serial bus to communicate with the microcontroller. The MCP23017 (I2C/TWI bus) and MCP23S17 (SPI bus) require only 2 (SCL + SDA) or 4 (SDO + SDI + SCK + /CS) signal wires respectively to connect to the microcontroller. They also have a 3-bit external addressing facility (A0, A1, A2) that allows up to 8 devices, supplying 128 I/O lines, to share a single bus connection without any special arrangements (each with one of the 8 possible configurations of A2, A1, A0).
Image
A disadvantage of this approach is that access to the expansion I/O is slower than that of the microcontroller - which has now been freed for the high speed operations. The fastest version of the device is the SPI bus (4-wire) MCP23S17 which requires the transfer of 3 data bytes to randomly access any one of its registers. Even with the maximum10MHz bus clock it will take several microseconds to read each port. This should still be adequate for the majority of I/O operations with signal frequencies of 100KHz or less.

As an alternative to polling the I/O expanders for input values, they can be configured to generate interrupts (requiring additional connections to the microcontroller) when change events occur, and to capture the I/O state at the instant the interrupt occurred, allowing the information to be retained until the microcontroller is able to retrieve it. For these operations each device can be treated as two 8-bit ports, or a single 16-bit port.
The expander ports provide most of the features expected from any microcontroller port: 25mA current source and sink, programmable pull-up resistors, interrupt-on-change mask registers, etc.

The device register address can be configured in one of two selectable maps. The chip can be programmed to allocate a separate block of addresses to the registers of each port. The default map, used in the example programs, has the registers of each port interleaved.

The example programs - one for I2C, the other for SPI - configure a single expander device with all Port A pins as inputs, and all Port B pins as outputs. The main program loop then polls the expander Port A every 100ms and sends the data out to the expander Port B.
The existing Flowcode SPI and I2Ccomponents include all the functions necessary to communicate with the I/O expanders at a byte level. The macros in the programs tidy-up the multi-byte communication processes and provide a simple 'address + data' interface to the main program, for any expander register, in read or write mode.
Image

Re: I/O expansion

Posted: Mon Oct 27, 2008 6:48 am
by Kumaran
Can you please post the circuit diagram? I have tried using this IC MCP23017 in my circuit. I set port A as an output. From my program I have made all bits to high. But it is not getting high. In proteus simulation it is working probably I am missing some components in the hardware. If you could post the circuit diagram, it would be greatly helpful.

Thanks in advance

Kumaran

Re: I/O expansion

Posted: Mon Oct 27, 2008 2:54 pm
by Benj
Hello Kumaran

Are you using pull up resistors on the two I2C Bus lines?

Re: I/O expansion

Posted: Mon Oct 27, 2008 3:46 pm
by Kumaran
Yes. I am using pullup resistor for I2C. I am using two mcp23017 in my circuit. after posting the request, I tried again by changing the first IC address from 3 (i.e 011) to 255. and second IC from 1 to 6. Now my first IC generated the output as I programmed but the second IC does not. Then I changed the second IC address to 255. Then I got the same outputs in first and second IC. I understand that I am doing some mistake in addressing. could you please tell me how to make the address pins connections?

Re: I/O expansion

Posted: Wed Oct 29, 2008 10:36 am
by Sean
The control byte sent to the MCP23017 (containing the slave address) has three sections:
The most significant nibble is the fixed hardware address 0100 (0x4)
The next three bits are controlled by the logic levels on the three hardware address pins A2, A1, A0 (pins 17, 16, 15 on the PDIP package). These three pins allow up to 8 individual devices to be allocated unique addresses on a single bus.
The least significant bit is the read/write control.

Example:

MCP23017 : A2 = 0v; A1 = 5v; A0 = 5v;

write mode
control byte = 0100 011 0 = 0x46

readmode
control byte = 0100 011 1 = 0x47

The example program was written for A2, A1, A0 = 0v (Write mode = 0x40, read mode = 0x41)

Re: I/O expansion

Posted: Thu Oct 30, 2008 10:36 am
by Kumaran
Hi

Thanks for clear explanation.

I have checked the program output in I2C simulation window. I am getting the exact value that you have mentioned in your explanation. Actually I am using the write macro from the article example file. I don't understand why my second IC is not generating any output if I specify any other address other than 255 in the software and hardware.

regards
Kumaran

Re: I/O expansion

Posted: Thu Oct 30, 2008 11:29 am
by Sean
If you are using the macros from the example program, all the command byte construction is carried out for you in the code. The first parameter passed to the read or write macro (dev_addr) should only contain the value of the A2, A1, A0 bits of the target chip (ie. a number between 0 and 7).
Kumaran wrote:I don't understand why my second IC is not generating any output if I specify any other address other than 255 in the software and hardware.
How are you setting the address of the second device? It is not possible to set a hardware address of 255 as there are only 3 address pins. Also, only the three least significant bits of the 'dev_addr' parameter value are used in the read and write macros, so 255 should represent the same address as 7, 15, 23, 31...... (A2, A1, A0 = 5v)

Re: I/O expansion

Posted: Thu Oct 30, 2008 12:08 pm
by Kumaran
attached the screen shot.

If you see the I2C window for my address setting of 255, 78 is transferring which is 01001110 in binary. If I set other than 255, (I didn't try 7, 15, 23, 31) for the HW/SW I am not getting the output. The second IC in hardware, I have soldered A0 = 5V, A1 = 5V, & A2 = NC (also I tried connecting A2 = Ground but there is no improvement)and in the software I set 3 for device address (I am using your Macro). Then I have soldered A0,A1, A2 = 5V (for both IC) then I set 255 as device address then my two ICs were generating output what ever I specify in the program.

Regards
Kumaran

Re: I/O expansion

Posted: Thu Oct 30, 2008 12:59 pm
by Sean
the operation of the write macro looks to be ok. The illegal device address of 255 you are sending is being converted into the legal address 7 and generating the write command byte 78 (0x4E). This is compatible with an MCP23017 with A2, A1, A0 pulled high.

According to the data in the I2C simulation window, the program is:
Setting Port B as all outputs (writing 0 to register 1 - IODIRB)
Setting Port A as all inputs (writing 255 to regiser 0 - IODIRA)
Writing the data 255 to Port A (writing 255 to register 18 - GPIOA)

If this is the case, the data was being written to a port configured as an input.

Your original test, with A2 of the second device pulled low (giving a device address of 3) should have worked and allowed the two devices to be accessed individually (A2 should have been pulled low and not left floating). It is probably worth trying to debug the system with two devices set to different hardware addresses (ie. first device address = 7, second device adress = 3).

Re: I/O expansion

Posted: Fri Oct 31, 2008 5:48 am
by Kumaran
There is no improvement as you said I have made two different address for each IC. First IC address = 7 & second IC address = 1. In that configuration also, only the first IC worked. So to check the circuit connection I made second IC address = 7 then both the IC worked. So There is no error in the circuit. But what is making it not to work?

Re: I/O expansion

Posted: Thu Nov 06, 2008 10:07 am
by Sean
Here is a modified version of the original example program. In addition to one MCP23017 (A2 : A1 : A0 = 0) copying the inputs on Port A to the outputs on Port B, a second MCP23017 (A2 : A1 : A0 = 4) on the same I2C bus outputs a free running counter value on its Port B pins.
io_expand_MX2.fcf_avr
(5.5 KiB) Downloaded 1424 times
The program has been written using Flowcode for AVR (ATmega32 target) and tested with prototype hardware. The code should import direcrtly into other versions of Flowcode with suitable target devices selected (eg. PIC16F877A).

Re: I/O expansion

Posted: Thu Nov 06, 2008 12:09 pm
by saschech@gmx.de
Hallo Sean
Ihave only the pic vers.If i want open I have a error.Definition datei ATMEL32.FCD is missing.

Regards wolfgang

Re: I/O expansion

Posted: Thu Nov 06, 2008 12:24 pm
by Sean
If you have the latest updates for Flowcode (available from our website), you can use the recently introduced 'File -> Import' feature to automatically convert most Flowcode programs between the PIC, AVR, and ARM versions.

I have used this feature to convert the previous AVR program to PIC (PIC16F877A target).
io_expand_MX2.fcf
(7.5 KiB) Downloaded 1416 times
Please note that I have not tested the PIC version on any hardware, but it compiles successfully and is an exact copy of the working AVR program.

Re: I/O expansion

Posted: Mon Oct 05, 2009 8:40 am
by WalkOver
Hello,

Do you think it's possible to address more than 8 MCP23S17 if I play with the CS pin.
I need 12 MCP23017 or MCP23S17.

Thank you for your help !

Re: I/O expansion

Posted: Mon Oct 05, 2009 10:39 am
by Sean
Yes. The SPI versions will allow you to address 8 devices for each CS line . The SPI hardware will be shared by all the chips.

The I2C versions do not offer this option (no CS pins). A Flowcode Software I2C component could be used, in addition to the hardware I2C, to create a second I2C bus to control the 4 extra chips.

This represents a lot of I/O. Hope you have a good power supply!

Re: I/O expansion

Posted: Mon Oct 05, 2009 1:31 pm
by WalkOver
Thanks a lot.
I tried to compile with one soft and on hard I2C but without any success.

For the power supply, i will use a LM2678 :)

Please Help

Posted: Fri Oct 09, 2009 4:02 pm
by Mathy
Hello,

I have a problem. I use two MCP23S17.

All the MCP23s17's PORT are set as output and I use your macro command.

The two MCP23S17 had two different hardware address ( 0 for the first and 1 for the second ) but, if i want to write on the first MCP23S17 PORTA a different value of the second MCP23S17 PORTA. The port A switch between the two different value.

Is it possible for you to test my program
Make attention because I use 18F6527 at 40 Mhz and I use B2 for the chip select.
And I use Flowcode V4...

Thank you so much for your help. I almost kill myself because of that! :mrgreen:

Re: I/O expansion

Posted: Fri Oct 09, 2009 10:21 pm
by Sean
Hello,

I will not be able to check your program for a couple of days, but I am aware of an additional requirement for enabling addressing mode for the SPI versions of the devices (not required for the I2C devices)

After a reset or power-up, addressing mode is disabled - all devices respond to address 0 regardless of the A2,A1,A0 settings. This might explain why both devices seem to be responding to the same commands.

To enable addressing mode, the HAEN bit (bit 3) of the IOCON register (register 10 or 11, (0x0A or 0x0B)) must be set to 1.

After reset/power-up the SPI_IOEXP_WR macro can be used to write the following parameters to enable addressing mode in all the devices connected to the SPI bus and selected by the CS line (all at address 0).

Device address 0
Register 0x0A
Data value 0x08

After this command has been sent, each chip will respond to its hardware address - hopefully allowing the remainder of your original program to work correctly.

Re: I/O expansion

Posted: Mon Oct 12, 2009 5:15 pm
by Mathy
Hello Sean,

Thank you very much for the tips. I tested it quickly this morning and I think it works now !

Bye :)

Mathy

Re: I/O expansion

Posted: Tue Oct 13, 2009 4:22 pm
by Mathy
Hello !

I have an other problem. The MCP23S17 doesn't respond on address over 0x03.
If i bias A0=0V, A1=0V A2=5V, The hardware address is 0x04 ?
With the same program I sent you the last time, the chip put PORTA and PORTB to 0 :-(

Any ideas ?

Thank you so much,

Mathy

Re: I/O expansion

Posted: Wed Oct 14, 2009 9:30 am
by Sean
Hello mathy,

I can not see any reason why addressing should only work up to address 3.
Setting A2,A1,A0 to 1,0,0 should give you address 4.
I would suspect a bad connection to, or fault with, the the A2 pin of the high address device.
To rule out individual component and connection problems, are you able to test a high address on both of your devices?
I will try to set up a test for a device the address > 3 to re-confirm correct address translation in the write macro.

Re: I/O expansion

Posted: Wed Oct 14, 2009 1:05 pm
by Mathy
Hello,

I'm so so sorry.....I test my circuit on a breadboard and I try to put my MCP23S17 on an other place and the first test seams to be ok.

I will put my breadboard in the trash !!!

Thank you again for your help.

Re: I/O expansion

Posted: Thu Oct 15, 2009 4:48 pm
by Mathy
Hello,

Ok, I think there is a problem....

I tested with severals 23S17 and with the address activation 0, 0x0A, 0x08,
The 23S17 respond well to the address 0, 1, 2 and 3 but the address 4, 5, 6 and 7 doesn't work. I can't display anything with those addresses...

Is it possible for you to test ? I don't know what I made to display a value last day but finally, It doesn't work...

Thank you and sorry for the inconvenience,

Mathy

Re: I/O expansion

Posted: Fri Oct 16, 2009 8:26 am
by Sean
Hello Mathy,

I have done some basic tests on a single 23S17, and had some confusing results with the higher addresses.

I found this errata document that might explain the problem:
MCP23x17 errata.pdf
(330.02 KiB) Downloaded 1360 times
If the device is configured for a high address ( 4, 5, 6, or 7) with A2 pulled high, it will not respond to address 0 after power-up/reset (as stated in the main data sheet), but needs an address with the A2 bit set.

The macro call used to enable hardware addressing in an earlier post should be followed by a second call with a high address so it can be recognised by any devices with A2 pulled high.

Device address 0
Register 0x0A
Data value 0x08

Device address 4
Register 0x0A
Data value 0x08

This should not cause any problems with newer devices that have had this error corrected.

Re: I/O expansion

Posted: Fri Oct 16, 2009 11:39 am
by Mathy
Thank you for your help sean,

I just try your tips but without any success.
I don't understand very well the datasheet. I find it not very clear and my English is so bad...
I'm lost.....

I bought my 23S17 few ays ago on Radiospares in DIP Package.
I will try with the SOIC package.

I will post the news if I found the solution !

Thank you again an tell me if you want to have a peace of program I use.

PS : Your MCP23S17 bug if you send him 0xFF for the DATA ? If I send this value, I have to reset....