CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem Interfacing PIC18F8723 and MCP23016

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
orazio



Joined: 03 Sep 2010
Posts: 27

View user's profile Send private message

Problem Interfacing PIC18F8723 and MCP23016
PostPosted: Sun Oct 28, 2012 10:44 am     Reply with quote

Good Morning,
I'm using CCS 4.084 compiler and PIC 18F8723.
I have connected my PIC18F8723 with MCP23016 io expander by microchip, and i want to use it as output (all 16 channels).
I set MCP23016 address to 0x40.
As described in microchip AppNote AN245 i have followed the schematics "MCP23016 I/O EXPANDER SCHEMATIC (SHEET 1 OF 2)"
to interface MCP23016 to my PIC, apart following differences:

-PIN 14 (MCP23016 SCLK) was connect to PIN 64 (PIC18F8723 SCLK)
-PIN 15 (MCP23016 SDA) was connect to PIN 65 (PIC18F8723 SDA)
-Pull-ups both SDA and SCLK to +5V using a 2.7K resistor.
-PIN 16 (MCP23016 A0) was connect to PIN 68 (PIC18F8723 RD2)
-PIN 17 (MCP23016 A1) was connect to PIN 67 (PIC18F8723 SD3)
-PIN 18 (MCP23016 A2) was connect to PIN 68 (PIC18F8723 SD4)

This is my code:
Code:

#include <18f8723.h>
#fuses HS,NOWDT,PROTECT,NOLVP,NOMCLR
#use delay(clock=25000000)
#use I2C(master, sda=PIN_D5, scl=PIN_D6, FORCE_HW)




#include <stdlib.h>
#include <string.h>


// COMMAND BYTE
#define GP0 0x00
#define GP1 0x01
#define OLAT0 0x02
#define OLAT1 0x03
#define IPOL0 0x04
#define IPOL1 0x05
#define IODIR0 0x06
#define IODIR1 0x07
#define INTCAP0 0x08
#define INTCAP1 0x09
#define IOCON0 0x0A
#define IOCON1 0x0B


void write_to_MCP(unsigned char WriteAddress, unsigned char cmdByte,unsigned char Data1, unsigned char Data2) {
i2c_start();
delay_us(20);
i2c_write(WriteAddress);
delay_us(20);
i2c_write(cmdByte);
delay_us(20);
i2c_write(Data1);
delay_us(20);
i2c_write(Data2);
delay_us(20);
i2c_stop();
delay_us(50);
}



void init_mcp23016(unsigned char MCP23016_Device_Address) {

write_to_MCP(MCP23016_Device_Address, IPOL0, 0x00, 0x00);
write_to_MCP(MCP23016_Device_Address, OLAT0, 0x00, 0x00);
write_to_MCP(MCP23016_Device_Address, IODIR0, 0x00, 0x00);

}

Init_All_Outputs() {
unsigned char ADR0_GP0= 0XFF;
unsigned char ADR0_GP1= 0XFF;

init_mcp23016(0x40);
write_to_MCP(0x40, OLAT0, ADR0_GP0, ADR0_GP1);
Delay_ms(10);
}

void main(){

  delay_ms(1000);


  output_low(PIN_D2); //Address mcp23016 000 => 0100 0000 = 40 Hex
  output_low(PIN_D3);
  output_low(PIN_D4);
  output_float(PIN_D6);
  output_float(PIN_D5);


  Init_All_Outputs();

  write_to_MCP(0x40, GP0, 0xFF, 0xFF);

  while(true) {
         write_to_MCP(0x40, GP0, 0x01, 0x00);   
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x02, 0x00);   
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x04, 0x00);   
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x08, 0x00);   
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x10, 0x00); 
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x20, 0x00); 
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x40, 0x00); 
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x80, 0x00); 
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x00, 0x01); 
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x00, 0x02); 
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x00, 0x04); 
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0x00, 0x08); 
       delay_ms(1500);
       write_to_MCP(0x40, GP0, 0x00, 0x00);   
       delay_ms(1500);
         write_to_MCP(0x40, GP0, 0xFF, 0xFF);   
         delay_ms(1500);
 }
}


