Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help me fix I2C code in Proteus

Status
Not open for further replies.

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
 

proteus i2c sequence file

I don't analyze deap your code but , in general seams ok. Do you put the pull-up resistor at SDA and SCL lines?
Use proteus logs to view if the eeprom is receiving the start and stop conditions. I'll try to watch your code better during the night.
 

proteus sda scl

HUPS...:!!!!
Reading better the PIC16 model help, I view:

I2C not modelled - assignment to SSPCON2 only stores value.
I2C not modelled - assignment to SSPADD only stores value.
I2C not modelled - read of SSPCON2 only returns current value.
I2C not modelled - read of SSPADD only returns current value.

The PIC model does not model the I2C mode of the MSSP.
Writing to the SSPCON2 or SSPADD registers simply stores the written value in the register and does not instigate any other action.
Reading the registers returns their initial values or the value last written to them.




SO is explained.....

SDA, SCL, have pull up, thx Elavionic

ThX

NeuralC
 

proteus i2c

hi friend


a better example is already in proteus how to interface 12c with pic see sample file , altough you have get rid the problem by reading of pic16dll
help file
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top