3
\$\begingroup\$

Im trying to store some data in the 24AA01 EEPROM using the PIC18F13K22. Since I am awaiting the components, I thought I will go ahead and simulate it in Proteus.

Schematic

This is my code (XC8 compiler based).

#include <xc.h>
#include "config.h"
#include "uart.h"

void i2c_writebyte(char x);
char i2c_readbyte();

void main(void) {
    OSCCON = 0x43;  //2Mhz
    TRISBbits.RB4 = 1;
    TRISBbits.RB6 = 1;
    TRISCbits.RC5 = 0;
    LATCbits.LATC5 = 0;   //Low to Enable Writing

    SSPADD = 4; //100kHz
    SSPSTAT = 0x80;
    SSPCON1 = 0x28;

    char a = 'y', c;

    uart_init();

    i2c_writebyte(a);

    c = i2c_readbyte();

    print(c, 1);

    LATCbits.LATC5 = 1;   //High to disable Writing
    while(1);
    return;
}
void i2c_writebyte(char x){
    try:

    SSPCON2bits.SEN = 1;    //Start bit
    while(SSPCON2bits.SEN != 0);

    SSPBUF = 0xA0;
    while(SSPSTATbits.BF != 0);
    while((SSPCON2 & 0x1F) || (SSPSTAT & 0x04));
    if (SSPCON2bits.ACKSTAT !=0){
    print("1", 1);
    return;
}

SSPBUF = 0x0;   //Address
while(SSPSTATbits.BF != 0);
if (SSPCON2bits.ACKSTAT !=0){
    print("2", 1);
    return;
}

SSPBUF = x;   //Byte
while(SSPSTATbits.BF != 0);
if (SSPCON2bits.ACKSTAT !=0){
    print("3", 1);
    return;
}

SSPCON2bits.PEN = 1;    //Stop bit
while(SSPCON2bits.PEN != 0);
}

char i2c_readbyte(){
    char x;
    try:
    SSPCON2bits.SEN = 1;    //Start bit
    while(SSPCON2bits.SEN != 0);

    SSPBUF = 0xA0;
    while(SSPSTATbits.BF != 0);
    if (SSPCON2bits.ACKSTAT !=0){
    print("4", 1);
    return;
    }

    SSPBUF = 0x0;   //Address
    while(SSPSTATbits.BF != 0);
    if (SSPCON2bits.ACKSTAT !=0){
    print("5", 1);
    return;
    }

    SSPCON2bits.SEN = 1;    //Start bit
    while(SSPCON2bits.SEN != 0);

    SSPBUF = 0xA1;
    while(SSPSTATbits.BF != 0);
    if (SSPCON2bits.ACKSTAT !=0){
    print("6", 1);
    return;
    }
    SSPCON2bits.ACKDT = 1; 
    SSPCON2bits.RCEN = 1;
    while(SSPSTATbits.BF == 0);
    x = SSPBUF;
    SSPCON2bits.ACKEN = 1;

    SSPCON2bits.PEN = 1;    //Stop bit
    while(SSPCON2bits.PEN != 0);

    return x;
}

I use the UART to tell me at what point the ACK was not received. The oscilloscope also confirms that when I check the waveform.

Waveform

Why isn't the EEPROM providing an ACK? Is it a simulation bug or am I doing something wrong?

Changing the pull-ups to 10k and 4.7k had no effect as well. I used an I2C debugger to see if the correct data was going but I saw something like this. Can anyone help me intepret this?

I2c Debugger

\$\endgroup\$
5
  • \$\begingroup\$ I don't have time to review your code, but I notice that your I2C pull-up resistors are very low value (i.e. "strong") with a value of 1k. Please change both those resistors in the simulation to 4k7 or 10k, re-test, and update the question at the bottom with the result of that test, so all readers can see that result easily. \$\endgroup\$
    – SamGibson
    Commented Nov 2, 2016 at 15:23
  • \$\begingroup\$ It created no change. \$\endgroup\$
    – hp07
    Commented Nov 2, 2016 at 15:26
  • \$\begingroup\$ @Sam a 100k worked for some reason \$\endgroup\$
    – hp07
    Commented Nov 4, 2016 at 14:50
  • \$\begingroup\$ "100k worked for some reason" - As Scott also mentioned in a comment on your answer, in real life, that is not a sensible value for I2C pull-ups. This suggests that there is a problem somewhere in the simulation you were using. \$\endgroup\$
    – SamGibson
    Commented Nov 4, 2016 at 16:28
  • \$\begingroup\$ FYI - Although I have not used Proteus for a long time, I found this previous EE.SE question "I2C pullup resistors not working in simulation" which suggests that I2C pull-up resistors cannot necessarily be simulated as normal resistors in Proteus. \$\endgroup\$
    – SamGibson
    Commented Nov 5, 2016 at 0:29

1 Answer 1

0
\$\begingroup\$

Solved ... to anybody who has this problem - change the pull ups to 100k and it works like a charm.

I request the Op to archive this question so that the code can be used by others who might need it.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 100k is simply a whacky number for an I2C pullup. \$\endgroup\$ Commented Nov 4, 2016 at 15:05
  • \$\begingroup\$ I know, thats why i didnt try it in the beginning \$\endgroup\$
    – hp07
    Commented Nov 4, 2016 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.