I have installed successfully the file firmware .hex in my PIC, but it doesn't work because i don't command the expander io. I see, always, all 16 channel of MCP23016 to 0 (ZERO).

Please can anyone help me ?
Thaks Crying or Very sad
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

Problem Interfacing PIC18F8723 and MCP23016
PostPosted: Sun Oct 28, 2012 1:04 pm     Reply with quote

Are you sure the PIC is running? If so, how?

If not, try putting output_toggle() commands in the code to
toggle LEDs and confirm it is even executing. Then you start
debugging the code. I would suspect, if the processor is running,
it may be hanging someplace.

Also, in the code library, there is a "MCP23016 simple driver" by PICoHolic
that you might look into....
_________________
Google and Forum Search are some of your best tools!!!!
orazio



Joined: 03 Sep 2010
Posts: 27

View user's profile Send private message

Problem Interfacing PIC18F8723 and MCP23016
PostPosted: Sun Oct 28, 2012 2:36 pm     Reply with quote

Yes, I'm sure that PIC is running !
I have connected a led in RG3 Pin, and i have added output_bit(PIN_G3,1) in my code. When the PIC run i see the led ON.

As you proposed, I have found "MCP23016 simple driver" by PICoHolic.
So I have tried using following code:

Code:

#include <18f8723.h>
#fuses HS,NOWDT,PROTECT,NOLVP,NOMCLR
#use delay(clock=25000000)
#use I2C(master, sda=PIN_D5, scl=PIN_D6, FORCE_HW)

#include <stdlib.h>
#include <string.h>

#ifndef  MCP23016
#define  MCP23016

#define MCP_write 0B01000000
#define MCP_read  0B01000001

