FORUM TOPIC · READ ONLY

mcp23017

mcp23017

Forum : General Remark and Questions

2 message(s) · archive en lecture seule

davc22
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

Re: mcp23017

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