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 support@ccsinfo.com

MCP23016

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
sadlpx



Joined: 19 Feb 2004
Posts: 23

View user's profile Send private message

MCP23016
PostPosted: Wed Feb 09, 2005 9:22 am     Reply with quote

Finally got the MCP working after lots of time.
Short background GP0 is all outputs.
GP1 is all inputs.

Kept having inputs go off on the I2cread. Tough to debug problem would go away when i stepped through code. Problem appears to be that more time is required before each I2cstart. Changed delay from 20 to 50usec just before the second i2cstart in the read _MCP and problem went away.

Hope this is useful
Code:

///////////////////////////////////////////////////////////////////////////////
//
//
////////////////////////////////////////////////////////////////////////////////
#include <16F876.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#device ICD=true
#use delay(clock=10000000)   // value based on crystal

//Uses a Scott Edwards Electronics 4x20 Serial LCD module
#use rs232(baud=9600,parity=N,xmit=PIN_c4,rcv=PIN_B0,stream=RS232,invert,bits=8)

unsigned int MCP_D1, MCP_d2;

// Define project I2C communication pins
#define SCL_PIN PIN_A4
#define SDA_PIN PIN_A5
#use i2c(master, sda=SDA_pin, scl=SCL_pin)

#include <BPP_420 LCD.C>

#define MCP23016_I2C_WRITE   0x40
#define MCP23016_I2C_READ    0x41


// COMMAND BYTE TO REGISTER RELATIONSHIP : Table: 1-3 of Microchip MCP23016 - DS20090A
#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

// BLOCK VARIABLE REGISTER
unsigned char MCP23016_Device_Address;  // MCP23016 Assigned Device Address.
int GPIO_port;       // MCP23016 Data Port Register.

// MCP23016 - I2C constants for selecting type of data transfer.
#define I2C_MCP23016_GP0_READ  0x41 // 1001 1111
#define I2C_MCP23016_GP0_WRITE 0x40 // 1001 1110
#define I2C_MCP23016_GP1_READ  0x41 // 1001 1111
#define I2C_MCP23016_GP1_WRITE 0x40 // 1001 1110

// ----------------------------------------------------------------------------


void write_to_MCP(unsigned char WriteAddress, unsigned char cmdByte,
                  unsigned char lsbData, unsigned char msbData) //, unsigned char msbData)
   {
   short int status;

   i2c_start();               // start condition
   delay_us(20);
   i2c_write(WriteAddress);   // Send slave address and clear (R/W_)
   delay_us(20);
   i2c_write(cmdByte);        // Command byte and register to be written.
   delay_us(20);
   i2c_write(lsbData);        // First data byte pair as per command byte(cmd)
   delay_us(20);
   i2c_write(msbData);        // Second data byte pair as per command byte(cmd)
   delay_us(20);
   i2c_stop();                // stop condition
   delay_us(50);              // delay to allow write (12us)min.

   }

// ----------------------------------------------------------------------------

Long int read_MCP(unsigned int WriteAddress, unsigned int cmdByte, unsigned int ReadAddress)
   {
   int Data, lsbData, msbData;
   long int ldata;
   short int status,count;

   startRead:
   count=0;                   // Initialize read attempts counter.

   i2c_start();               // start condition
   delay_us(20);
   i2c_write(WriteAddress);   // Send slave address and clear (R/W_)
   delay_us(20);
   i2c_write(cmdByte);        // Command byte and register to be written.
   delay_us(50);
   i2c_start();
   delay_us(20);              // restart condition
   i2c_write(ReadAddress);    // Send slave address and clear (R_/W)
   delay_us(20);
   lsbData = i2c_read(1);     // Data from LSB or MSB of register
   delay_us(20);
   msbData = i2c_read(0);     // Data from LSB or MSB of register
   delay_us(20);
   i2c_stop();                // stop condition
   delay_us(50);              // delay to allow read (12us)min.
   MCP_D1 = lsbdata;
   MCP_d2 = msbdata;
   ldata = (msbdata<<8);
   ldata = ldata + lsbdata;
   return(ldata);
 }



// ----------------------------------------------------------------------------
/*
void init_mcp23016(unsigned char MCP23016_Device_Address)
{
   // Wait for MCP23016 Expander Device to power-up.
   delay_ms(250);
   delay_ms(250);
   delay_ms(250);

   // Set-up selected I/O expander unit
   //write2Expander(MCP23016_Device_Address, IPOL0, 0xFF, 0xFF); // Invert all input polarities if active low.
   //write2Expander(MCP23016_Device_Address, IPOL1, 0xFF, 0xFF); // Invert all input polarities if active low.
   write2Expander(MCP23016_Device_Address, IPOL0, 0x00, 0x00);   // NonInvert all input polarities if active low.
   write2Expander(MCP23016_Device_Address, IPOL1, 0x00, 0x00);   // NonInvert all input polarities if active low.

   write2Expander(MCP23016_Device_Address, IOCON0, 0x01, 0x01); // IARES(1) to max. activity detection time.
   write2Expander(MCP23016_Device_Address, IOCON0, 0x01, 0x01); // IARES(1) to max. activity detection time.

   write2Expander(MCP23016_Device_Address, IODIR0, 0x00, 0x00); // Direction of all data is output.
   write2Expander(MCP23016_Device_Address, IODIR1, 0x00, 0x00); // Direction of all data is output.

   write2Expander(MCP23016_Device_Address, OLAT0, 0xFF, 0xFF); // Update o/p latch that controls the output.
   write2Expander(MCP23016_Device_Address, OLAT1, 0xFF, 0xFF); // Update o/p latch that controls the output.

   //write2Expander(MCP23016_Device_Address, IODIR0, 0x00, 0x00); // Direction of all data is output.
   //write2Expander(MCP23016_Device_Address, IODIR1, 0x00, 0x00); // Direction of all data is output.
}
*/

//=============================================

void main(void) {
   int n, nn, o;
   long int oo;


   putc(3);
   putc(12);               // Clear LCD
   putc(1);
   printf("I/O Tester");
   write_to_MCP(MCP23016_I2C_WRITE, IODIR0, 0x00, 0xff); // GP0= outputs GP1=inputs
   LCD_goto (20);

   while(1) {

      for (n=0; n<255; ++n) {
           delay_ms(500);
           nn = (n ^ 0xff);
           write_to_MCP(MCP23016_I2C_WRITE, OLAT0, nn, 0);
           LCD_goto (20);
           printf("\%03d ", n);

           oo = read_MCP(MCP23016_I2C_WRITE, GP0, MCP23016_I2C_READ);
           LCD_goto (40);

           oo = (oo ^ 0xff00);
           oo = (oo & 0xff00);
           printf("\%04lx ", oo);
      }

  }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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