Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Problem with I2C EEPROM

Status
Not open for further replies.

kyru27

New Member
I think I should be able to read and write the 24LC256 I'm using with the following code:

Code:
#include <p18f4620.h>
#include <i2c.h>

#pragma config WDT = OFF
#pragma config MCLRE = ON
#pragma config LVP = OFF
#pragma config XINST=OFF
#pragma config OSC=INTIO67

#define CLOCK_FREQ		(80000000ul)      // Hz 

void main(void)
{

char data;

OpenI2C(MASTER, SLEW_OFF);

StartI2C();
WriteI2C(0b10100000); //control byte
WriteI2C(0b00000000); //adr hi
WriteI2C(0b00000000); //adr lo
WriteI2C(0x25); //data 0
StopI2C();

StartI2C();
WriteI2C(0b10100001); //control byte (read data)
WriteI2C(0b00000000); //adr hi
WriteI2C(0b00000000); //adr lo
data=ReadI2C();

StopI2C(); 
}

But, by watching data in debug mode, I get an FF instead of the 25 I think should be reading.

I think I've done everything according to the datasheet (http://www.datasheetcatalog.org/datasheet2/7/0yuw0yc3x0278cpz78zge08qi13y.pdf), even exchanging the chip selection bits to 000 or 111 if it might be the problem, and I guess the schematic is right (I'm showing it anyway).

Any idea of what can be wrong?

Thanks.
 
Last edited:
Can't use the delays :(, they enter an infinite loop as in my other question (https://www.electro-tech-online.com/threads/problem-with-sample-spi-transmission.127832/) and nothing can be done... Aren't there more libraries for delay functions except for the predetermined ones of MPLAB C18?

I've tried to work around this problem with the following:
Code:
WriteI2C(0b10100000);
retraso(i);
...

retraso (int i)
{
while (i>0)
{
int j=255;
while (j>0)
{
Nop();
j=j-1;
}
i=i-1;
}
}

And this way to produce a delay, but this has 2 problems:

1) I don't how much time the delay really happens.

2) It also loops indefinitely with some values of i.



Any idea of how this could be solved? Thanks.
 
Last edited:
Write your own..... Its dead simple

Code:
void delayUs( int x )
   {
   while(x--)
      {
      NOP(); /// add these to get 1uS
      }
   }

void delayMs( int x)
   {
   while(x--)
      delayUs(1000);
   }

A while statement has about 3 clock cycles.. A nop() has 1 clock cycle

If you use a 20mHz xtal 1 clock cycle is 200nS
A 4mHz xtal... 1uS

The rest is easy....
 
Last edited:
You can figure out how long the delay is by counting the actual number of clock cycles between loops using a simulator. Why does 20ms seem absurdly long for an eeprom delay?
 
Last edited:
Why does 20ms seem absurdly long for an eeprom delay?

Just being cautious!!! Its normally 5mS for a 400khz device..... but I don't know what he's using... I know the diagram states a 24C256 device... and 100khz is much longer..

We need to find out the fault first.
 
