neuralc
Full Member level 4
- Joined
- Nov 6, 2001
- Messages
- 236
- Helped
- 9
- Reputation
- 18
- Reaction score
- 3
- Trophy points
- 1,298
- Activity points
- 2,202
Hi all,
I'm trying to use the attached i2c c source files.
Simulating in proteus with 16f876a and fm24c16, and whe I send a byte (using SendI2C) in the StartI2C() the SEN are set to 1, that should esltimul the hardware to generate a start condition (SDA should go low), but the problem is the SDA doesn't go low neither the SSPIF are set again and I get an infinite loop ...
Some one can help??
ThX
NeuralC
/******************************************************************************
* I2C Header file
*
* This file contains the function prototypes for the I2C routines defined
* in I2C.C.
******************************************************************************
*/
#ifndef _I2C_H
#define _I2C_H
// Function Prototypes
char SendI2C(char, char, char*);
char GetI2C(char, char, char, char*);
char StartI2C(char);
char ReStartI2C(char);
void StopI2C(void);
#endif
/******************************************************************************
* I2C Routines (2002.11.09)
*
* This file contains the I2C routines.
* Each routine's parameters are explained above the function declaration.
******************************************************************************
*/
#ifndef _I2C_C
#define _I2C_C
#include "i2c.h"
/******************************************************************************
* SendI2C
* I2CADD : Address of I2C slave device shifted left by 1 bit
* I2CBYTES : Number of bytes to send from I2CBUFFER
* I2CBUFFER : Pointer to a string buffer containing the bytes to send
*
* This subroutine transfers I2CBYTES bytes of data from the string pointed to
* by I2CBUFFER to the slave device at address I2CADD.
*
* Returns 1 : Send completed successfully
* 0 : Send failed
******************************************************************************
*/
char SendI2C(char I2CADD, char I2CBYTES, char *I2CBUFFER)
{
char COUNT = 0;
char bSUCCESS = 1; // Assume successful transfer
if (StartI2C(I2CADD & 0xFE)) // Start transfer and indicate write
{
while (COUNT < I2CBYTES) // Loop until all bytes have been sent
{
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CBUFFER[COUNT++]; // Send byte
while (SSPIF == 0); // Wait until byte sent
}
} else
bSUCCESS = 0; // Indicate send failed
StopI2C(); // Stop the transfer
return bSUCCESS; // Return success indicator
}
/******************************************************************************
* GetI2C
* I2CADD : Address of I2C slave device shifted left by 1 bit
* I2CCOMMAND : > 0 indicates commanded receive, command in first byte of
* I2CBUFFER
* = 0 indicates normal receive
* I2CBYTES : Number of bytes to get from device and write to I2CBUFFER
* I2CBUFFER : Pointer to a string buffer, bytes read will be stored here
*
* This subroutine transfers I2CBYTES bytes of data from the slave device at
* address I2CADD and stores them in I2CBUFFER. If a commanded receive is
* indicated by I2CCOMMAND, the first byte of I2CBUFFER is written to the
* slave device before reading any data.
*
* Returns 1 : Get successful
* 0 : Get failed
******************************************************************************
*/
char GetI2C(char I2CADD, char I2CCOMMAND, char I2CBYTES, char *I2CBUFFER)
{
char COUNT = 0;
char bSUCCESS;
if (I2CCOMMAND)
{
bSUCCESS = StartI2C(I2CADD & 0xFE); // Start transfer and indicate write
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CBUFFER[0]; // Send command byte
while (SSPIF == 0); // Wait until byte sent
ReStartI2C(I2CADD | 0x01); // ReStart transfer and indicate read
} else
bSUCCESS = StartI2C(I2CADD | 0x01); // Start transfer and indicate read
while (COUNT < I2CBYTES)
{
SSPIF = 0; // Clear interrupt flag
RCEN = 1; // Initiate read sequence
while (SSPIF == 0);
I2CBUFFER[COUNT++] = SSPBUF; // Store byte in buffer
SSPIF = 0; // Clear interrupt flag
if (COUNT == I2CBYTES) // If we've read all the bytes
ACKDT = 1; // indicate we're done by no ack
else
ACKDT = 0; // else acknowledge the byte
ACKEN = 1; // Start acknowledge sequence
while (SSPIF == 0); // Wait until acknowledge complete
}
StopI2C(); // Stop the transfer
return bSUCCESS; // Return success indicator
}
/******************************************************************************
* StartI2C
* I2CADD : Address of I2C slave device (left shifted by 1 bit) + R/W bit
*
* This subroutine initiates an I2C transfer by sending a start condition and
* the slave device address, I2CADD.
*
* Returns 1 : Slave device acknowledged
* 0 : Slave device failed to acknowledge
******************************************************************************
*/
char StartI2C(char I2CADD)
{
SSPIF = 0; // Clear interrupt flag
SEN = 1; // Initiate start condition
while (SSPIF == 0); // Wait until Start condition complete
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CADD; // Send address of slave device
while (SSPIF == 0); // Wait until address has been sent
if (ACKSTAT == 0)
return 1; // Return 1 if device acknowledged
else
return 0; // Return 0 if device didn't acknowledge
}
/******************************************************************************
* ReStartI2C
* I2CADD : Address of I2C slave device (left shifted by 1 bit) + R/W bit
*
* This subroutine sends a ReStart condition to the slave device at address
* I2CADD.
*
* Returns 1 : Slave device acknowledged
* 0 : Slave device failed to acknowledge
******************************************************************************
*/
char ReStartI2C(char I2CADD)
{
SSPIF = 0;
RSEN = 1; // Initiate ReStart condition
while (SSPIF == 0); // Wait until start condition complete
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CADD; // Send address of slave device
while (SSPIF == 0); // Wait until address has been sent
if (ACKSTAT == 0)
return 1; // Return 1 if device acknowledged
else
return 0; // Return 0 if device didn't acknowledge
}
/******************************************************************************
* StopI2C
*
* This subroutine ends an I2C transfer by sending a Stop condition.
******************************************************************************
*/
void StopI2C(void)
{
SSPIF = 0; // Clear interrupt flag
PEN = 1; // Send Stop condition
while (SSPIF == 0); // Wait until stop condition complete
}
#endif
I'm trying to use the attached i2c c source files.
Simulating in proteus with 16f876a and fm24c16, and whe I send a byte (using SendI2C) in the StartI2C() the SEN are set to 1, that should esltimul the hardware to generate a start condition (SDA should go low), but the problem is the SDA doesn't go low neither the SSPIF are set again and I get an infinite loop ...
Some one can help??
ThX
NeuralC
/******************************************************************************
* I2C Header file
*
* This file contains the function prototypes for the I2C routines defined
* in I2C.C.
******************************************************************************
*/
#ifndef _I2C_H
#define _I2C_H
// Function Prototypes
char SendI2C(char, char, char*);
char GetI2C(char, char, char, char*);
char StartI2C(char);
char ReStartI2C(char);
void StopI2C(void);
#endif
/******************************************************************************
* I2C Routines (2002.11.09)
*
* This file contains the I2C routines.
* Each routine's parameters are explained above the function declaration.
******************************************************************************
*/
#ifndef _I2C_C
#define _I2C_C
#include "i2c.h"
/******************************************************************************
* SendI2C
* I2CADD : Address of I2C slave device shifted left by 1 bit
* I2CBYTES : Number of bytes to send from I2CBUFFER
* I2CBUFFER : Pointer to a string buffer containing the bytes to send
*
* This subroutine transfers I2CBYTES bytes of data from the string pointed to
* by I2CBUFFER to the slave device at address I2CADD.
*
* Returns 1 : Send completed successfully
* 0 : Send failed
******************************************************************************
*/
char SendI2C(char I2CADD, char I2CBYTES, char *I2CBUFFER)
{
char COUNT = 0;
char bSUCCESS = 1; // Assume successful transfer
if (StartI2C(I2CADD & 0xFE)) // Start transfer and indicate write
{
while (COUNT < I2CBYTES) // Loop until all bytes have been sent
{
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CBUFFER[COUNT++]; // Send byte
while (SSPIF == 0); // Wait until byte sent
}
} else
bSUCCESS = 0; // Indicate send failed
StopI2C(); // Stop the transfer
return bSUCCESS; // Return success indicator
}
/******************************************************************************
* GetI2C
* I2CADD : Address of I2C slave device shifted left by 1 bit
* I2CCOMMAND : > 0 indicates commanded receive, command in first byte of
* I2CBUFFER
* = 0 indicates normal receive
* I2CBYTES : Number of bytes to get from device and write to I2CBUFFER
* I2CBUFFER : Pointer to a string buffer, bytes read will be stored here
*
* This subroutine transfers I2CBYTES bytes of data from the slave device at
* address I2CADD and stores them in I2CBUFFER. If a commanded receive is
* indicated by I2CCOMMAND, the first byte of I2CBUFFER is written to the
* slave device before reading any data.
*
* Returns 1 : Get successful
* 0 : Get failed
******************************************************************************
*/
char GetI2C(char I2CADD, char I2CCOMMAND, char I2CBYTES, char *I2CBUFFER)
{
char COUNT = 0;
char bSUCCESS;
if (I2CCOMMAND)
{
bSUCCESS = StartI2C(I2CADD & 0xFE); // Start transfer and indicate write
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CBUFFER[0]; // Send command byte
while (SSPIF == 0); // Wait until byte sent
ReStartI2C(I2CADD | 0x01); // ReStart transfer and indicate read
} else
bSUCCESS = StartI2C(I2CADD | 0x01); // Start transfer and indicate read
while (COUNT < I2CBYTES)
{
SSPIF = 0; // Clear interrupt flag
RCEN = 1; // Initiate read sequence
while (SSPIF == 0);
I2CBUFFER[COUNT++] = SSPBUF; // Store byte in buffer
SSPIF = 0; // Clear interrupt flag
if (COUNT == I2CBYTES) // If we've read all the bytes
ACKDT = 1; // indicate we're done by no ack
else
ACKDT = 0; // else acknowledge the byte
ACKEN = 1; // Start acknowledge sequence
while (SSPIF == 0); // Wait until acknowledge complete
}
StopI2C(); // Stop the transfer
return bSUCCESS; // Return success indicator
}
/******************************************************************************
* StartI2C
* I2CADD : Address of I2C slave device (left shifted by 1 bit) + R/W bit
*
* This subroutine initiates an I2C transfer by sending a start condition and
* the slave device address, I2CADD.
*
* Returns 1 : Slave device acknowledged
* 0 : Slave device failed to acknowledge
******************************************************************************
*/
char StartI2C(char I2CADD)
{
SSPIF = 0; // Clear interrupt flag
SEN = 1; // Initiate start condition
while (SSPIF == 0); // Wait until Start condition complete
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CADD; // Send address of slave device
while (SSPIF == 0); // Wait until address has been sent
if (ACKSTAT == 0)
return 1; // Return 1 if device acknowledged
else
return 0; // Return 0 if device didn't acknowledge
}
/******************************************************************************
* ReStartI2C
* I2CADD : Address of I2C slave device (left shifted by 1 bit) + R/W bit
*
* This subroutine sends a ReStart condition to the slave device at address
* I2CADD.
*
* Returns 1 : Slave device acknowledged
* 0 : Slave device failed to acknowledge
******************************************************************************
*/
char ReStartI2C(char I2CADD)
{
SSPIF = 0;
RSEN = 1; // Initiate ReStart condition
while (SSPIF == 0); // Wait until start condition complete
SSPIF = 0; // Clear interrupt flag
SSPBUF = I2CADD; // Send address of slave device
while (SSPIF == 0); // Wait until address has been sent
if (ACKSTAT == 0)
return 1; // Return 1 if device acknowledged
else
return 0; // Return 0 if device didn't acknowledge
}
/******************************************************************************
* StopI2C
*
* This subroutine ends an I2C transfer by sending a Stop condition.
******************************************************************************
*/
void StopI2C(void)
{
SSPIF = 0; // Clear interrupt flag
PEN = 1; // Send Stop condition
while (SSPIF == 0); // Wait until stop condition complete
}
#endif