Easy 24C I2C Serial EEPROM Interfacing with AVR Microcontrollers
In this turorial we will see how we can easily interface a 24C series serial EEPROM with AVR microcontrollers.
What is an EEPROM?
An EEPROM is kinds of novalatile memory, that means it is used for storing digital data permanently without any power suply. EEPROM stands for Electrically Erasable Programmable Read Only Memory. The advantage of these kind of ROMs is that they can be erased Electrically to make them ready for storing new data. Compare this with a CD R disks they can be recorded only once. A small amount of EEPROM is also available internally on the AVR chips. So if the volume of data you want to store is small (say few user names and password) then you can use it. The internal eeprom makes design small and simple.
But if the amount of data you want to store is large, say in order of few tens of kilobytes then you have to interface a External EEPROM chip with your AVR MCU. You can store pictures, sound and long texts in these eeproms.
Their are many kinds of EEPROM chip available from many manufactures. One very common family is 24C series serial EEPROMs. They are available upto 128KB in size. They uses I2C interface with host controller (MCU) which is a very popular serial communication standard. I will write more indept tutorial on I2C in comming days and in this tutorial I will give you easy to use function that you can use without any knowledge of I2C interface.
In this tutorial we will be using 24C64 EEPROM chip which has 8192 bytes = 8 KB = 8x1024 bytes of data storage.
The chip has storage location which have their unique address ranging from 0-8191. Consider these as storage cells so while storing and retriving data you have to tell the chip which cell location you want to read.
![]() |
Fig. : Storage Cells inside the 24C64 EEPROM Chip. |
For exaple if you read location 0003 you will get 99 (see image above). Note each cell can store 8BITs of data so range you can store is 0-255 (-128 to +127). So if you want to store bigget data like int you have to store them in two cells.
Hardware Setup
Connect your ATmega32 with 24C64 chip as shown in the circuit diagram. You can use any avr development board for the purpose or assemble the whole circuit in a Breadboard or Veroboard.
Fig. : Circuit Setup for 24C64. |
Software Setup
Download and add the following files to your AVR Studio project. Now you can use the following functions for EEPROM interfacing.
- 24c64.h
- 24c64.c
| EEOpen() |
Arguments - None Returns - Nothing Description: This function should be called before any read/write operation. This functions initialize the communication channel. |
| EEWriteByte(unsigned int address,uint8_t data) |
Arguments
Returns
Description: Use this function to store a 8bit value in any EEPROM storage cell. |
| EEReadByte(unsigned int address) |
Arguments
Returns
Description: Use this function to read a 8bit value from any EEPROM storage cell. |
Sample Program.
The following sample program demonstrate the use of external EEPROM interfaing functions. The program makes use of the LCD library for AVRs to display information in a 16x2 LCD display. The program first writes 8Kbytes of data to a 24c64 eeprom to fill the whole eeprom with '7' and then it reads back to see if all the location has 7. If the condition is met the screen shows "Write Successfull" message.
I have used my xBoard - An Advance ATmega32 development board to test the routines. You can use any devboard with ATmega16 or ATmega32 MCUs. The 24C64 was mounted on a Breadboard.
![]() |
Fig. : 24C64 Serial EEProm Interface with ATmega32. |
The 5v,GND,SDA,SCL were connected to the xBoard development board.
![]() |
Fig. : xBoard with MCU ATmega32. |
![]() |
Fig. : Output of 24C64 test program. |
/*
A sample program to test the Extrenal EEPROM interfacing
routines. The program fills the whole EEPROM with 7 and
then reads the whole EEPROM memory to see if all of them
contains 7.
This helps in quick testing of you hardware /software before
using these routines in your own programs.
The target for this program is ATmega8, ATmega16, or ATmega32
running at 16MHz. If you use slower crystal the program will
simply run slow but without any problems.
This program also makes use of eXtreme Electronics 16x2 LCD
Interfacing routines. See the related page for more info
Author : Avinash Gupta
Date : 16 March 2009
Mail : me@avinashgupta.com
Web : www.eXtremeElectronics.co.in
NOTE: IF YOU USE THIS LIBRARY IN YOUR PROGRAMS AND FINDS
IT USEFUL PLEASE MENTION US IN CREDIT AND RECOMEND OTHERS.
*/
#include <avr/io.h>
#include "util/delay.h"
#include "24c64.h"
#include "lcd.h"
/**********************************
A simple delay routine to wait
between messages given to user
so that he/she gets time to read them
***********************************/
void Wait()
{
uint8_t i;
for(i=0;i<100;i++)
_delay_loop_2(0);
}
void main()
{
//Varriables
uint8_t failed;
unsigned int address;
//Initialize LCD
LCDInit(LS_BLINK);
//Init EEPROM
EEOpen();
_delay_loop_2(0);
LCDClear();
LCDWriteString("External EEPROM");
LCDWriteStringXY(0,1,"Test");
Wait();
LCDClear();
LCDWriteString("Writting...");
//Fill whole eeprom 8KB (8192 bytes)
//with number 7
failed=0;
for(address=0;address<8192;address++)
{
if(EEWriteByte(address,7)==0)
{
//Write Failed
LCDClear();
LCDWriteString("Write Failed !");
LCDWriteStringXY(0,1,"Addess = ");
LCDWriteInt(address,4);
failed=1;
Wait();
break;
}
}
LCDClear();
if(!failed)
LCDWriteString("Written 8192bytes");
Wait();
LCDClear();
LCDWriteString("Verifying ...");
//Check if every location in EEPROM has
//number 7 stored
failed=0;
for(address=0;address<8192;address++)
{
if(EEReadByte(address)!=7)
{
//Failed !
LCDClear();
LCDWriteString("Verify Failed");
LCDWriteStringXY(0,1,"Addess = ");
LCDWriteInt(address,4);
failed=1;
Wait();
break;
}
}
if(!failed)
{
//We have Done it !!!
LCDClear();
LCDWriteString("Write Success !");
}
while(1);
}
Note On Installing 16x2 LCD Module.
The LCD Module can be easily installed with AVR ATmega32 as the sample program supports it. The connection is simple. Connect the LCD to your ATmega32 as shown below. For Finding out location of PINs such as PC7,PC6,PB4 etc see the ATmega32 datasheet. The LCD must be installed to see the output of the program. After powering on the circuit please adjust the 10K POT until the display is clearly visible.
I strongly recommend you to see the LCD Interfacing Tutorial and Setup and run some LCD demo code to be sure that LCD is working correctly.
![]() |
Fig. : LCD Interface with ATmega32. |
Downloads
All the required files for 24C eeprom interfacing with AVR MCUs.






