mcp23017

Create new topics, add your comment, remark, bugs...
Post Reply
davc22
Posts: 2
Joined: Sun Apr 24, 2011 1:19 am

mcp23017

Post by davc22 » Sun Apr 24, 2011 1:28 am

hi ,

i'm using 18F4620 with MCP23017 . the interface is I2C. i have no problem writing to MCP but i can't read.the mcp always return 0xC2.
thanks for any help

david


#include <p18cxxx.h>
#include "I2C.h"
#include "Ports.h"
#include "TypeDef.h"
/******************************************************************/
// Function:OpenI2C
// Action : This open the MSSP module & Set it
// Code :
// Input :
// Output :
//*****************************************************************/

void OpenI2C(void)
{
//Reseting MSSP registers
SSPCON1 = 0x00;
SSPCON2 = 0x00;
// Set Ports
I2C_SCL_AS_INPUT;
I2C_SDA_AS_INPUT;
// Disable Slew Rate
SSPSTAT |= 0x80 ;
// Set Baud Rate
SSPADD = SSPADD_FOR_BAUD ;
// Set Mode and enable Module
SSPCON1 = I2C_MSTR_MOD + I2C_ENA ;
PIR1bits.SSPIF = 0;//reset MSSP interrupt flag bi
}// end of OpenI2C()

/******************************************************************/
// Function:IdleI2C
// Action : sample status bits and wait for the bus To Be free
// Code :
// Input :
// Output :
//*****************************************************************/

void IdleI2C(void)
{
//Test and wait until I2C module is idle
while ( (SSPCON2 & 0x1F) | (SSPSTATbits.R_W) )
continue; //keep looping until idle
}//end of IdleI2C()

/******************************************************************/
// Function:NotAckI2C
// Action : Send nACK to slave(@ after received data)
// Code :
// Input :
// Output :
//*****************************************************************/

void NotAckI2C(void)
{

SSPCON2bits.ACKDT = 1; // set acknowledge bit for NOT ACK

SSPCON2bits.ACKEN = 1; // initiate bus acknowledge sequence

}//end of NotAckI2C()

/******************************************************************/
// Function:StartI2C
// Action : Generate Start Bit and wait for flag to rise
// Code :
// Input :
// Output :
//*****************************************************************/

void StartI2C(void)
{
SSPCON2bits.SEN = 1; //Initiate Start condition
while(!PIR1bits.SSPIF ); //wait for Flag To rise
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
}//end of StartI2C()

/******************************************************************/
// Function:ReStartI2C
// Action : Generate ReStart Bit and wait for flag to rise
// Code :
// Input :
// Output :
//*****************************************************************/

void ReStartI2C(void)
{
SSPCON2bits.RSEN = 1; //Initiate Start condition
while(!PIR1bits.SSPIF ); //wait for Flag To rise
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
}//end of StartI2C()
/******************************************************************/
// Function:Stop I2C
// Action : Generate Stopt Bit and wait for flag to rise
// Code :
// Input :
// Output :
//*****************************************************************/
void StopI2C(void)
{
SSPCON2bits.PEN = 1; //Generate Stop condition
while(!PIR1bits.SSPIF ); //wait for interrupt
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit

}//end of StopI2C()

/******************************************************************/
// Function:WriteI2C
// Action : Write byte to slave
// Code :
// Input :Data byte
// Output :
//*****************************************************************/


Byte WriteI2C(Byte data_out)
{
SSPCON2bits.ACKSTAT = 1; //reset ACK bit flag
SSPBUF = data_out; // write single byte to SSPBUF
if(SSPCON1bits.WCOL ) // test if write collision occurred
{
SSPCON1bits.WCOL = 0; //Reset collision bit
while(SSPSTATbits.BF ); // wait until write cycle is complete
}
while(!PIR1bits.SSPIF); //wait for interrupt
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
if(!SSPCON2bits.ACKSTAT ) //Was there an ACK sent from MCP?
return ACK; //MCP sent ACK
else
return NACK; //No ACK was sent


} //end of WriteI2C()
/******************************************************************/
// Function:Read byte from slave
// Action : Write byte to slave
// Code :
// Input :Data byte
// Output :
//*****************************************************************/
Byte ReadI2C(void)
{
IdleI2C(); //Wait bus to be free
SSPCON2bits.RCEN = 1; // enable master for 1 byte reception

while (SSPSTATbits.BF == 0); // wait until byte received

while(PIR1bits.SSPIF == 0); //wait for interrupt

PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit

return SSPBUF; // return with read byte

}//end of ReadI2C()
/******************************************************************/
// Function:I2CWriteByteToMCP
// Action :Write To Mcp23017 GPIO expender.It sends 3 Bytes : first the Ic address ,
// internal Register Address , the last byte is the register data
// Code :
// Input :Byte ICadd,Byte Regadd,Byte Regdata
// Output :Byte : NACK or ACK
//*****************************************************************/

Byte I2CWriteByteToMCP(Byte ICadd,Byte Regadd,Byte Regdata)
{
OpenI2C(); //Configure & Open Module
IdleI2C(); //Wait bus to be free
StartI2C(); //Generates a Start I2C condition
IdleI2C(); //Wait bus to be free
// Write Device Address
if (WriteI2C(ICadd | WrtCmd ) == NACK)
{
while(1); //STOP program
}

// Write Register Address
if (WriteI2C(Regadd ) == NACK)
{
while(1); //STOP program
}

// Write Register Data
if (WriteI2C(Regdata ) == NACK)
{
while(1); //STOP program

}
Nop();
// Send stop bit
StopI2C();

}
// end I2CWriteByteToMCP()
/******************************************************************/
// Function:ReadByteFromMCp
// Action :ReadFrom Mcp23017 GPIO expender.
// Code :
// Input :Byte ICadd,Byte Regadd
// Output :Byte : data
//*****************************************************************/
Byte ReadByteFromMCp(Byte ICadd,Byte Regadd)

{
Byte data_byte = 0; //variable to hold the data byte from the SLAVE
OpenI2C(); //Configure & Open Module
IdleI2C(); //Wait bus to be free
StartI2C(); //Generates a Start I2C condition
IdleI2C(); //Wait bus to be free
// Write Device Address
if (WriteI2C(ICadd | WrtCmd ) == NACK)
{
while(1); //STOP program
}

// Write Register Address
if (WriteI2C(Regadd ) == NACK)
{
while(1); //STOP program
}
IdleI2C(); //Wait bus to be free
ReStartI2C();
//StartI2C(); //Generates a Start I2C condition
if (WriteI2C(ICadd | ReadCmd) == NACK)
{
while(1); //STOP program
}



data_byte = ReadI2C(); //read the received data from the SLAVE

//data_byte = ReadI2C(); //read the received data from the SLAVE
NotAckI2C(); //Generates a Not Ack condition after reading data

StopI2C(); //Generates a Stop I2C condition

IdleI2C(); //Loops until I2C BUS is Idle

return data_byte; //return data byte from SLAVE

}

davc22
Posts: 2
Joined: Sun Apr 24, 2011 1:19 am

Re: mcp23017

Post by davc22 » Mon Apr 25, 2011 4:27 pm

it's o.k. i have solved the problem.

Post Reply

Who is online

Users browsing this forum: No registered users and 34 guests