Still doesn't go though I think everything should be alright as I think I've put the correct cycles to execute (as its an INTIO67 t should be 8 Mhz, which implies 500 ns, so for 20 ms, those are 40000 cycles (which are 10*1000*4 cycles to run the delay routine).

My code now is:

Code:
#include <p18f4620.h>
#include <i2c.h>
#include <delays.h>
//#include "key33.h"  

void delayUs( int x );
void delayMs( int x);

#pragma config WDT = OFF
#pragma config MCLRE = ON
#pragma config LVP = OFF
#pragma config XINST=OFF
#pragma config OSC=INTIO67

#define CLOCK_FREQ		(80000000ul)      // Hz 

int main(void)
{
char data;

OpenI2C(MASTER, SLEW_OFF);

StartI2C();
WriteI2C(0b10100000); //control byte

delayMs(10);
WriteI2C(0b00000000); //adr hi
delayMs(10);
WriteI2C(0b00000000); //adr lo
delayMs(10);
WriteI2C(0x25); //data 0
delayMs(10);
StopI2C();



StartI2C();
WriteI2C(0b10100001); //control byte (read data)
delayMs(10);
WriteI2C(0b00000000); //adr hi
delayMs(10);
WriteI2C(0b00000000); //adr lo
delayMs(10);
data=ReadI2C();

StopI2C(); 
}

void delayUs( int x )
   {
   while(x--)
      {
      Nop(); /// add these to get 1uS
      }
   }
 
void delayMs( int x)
   {
   while(x--)
	{
      delayUs(1000);
   }
	}

(This code does an strange thing which is that it might seemingly enter an infinite loop unless you step into the calls of DelayMs function, and run into the breakpoint on delayUs(1000); once you are in, if someone wants to try it).

Everything is as in the schematic (checked with polimeter in the circuit that connections are right) except for pin 7 which doesn't have the resistor and is grounded.

I don't know what else to do... Hope anyone has an idea.


PD: Also tried changing the chip select bits to 111 but nothing.
 
Last edited:
Stick two LEDs on the scl/ sda lines and use a debugger to step through your code, you will soon find where your problem lies. I hate using libraries where all the 1's and 0's are taken care of for ya :)
 
Stick two LEDs on the scl/ sda lines and use a debugger to step through your code, you will soon find where your problem lies. I hate using libraries where all the 1's and 0's are taken care of for ya :)

I'm already using debug mode and this is where I find that data is FFh instead of 25h, if the LEDs are for checking voltage is coming I already checked it with the polimeter, although, perhaps, you might be refering to something else.

Thanks.
 
I'm already using debug mode and this is where I find that data is FFh instead of 25h, if the LEDs are for checking voltage is coming I already checked it with the polimeter, although, perhaps, you might be refering to something else.

Thanks.

In my experience, 70% of the folks I have seen having problems with I2C have a state change happening when they didn't expect it. Obviously there are many possible causes for it, however the fact remains. 25% seem to have no patience to wait for a write cycle to complete, and the remainder have some other mid packet, or subtle timing problem, usually device dependent :)

Just slowly stepping through the code with a couple of LED's on the lines allows you to visually see what's going on. It's equally possible that one of the lines is changing state when you don't expect it to, rather than a delay issue, and doing this instantly shows you where in your code it's happening. Unless that is, you are 100% certain that this is not the case. Using programmers, debuggers and logic probes etc is all well and dandy, but it all takes time setting up, running tests etc, sometimes the simplest observation short cuts all that pain :)

Get yourself a pencil and a piece of paper and jot down what's happening visually, then see if it follows what you expect. If it does then great, you can concentrate on subtle timing problems :)
 
OK!!!!

Faults.....
1) you defined your XTAL at 80mhz... not 8mhz ( this is probably why your delays didn't work )
2) You need to set the OSCCON register to 8mhz as well
3) Your ReadI2C routine should be like this

Code:
   StartI2C();
   WriteI2C(0b10100000); // control byte (write data)
   WriteI2C(0b00000000); // adr hi ( set read )
   WriteI2C(0b00000000); // adr lo ( address )
   RestartI2C();		  // correct read of I2C requires a restart!!!
   WriteI2C(0b10100001); // control byte (read data)
   data=ReadI2C(); 
   StopI2C();

Lastly (not important).. most memories can run at 400khz, so "SLEW_ON" when initiating the I2C.

Your code wrote 0x25 to the eeprom..... but the read command was faulty.
 
Last edited:
Thanks a ton for your answers and helping me.

Just one thing, trying to set the OSCCON for 8 Mhz makes the code to hang up when doing the second WriteSPI at least for me (I have tested it with values 0x70, 0x71 and 0x72 in case the last two bits had something to do). Anyway it works nicely without having it set, so I'm not into trying to know why this happens as long as it works, but I want to write this just in case anyone finds this problem.
 
I don't use anyone else's I2C routines.... I use my own. The OSCCON can be set with 0x70 ( 8mhz) ...0x60 ( 4mhz).... 0x50 (2mhz) ... etc...

The rest of the OSCCON is for stabilizing flags and external controls.. The chip defaults to 1mhz if you don't use it , so you can set the frequency variable to that.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top