Hi Avinash,
I am thinking of ATMega16 to use for sending data to a transmitter for testing purposes. Should I use EEPROM to store the data to be sent or can I just directly write the data in program and it randomly stores and sends it? And is there an easy way to do it for big data (for ex. with arrays) or should I do it byte by byte?
March 20th, 2009 at 5:25 pmHello Fortune,
You can use a EEPROM such as 24C64 (8Kbytes) or 24C1024 (128Kbytes) to store that data. Read them byte by byte in loop and transmit. I think 128K byte of data would be enough.
March 20th, 2009 at 6:40 pmHi Avinash,
March 21st, 2009 at 4:44 amThank you very much.I really appreciate your effort and help!
Hi look your email to see my lib
March 22nd, 2009 at 3:18 pmWaht about if you don’t have SCL SDA Port, for example
if We need maybe PB5 and PB6 (without TWI register)?
best regard and thanks for nice work
March 23rd, 2009 at 4:48 pmI just need to output 256bytes. I need to output them serially. I have just thought to write it in the program in a loop using if the corresponding bit is 1
if(data[i]&(1<<n)) //n is the current bit # in progress
PORTA|=(1<<output);//output is the pin used for serial comm.
is this correct and enough? do I need a delay between every bit/byte? and what will be the baud rate(ATMega16) as default if i dont do any init.? (I want Baud ca. 1Kbit/s)
March 23rd, 2009 at 8:33 pmHi,
March 24th, 2009 at 4:07 amWhat is the value of the resistors connected to the 24c64.It
says 4k7.What does that mean?
@Fortune,
You have a lots of confusion. First you are manualy sending just bit by bit to a port. In that way you cannot do RS232 communication. No device (such a PC) will be able to make anything out of that varrying voltage on a PIN.
Their is a STANDARD for RS232 communication.
You are talking about BAUD rate and you are NOT AT ALL USING THE USART. The baud rate is assosiated with USART.
and 1Kbit/s is not a standrad baud rate.
PLEASE GO THROUGH THE SUBJECT BEFORE ASKING.
SEE
March 24th, 2009 at 6:57 amhttp://extremeelectronics.co.in/avr-tutorials/rs232-communication-the-basics/
@Mozard
4k7 = 4.7k = 4.7 Kilo Ohms = 4700 Ohms
Got it
its just a standard way in commercial electronics!!!
Remember that from now.
March 24th, 2009 at 6:59 amHi Avinash again
,
first of all I dont want to send the data using RS232 but via a normal port like portA. I said serial comm. technically while I will send them bit by bit using just one pin of a port.
March 24th, 2009 at 3:28 pmI may have used the baud rate wrong but I wonder to know in what freq. I output the bits in the Port? As I know default freq. of ATMega16 is 1Mhz, but my output freq. will be less than 1MBit/s while one output op. takes more cycles than 1???
Sorry for putting on too much confusion..
Hi Avinash,
March 25th, 2009 at 1:11 amI am trying to read data from a file and then store the data in the 24C64.Do you have any idea how this could be implemented? I am trying to use fopen for file reading, but it is not working.Any help would be appreciated.Thank you..:)
Hi everyone,
I need some help with I2C protocols. I want to store my program in an external I2C Memory AT24C512, and execute the program from there.
But i am clueless on how to go about, i know about the i2c read and write cycles
March 25th, 2009 at 6:51 pmAVR MCU does not support execution from external memory.
One way you can go is to write a bootloader that first loads the program form external memory to internal flash then start execution. See datasheets
March 26th, 2009 at 10:24 amactually i am working with 8052. can you give me some suggestion for i2c interface with 8052.
March 26th, 2009 at 2:34 pmthank u
Hello Avinash, I saw your code you are doing interfacing LCD with Atmega32. Was wondering if you help me to get started with Interfacing EEPROM(25AA1024 I/P ) and Real Time Clock (DS1305) with ATmega32 using 3-wire SPI. I did all the wiring on breadboard let me know if you want to know which pins i am using.
April 13th, 2009 at 12:29 pmThanks
cheers,
Romil
hi
April 24th, 2009 at 8:45 pmiusing eeprom in rfid project with 1mb (sst25f016b)interfacing to atmega32using spi and ineed ur help to start cod
Hello Avinash,
May 2nd, 2009 at 11:17 amThere is very valuable notes on AVR microcontroller. I started with ATMEGA8 and I connect it with external crystal oscillator, of 8 MHz, but I think it is work on internal oscillator. I search for that then i found that thee is a fuse bit, please tell me about fuse bit ant how can i programme fuse bit. At present i use AT-PROG ( Parallel port, with two resistors directly connected to IC).
Thanks
Kapil
Fuse byte info here
May 2nd, 2009 at 4:19 pmhttp://forum.extremeelectronics.co.in/viewtopic.php?f=2&t=24
hi, i am trying to interface atmega 16 with at8052, where 8052 is the master which is connected with RTC(DS1703) ATmega16 is a slave i am not able to interface ATmega16 with AT8052, there is some problem in slave coding, please can you help me in coding of ATmega 16 as a slave mode ,
July 1st, 2009 at 8:28 amhi avinash..
August 3rd, 2009 at 2:11 pmI am using 24C04. I modify address limit as 4096. I am using your I2C library with ATmega32. My program is running upto lcdstring(“Writting…”). But its not running or somewaht else after this. I didnt used 4K7 pullups are they very necessary. Plz Clarify
hi…
August 3rd, 2009 at 2:15 pmWhat should be the DDR values for PORTC as we are using SCL & SDA.
@Devesh
August 3rd, 2009 at 6:51 pmYes in I2C pullups are required. Without it it won’t work
It didn’t work with proteus
August 11th, 2009 at 6:05 amanyone knows why???
It gets stuck in the command writting…
In proteus u have to remove two pull up resistors (4.7K)
but in real case use them
August 11th, 2009 at 8:18 amthanks Avinash,
August 11th, 2009 at 1:54 pmI already tried that,
but even so, it didnt work
can you help me on this…
hi avinash..
August 17th, 2009 at 8:43 pmI am using AT24C04 what kind of modification i should do in your code to make it compatuble to 24C04.
@Devesh,
Use without any modification
August 18th, 2009 at 7:59 amhi avinash,
thats a good tutorial
i want to interface atmega 16 with eeprom, but only on avr studio first, also i need to store 120K data on it, can u help me in it, as in which eeprom better, which ports of eeprom connected to scl,sda for i2c and more
September 8th, 2009 at 1:08 pmHi Avinash,
I have a couple of questions
1) I want to transmit data bit by bit to flash memory and store it in an empty array. I already have used your tutorial on RS232 and I have got data transmitting.
But I can’t get it to store in the appropriate array. Should I use a buffer, like in EEPROM or something or should I store it directly.
The transmission rate is not a problem for the project im using it for.
Thanks
September 9th, 2009 at 5:26 pm@Kushal
September 12th, 2009 at 8:35 amuse 24C1024 EEPROM it has a capacity of 128KB
Hi Avinash,
Wikipedia says in their I2C overview that each slave on the I2C bus has an address and in turn there could be multiple slaves connected to the bus. How do I set or learn the address of the 24Cxxx chip? And how to connect if I want to have more than one of these eeproms attached? How do I address them?
Thanks
September 12th, 2009 at 6:23 pm@Michal,
Very good question. Yes thats the beauty of I2C bus. Each slave on it have a unique address, thus many slaves can be connected in parallel in same bus lines. the address in I2C bus is 7 bit (the last bit is Read/Write select bit) so as many as 128 I2C slave can be connected in i2c bus.The 24C series has the address in form of [MSB]1,0,1,0,A1,A2,A3[LSB] where A1,A2,A3 can be set to proper state by using 3 pins on the chip. So as many as 8 24C eeprom can be connected in a bus.
In the above example I have not connected A1,A2,A3 (this means the are 0, 0, 0) to keep it simple. For more details see data sheet.
September 13th, 2009 at 8:18 amHi Avinash
October 30th, 2009 at 6:00 amvery good effort ,i want to make one master(atmega32)read & write with 3 slaves (atmega32), how can i send and recieve data from them.
Dear sir, if possible please provide tutorial on interfacing micro Controller, with other micro controller using I2C/ twi,
October 30th, 2009 at 11:41 am@sridhar – what you probably need is a multi-master i2c setup where each MCU can asynchronously send data to any other i2c device on the bus. Google for “i2c multi-master” and you’ll get a number of useful links.
@mohamed – do you mean 3 ICs writing into the eeprom and one IC reading it? In that case you’ll probably need multi-master as well.
Both of you guys could get away with just one bus master but then the setup would need an interrupt line from each slave, alerting the master that there are data to be processed. The master will then issue a read command to the slave, fetch the data and process. It really depends on what you’re trying to achieve. Whether to choose single-master or multi-master depends on circumstances.
October 31st, 2009 at 4:23 ami make wide search but i didnt find interfacing two avr ,i find avr with another devices such as eprom,could u Nominate me web site
October 31st, 2009 at 6:28 am@Michal
Thanks for helping out Sridhar
October 31st, 2009 at 8:14 amthank you 4 all for helping out,
October 31st, 2009 at 9:59 amhere i am using single-master, i.e one master need to read multi slave, but all the slave is of same Atmega 8 as well as master,
ya, iam trying on google but links are not helping out much.,
if any one tried the same please help me out.
thank you for ur caring,
October 31st, 2009 at 10:11 amwhat i want to do is only one master(atmega32)read & write with 3 slaves (atmega32)
hey guys where r u???????
November 18th, 2009 at 9:38 amIf we says A1,A2,A3 are used to unique address makeing:
1. only in 24c01,24c02 -> 8 IC’s
December 2nd, 2009 at 7:29 pm2. 24c04 has two pages switched by A3 -> 4 IC’s
(simply you can without changing code change 1*24c04 into 2*24c02)
3. and go on….
thank you for your web.but i dont know how to connect thw wire to real lcd.because in real lcd we have 16 socket.but in diagram lcd we have 14.please help me.thank
January 3rd, 2010 at 3:30 am@Ali
The PCB of the LCD has the PIN names. From that you can clearly see that the last two pins 15 and 16 are connected to the LED backlight !!!
January 3rd, 2010 at 9:13 amhi avinash
January 8th, 2010 at 10:53 pmamazing tuts !!!!!!!
i want to store a set of words in eeprom . as per your file it enables the storage of only int datatypes. can i store strings by just changing the datatype of the argument in the functions. or shld i make anyother change
Dear sir,
January 9th, 2010 at 11:07 amI am using AVR micro controller, atmega 16, in need to communicate TWi interface with other micro controller,
I am using code vision for the complier.
I tried the code which is given in atmel application 311,312, etc but it was not working may be I could not properly analyze,
So, I built the RTC interface for DS1307 it was working with the Code vision in built library , so I have taken only the read format of the RTC and I tried to implement the slave,
With
START();
Write address();
Start();
Write location();
data=read data();
Return data;
By this code I was able to get data from the RTC,
So I thought to go with reverse engineering/programming to send a data to the master as the slave microcontroller need to act as RTC for only this particular code, but still it is not working,
Please if u have any such general implication of the i2c master and slave code please help me,
Hi Avinash!
Your EEPROM libraries are awesome! I am new to AVR’s though I have worked in PIC n 8051! But from scratch I could learn AVRs in a week!!! Thanks to all your efforts to build code libraries and projects that teaches a novice end to end in a short span of time!!! All the contents you have given are so useful, that I am working on a product with all the support libraries and schematics you have furnished in your site.
January 26th, 2010 at 12:43 pmhi,
February 13th, 2010 at 3:15 pmi tried reading RTC registers after every 1sec but it fails to update time on LCD. At power on-reset only once it display the time but after it is not updating time. Please help me.
thank u
hi avinash!
great tutorial, now i want to interface EEPROm with LPC 2148 controller can you help me for that?
February 26th, 2010 at 5:41 pmhi i’m vinod a final b.e student .i’m using a 24c32serial eeprom in my project iwant to know whether the eeprom cn erased by using code if so can i get what instructiona to be used
March 16th, 2010 at 6:02 amdear avinash ,
March 24th, 2010 at 2:10 pmi have gone through ur code and its working fine. i have one doubt that why u have used a dummy writing sequence inside the function readbyte().
and one more doubt isi have written 0×0A address with some value but all locations including 0xA0 shows the same value. what is the reason ?
plz reply me soon.
See 24Cxx datasheet. It is required .
March 24th, 2010 at 4:19 pmits there in your code. if anything wrong plz send me the exact code. my id is paltu4u@gmail.com
March 26th, 2010 at 12:58 amThanks my frind
May 19th, 2010 at 8:01 amThank for this Library, i using it on my projects.
July 1st, 2010 at 12:33 pmHere is I post your library with comments on russian on my own site.
http://avrlab.com/node/84
@AVR Lab
You have not provided any link to the original source?
Please provide a link to this page.
July 3rd, 2010 at 9:29 am