#define GP0     0x00
#define GP1     0x01
#define OLAT0   0x02
#define OLAT1   0x03
#define IPOL0   0x04    // INPUT POLARITY PORT REGISTER 0
#define IPOL1   0x05    // INPUT POLARITY PORT REGISTER 1
#define IODIR0  0x06    // I/O DIRECTION REGISTER 0
#define IODIR1  0x07    // I/O DIRECTION REGISTER 1
#define INTCAP0 0x08 // INTERRUPT CAPTURE REGISTER 0
#define INTCAP1 0x09 // INTERRUPT CAPTURE REGISTER 1
#define IOCON0  0x0A // I/O EXPANDER CONTROL REGISTER 0
#define IOCON1  0x0B // I/O EXPANDER CONTROL REGISTER 1
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
void InitMCP23016(int8 AddressSelect, int8 P0, int8 P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(IODIR0);
      delay_us(20);
   i2c_write(P0);
      delay_us(20);
   i2c_write(P1);
      delay_us(20);
   i2c_stop();
      delay_us(20);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(IOCON0);
      delay_us(20);
   i2c_write(0x01);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void GetGPx(int8 AddressSelect, int8 *P0, int8 *P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(GP0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_read | (AddressSelect << 1));
      delay_us(20);
   *P0 = i2c_read();
      delay_us(20);
   *P1 = i2c_read(0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void SetGPx(int8 AddressSelect, int8 P0, int8 P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(OLAT0);
      delay_us(20);
   i2c_write(P0);
      delay_us(20);
   i2c_write(P1);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void GetINTGPx(int8 AddressSelect, int8 *P0, int8 *P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(INTCAP0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_read | (AddressSelect << 1));
      delay_us(20);
   *P0 = i2c_read();
      delay_us(20);
   *P1 = i2c_read(0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void SetGPREG(int8 AddressSelect, int8 REG, int8 Data)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(REG);
      delay_us(20);
   i2c_write(Data);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
#endif

void main(){
  delay_ms(1000);
  output_bit(PIN_G3,1);

  output_low(PIN_D2); //Address mcp23016 000 => 0100 0000 = 40 Hex
  output_low(PIN_D3);
  output_low(PIN_D4);
  output_float(PIN_D6);
  output_float(PIN_D5);

  delay_ms(2000);


  InitMCP23016(0x40,0x00,0x00);
  delay_ms(350);

  SetGPx(0x40, 0xFF, 0xFF);

  while(true) {
       
 }
}


I have installed the firmware in my PIC, but it doesn't work. I see the LED ON, but I see, always, all 16 channel of MCP23016 to 0 (ZERO).

Any suggestion will be appreciated.
Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19505

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 3:13 pm     Reply with quote

Turning the LED 'on', doesn't prove the critical question - how fast it is going.

_Always_, start with a simple 'flash an LED' program, set to flash at (say) 1 second, and before trying to track down code problems, verify that your chip is running at the expected speed. Until this is right, your chip is not genuinely 'running', it is just waking up....

Why are you driving the chip's address lines from the PIC?. This is complex, and wastes pins on the PIC. The point of the address lines is they are meant to be 'hard wired' to specific patterns to allow multiple chips to be used on the same bus. It doesn't say in the data sheet, but on many chips like this the lines need to be setup _before_ the chip wakes up....

Best Wishes
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 3:13 pm     Reply with quote

You are getting short with me because you think I'm asking a stupid
question. This situation crops up constantly and I don't assume anything
(you shouldn't either). The key to troubleshooting is to progress in steps
and prove each step before proceeding, where many people assume and
get into trouble.

Your routines may be hanging in the middle somewhere. I2C can (and will)
hang and stop executing if something is not right.

The output command you used doesn't tell you anything except the
processor executed the first few lines. The reason why I suggested
OUTPUT_TOGGLE is because you will know the entire loop is being
executed repeatedly if the LED toggles on and off.
_________________
Google and Forum Search are some of your best tools!!!!
orazio



Joined: 03 Sep 2010
Posts: 27

View user's profile Send private message

Problem Interfacing PIC18F8723 and MCP23016
PostPosted: Sun Oct 28, 2012 3:47 pm     Reply with quote

Sorry, but i haven't understood your suggestion.

Ok Ttelmah, i have modified the code to flash LED ON/OFF each second.
But excuse me, what do you mean when you say "verify that your chip is running at the expected speed"? Can you explain better?

This is the code
Code:

#include <18f8723.h>
#fuses HS,NOWDT,PROTECT,NOLVP,NOMCLR
#use delay(clock=25000000)
#use I2C(master, sda=PIN_D5, scl=PIN_D6, FORCE_HW)

#include <stdlib.h>
#include <string.h>

#ifndef  MCP23016
#define  MCP23016

#define MCP_write 0B01000000
#define MCP_read  0B01000001

#define GP0     0x00
#define GP1     0x01
#define OLAT0   0x02
#define OLAT1   0x03
#define IPOL0   0x04    // INPUT POLARITY PORT REGISTER 0
#define IPOL1   0x05    // INPUT POLARITY PORT REGISTER 1
#define IODIR0  0x06    // I/O DIRECTION REGISTER 0
#define IODIR1  0x07    // I/O DIRECTION REGISTER 1
#define INTCAP0 0x08 // INTERRUPT CAPTURE REGISTER 0
#define INTCAP1 0x09 // INTERRUPT CAPTURE REGISTER 1
#define IOCON0  0x0A // I/O EXPANDER CONTROL REGISTER 0
#define IOCON1  0x0B // I/O EXPANDER CONTROL REGISTER 1
//////////////////////////////////////////////////////////////////////////////

int1 x =0x01;

//////////////////////////////////////////////////////////////////////////////
void InitMCP23016(int8 AddressSelect, int8 P0, int8 P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(IODIR0);
      delay_us(20);
   i2c_write(P0);
      delay_us(20);
   i2c_write(P1);
      delay_us(20);
   i2c_stop();
      delay_us(20);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(IOCON0);
      delay_us(20);
   i2c_write(0x01);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void GetGPx(int8 AddressSelect, int8 *P0, int8 *P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(GP0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_read | (AddressSelect << 1));
      delay_us(20);
   *P0 = i2c_read();
      delay_us(20);
   *P1 = i2c_read(0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void SetGPx(int8 AddressSelect, int8 P0, int8 P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(OLAT0);
      delay_us(20);
   i2c_write(P0);
      delay_us(20);
   i2c_write(P1);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void GetINTGPx(int8 AddressSelect, int8 *P0, int8 *P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(INTCAP0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_read | (AddressSelect << 1));
      delay_us(20);
   *P0 = i2c_read();
      delay_us(20);
   *P1 = i2c_read(0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void SetGPREG(int8 AddressSelect, int8 REG, int8 Data)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(REG);
      delay_us(20);
   i2c_write(Data);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
#endif

void main(){
  delay_ms(1000);
  output_bit(PIN_G3,1);

  output_low(PIN_D2); //Address mcp23016 000 => 0100 0000 = 40 Hex
  output_low(PIN_D3);
  output_low(PIN_D4);
  output_float(PIN_D6);
  output_float(PIN_D5);

  delay_ms(2000);


  InitMCP23016(0x40,0x00,0x00);
  delay_ms(350);

  SetGPx(0x40, 0xFF, 0xFF);

  while(true) {
                    x=x^0x01;
          output_bit(PIN_G3,x);
          delay_ms(1000)
       
 }
}

I see the LED flashing ON/OFF each second, but all 16 channel of MCP23016 are to 0 (ZERO).

I'm a developer. My electronic engineer project the board and he decides to drive the chip's address lines from the PIC; probably because the data sheet doesn't say that many chips like this the lines need to be setup _before_ the chip wakes up.

Do you think could be this the problem?

Thanks for your interest.


Embarassed
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 5:12 pm     Reply with quote

Quote:
I'm a developer. My electronic engineer project the board and he decides to drive the chip's address lines from the PIC; probably because the data sheet doesn't say that many chips like this the lines need to be setup _before_ the chip wakes up.

Do you think could be this the problem?
Very well possible this is a problem. At least it is wasting I/O pins on your processor, it makes no sense to add an I/O-expander chip and then waste 3 pins like this.
You might be lucky there probably is a workaround for the power-up feature: the MCP23016 has a power-up timer of approximately 72ms. When you ensure your PIC wakes up faster and sets the I/O pins immediately it might work. Get rid of your initial delay routines and add the NOPUT fuse to disable the PIC's Power Up Timeout.
Disadvantage is that the NOPUT fuse will make your PIC less stable in starting up after power on. You might consider revising your hardware to comply to the Microchip advised design.

For reference here a link to the driver you used: http://www.ccsinfo.com/forum/viewtopic.php?t=29024

Just a few minor notes:
Code:
InitMCP23016(0x40,0x00,0x00);
Your driver already adds the 0x40 offset so you should use the base register addresses (i.e. 0).
Code:
InitMCP23016(0x00,0x00,0x00);
Fix also for your SetGPx() call.

Code:
x=x^0x01;
output_bit(PIN_G3,x);
Shorter and easier to read:
Code:
output_toggle(PIN_G3);


Code:
#ifndef  MCP23016
#define  MCP23016
This is not used in your program and can be removed.

Code:
  output_float(PIN_D6);
  output_float(PIN_D5);
This doesn't hurt, but isn't doing anything either as the D5 and D6 outputs were overruled by enabling the I2C module.

Last edited by ckielstra on Sun Oct 28, 2012 5:27 pm; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 5:26 pm     Reply with quote

Something else to try, is the I2C test program here from PCMprogrammer. It would verify that the PIC can communicate with the I2C device.
You might have a bad 23016 and no amount of good (ie working) code would actually run right. Or perhaps a bad wiring/solder connections ,etc.

sometimes hardware can be faulty...

hth
jay
orazio



Joined: 03 Sep 2010
Posts: 27

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 5:45 pm     Reply with quote

Thank you ckielstra. I have followed your suggestion and I have solved the problem.

This is the code
Code:

#include <18f8723.h>
#fuses HS,NOWDT,PROTECT,NOLVP,NOMCLR,NOPUT
#use delay(clock=25000000)
#use I2C(master, sda=PIN_D5, scl=PIN_D6, FORCE_HW)

#include <stdlib.h>
#include <string.h>

#define MCP_write 0B01000000
#define MCP_read  0B01000001

#define GP0     0x00
#define GP1     0x01
#define OLAT0   0x02
#define OLAT1   0x03
#define IPOL0   0x04    // INPUT POLARITY PORT REGISTER 0
#define IPOL1   0x05    // INPUT POLARITY PORT REGISTER 1
#define IODIR0  0x06    // I/O DIRECTION REGISTER 0
#define IODIR1  0x07    // I/O DIRECTION REGISTER 1
#define INTCAP0 0x08 // INTERRUPT CAPTURE REGISTER 0
#define INTCAP1 0x09 // INTERRUPT CAPTURE REGISTER 1
#define IOCON0  0x0A // I/O EXPANDER CONTROL REGISTER 0
#define IOCON1  0x0B // I/O EXPANDER CONTROL REGISTER 1
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
void InitMCP23016(int8 AddressSelect, int8 P0, int8 P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(IODIR0);
      delay_us(20);
   i2c_write(P0);
      delay_us(20);
   i2c_write(P1);
      delay_us(20);
   i2c_stop();
      delay_us(20);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(IOCON0);
      delay_us(20);
   i2c_write(0x01);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void GetGPx(int8 AddressSelect, int8 *P0, int8 *P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(GP0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_read | (AddressSelect << 1));
      delay_us(20);
   *P0 = i2c_read();
      delay_us(20);
   *P1 = i2c_read(0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void SetGPx(int8 AddressSelect, int8 P0, int8 P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(OLAT0);
      delay_us(20);
   i2c_write(P0);
      delay_us(20);
   i2c_write(P1);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void GetINTGPx(int8 AddressSelect, int8 *P0, int8 *P1)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(INTCAP0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
   i2c_start();
      delay_us(20);
   i2c_write(MCP_read | (AddressSelect << 1));
      delay_us(20);
   *P0 = i2c_read();
      delay_us(20);
   *P1 = i2c_read(0);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//////////////////////////////////////////////////////////////////////////////
void SetGPREG(int8 AddressSelect, int8 REG, int8 Data)
{
   i2c_start();
      delay_us(20);
   i2c_write(MCP_write | (AddressSelect << 1));
      delay_us(20);
   i2c_write(REG);
      delay_us(20);
   i2c_write(Data);
      delay_us(20);
   i2c_stop();
      delay_us(50);
}
//#endif

void main(){
  delay_ms(10);


  output_low(PIN_D2); //Address mcp23016 000 => 0100 0000 = 40 Hex
  output_low(PIN_D3);
  output_low(PIN_D4);

  delay_ms(2000);


  InitMCP23016(0x00,0x00,0x00);
  delay_ms(350);

  SetGPx(0x00, 0xFF, 0xFF);

  while(true) {
            output_toggle(PIN_G3);
            delay_ms(1000);

 }
}


Now the led flash and I can command the io expander output.
The solution is to put MCP 23016's A0,A1,A2 pins 'hard wired' to ground. ("massa")
My electronic enginner must revise the hardware.

Thanks to all. Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19505

View user's profile Send private message

PostPosted: Mon Oct 29, 2012 2:11 am     Reply with quote

As you saw, I had a 'nasty feeling' that was the case...

It is true of a lot of I2C devices. They are not designed to be 'mobile' on the bus, but to be at fixed addresses that are set before the bus becomes active. The address pins allow multiples of the same device to be on the bus.

I had run into this before, on a system where we had a long I2C bus (with extenders), and wanted sub boards to have different addresses set in software. We had to add circuitry so the processor controlled the supply to the chip, set the address, and only then wake up the chip, to make it work. Again the data sheet did not 'say'....

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group