PIC16F819 External EEPROM (24LC64) with CCS C problem

Thread Starter

omar2211

Joined Oct 23, 2019
11
Hello,
it's my first time playing around with external eeproms (ik this chip has internal eeprom but I want to experiment with external eeproms)

I have a test setup where my chip connected to an LED and a button. so when I click the button a value (ex.: 5) should be written on my eeprom and then the LED will turn on for the value saved on the eeprom (5 seconds).

anyways my problem is always with the write command where it just stops and never goes forward in the code. even without connecting my eeprom it does the same.

I am using the latest version of CCS C 5.1. will attach my C and 2464 files.

Mod edit: changed title to match EEPROM in use- JohnInTX
 

Attachments

Last edited by a moderator:

Ian Rogers

Joined Dec 12, 2012
966
I never had any luck with "ext_eeprom_ready()"
I just use a 20mS delay after the write function and a 1mS after the read..

To test if the ready function is causing a problem do this

C:
BOOLEAN ext_eeprom_ready() {
   /*int1 ack;
   i2c_start();            // If the write command is acknowledged,
   ack = i2c_write(0xa0);  // then the device is ready.
   i2c_stop();*/
   delay_ms(20);
   return 1;  //  Bodge to check.
}
 

Thread Starter

omar2211

Joined Oct 23, 2019
11
I never had any luck with "ext_eeprom_ready()"
I just use a 20mS delay after the write function and a 1mS after the read..

To test if the ready function is causing a problem do this

C:
BOOLEAN ext_eeprom_ready() {
   /*int1 ack;
   i2c_start();            // If the write command is acknowledged,
   ack = i2c_write(0xa0);  // then the device is ready.
   i2c_stop();*/
   delay_ms(20);
   return 1;  //  Bodge to check.
}
Yes it is the problem!! what should I do then ?
 

Thread Starter

omar2211

Joined Oct 23, 2019
11
I never had any luck with "ext_eeprom_ready()"
I just use a 20mS delay after the write function and a 1mS after the read..

To test if the ready function is causing a problem do this

C:
BOOLEAN ext_eeprom_ready() {
   /*int1 ack;
   i2c_start();            // If the write command is acknowledged,
   ack = i2c_write(0xa0);  // then the device is ready.
   i2c_stop();*/
   delay_ms(20);
   return 1;  //  Bodge to check.
}
I found this driver which should be prefect for the one I have 24LC64. YET IT IS NOT WORKING
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,628
Have you written '0' to the SDA and SCL output pins during init? The bit-bang code implies that it drives the line by toggling the TRIS bits from input (pulled up to 1) to output (driven down to 0 by the port). Write the 0s to the port after setting the TRIS lines to 1 to avoid transients that can confuse the EEPROM.

If you can set a breakpoint right after 'init', verify both SDA and SCL are 1. After i2c_start(), verify that both are '0. That would at least confirm that the pins are wiggling.

After that, call i2c_init() then ext_eeprom_ready() and verify that it returns 'ready'.

Once you get something working, I would revisit the 'EEPROM busy' code. Hanging the code waiting on an IO operation is a big no-no.

Good luck!
 

Pushkar1

Joined Apr 5, 2021
416
1) Always use code tag to post code Do not post code in PDF.

2) Have you verified the eprom address while sending it from microcontroller,
 

Ian Rogers

Joined Dec 12, 2012
966
Edited your library.. Try this one..

C:
///////////////////////////////////////////////////////////////////////////
////   Library for a 24LC64 serial EEPROM                              ////
////                                                                   ////
////   init_ext_eeprom();    Call before the other functions are used  ////
////                                                                   ////
////   write_ext_eeprom(a, d);  Write the byte d to the address a      ////
////                                                                   ////
////   d = read_ext_eeprom(a);   Read the byte d from the address a    ////
////                                                                   ////
////   The main program may define eeprom_sda                          ////
////   and eeprom_scl to override the defaults below.                  ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

#ifndef EEPROM_SDA

#define EEPROM_SDA  PIN_B1
#define EEPROM_SCL  PIN_B4

#endif

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE   8192

void init_ext_eeprom()
{
   output_FLOAT(EEPROM_SCL);
   output_FLOAT(EEPROM_SDA);
}

void write_ext_eeprom(long int address, BYTE data)
{
   short int status;
   i2c_start();
   i2c_write(0xa0);
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();
    i2c_stop();
   delay_ms(20);
}

BYTE read_ext_eeprom(long int address) {
   BYTE data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}
 

Thread Starter

omar2211

Joined Oct 23, 2019
11
Edited your library.. Try this one..

C:
///////////////////////////////////////////////////////////////////////////
////   Library for a 24LC64 serial EEPROM                              ////
////                                                                   ////
////   init_ext_eeprom();    Call before the other functions are used  ////
////                                                                   ////
////   write_ext_eeprom(a, d);  Write the byte d to the address a      ////
////                                                                   ////
////   d = read_ext_eeprom(a);   Read the byte d from the address a    ////
////                                                                   ////
////   The main program may define eeprom_sda                          ////
////   and eeprom_scl to override the defaults below.                  ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

#ifndef EEPROM_SDA

#define EEPROM_SDA  PIN_B1
#define EEPROM_SCL  PIN_B4

#endif

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE   8192

void init_ext_eeprom()
{
   output_FLOAT(EEPROM_SCL);
   output_FLOAT(EEPROM_SDA);
}

void write_ext_eeprom(long int address, BYTE data)
{
   short int status;
   i2c_start();
   i2c_write(0xa0);
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();
    i2c_stop();
   delay_ms(20);
}

BYTE read_ext_eeprom(long int address) {
   BYTE data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write((address>>8)&0x1f);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}
Just tried that! the code went on and is working. But the numbers saved on the eeprom is not correct. It should write on the address value 5 which means when it delays it should delay for 5 seconds (5 * 1000). So basically now it moves on with the code but the eeprom is not doing its job which is saving values. Thanks for the fix and your help. If you got any other idea I would love to hear from you!
 

Ian Rogers

Joined Dec 12, 2012
966
You need to check to see if your compiler can do that...
Usually the delay needs a constant and not a variable...
delay_ms( constant );
So a variable may not work.
delay_ms( add*1000 );

The other thing that bothers me is.. If your eeprom IS giving wrong values, then that probably why the busy doesn't work!
Is the SDA pin being held low by something??
 
Top