Thursday, August 14, 2008

Interfacing RTC & serial EEPROM using i2c bus, with ATmega128 uC



Hi friends,
here is my experiment with i2c bus for interfacing serial EEPROM (24C256) and RTC (DS1307) using AVR microcontroller ATmega128. The circuit is also provided with an RS232 port for connecting with PC to send commands for reading/writing EEPROM or setting date/time in RTC. (Click on images to enlarge them)

communication with PC is done through Hyper Terminal. A screen shot of the message sent to PC by microcontroller immediately after power ON is shown in the figure at the left, where the user is asked to enter choice from the menu options related to EEPROM and RTC. User can store data in EEPROM, or set RTC date and time by entering them using PC keyboard.
Hyper Terminal is used with 19200 Baud, No parity, No hardware flow control settings.

When the circuit is powered on, a welcome message is displayed on the Hyper Terminal window and a menu with 9 options (0-8) is displayed (refer to the figure). The options are explained here:

0: Erase EEPROM (fills eeprom with 0xff bytes)
1: Write EEPROM (starts writing eeprom starting with 0x0000 address)
2: Read EEPROM (reads eeprom starting with 0x0000 address)
3: Write eeprom page (writes one page of eeprom at specified page number)
4: Read eeprom page (Reads one page of eeprom at specified page number)
5: Display RTC Date (Displays current date from RTC)
6: Display RTC time (Displays current time from RTC)
7: Update RTC Date (Setting new date in RTC)
8: Update RTC time (Setting new time in RTC)

The option is selected from PC keyboard. While writing to eeprom or RTC the data is entered using PC keyboard as specified by the program.

The software routines include DS1307 library, 24C256 library & I2C library along with the main function.

The code is written in C using winAVR (inside AVRStudio). The complete project folder can be downloaded here in zip format (updated on 25-April-2009, earlier it was in ICCAVR format):

Download Complete Source code


Download datasheets:
ATmega128 DS1307 FM24C256 MAX232

Thanks!

(last updated on 25-April-2009)
---------
ccd@dharmanitech.com

62 comments:

manojkumar said...

Hi Dharmani, this is manoj. I want to know its function and brief explanation of the circuit if possible. And send the library function u have created, i will try to understand it. My ID manojlenin@gmail.com

Bina said...

Hi Dharmani, Iwanto try your project would you send me the complete files to bina.pratomo@yahoo.co.id
Thanks.

CC Dharmani said...

Thanks for your interest,guys!! I've sent u the program files, hope u find them useful.. post here if any doubt is there..
Thanks.

aries said...

hi...i'm interested in this EEPROM..By the way, can i use it in Microchip PIC?
Please send me the files at bbs_aries@yahoo.com for me to try it..thanks

CC Dharmani said...

Hi Aries,
yes, you can use PIC micro with this EEPROM. Actually, any microcontroller having i2c bus can be interfaced with this EEPROM.
I've sent you the files, they'll need some modifications as they're written for AVR controller.
Thanks!

CC Dharmani said...

Hi Henric,
I've sent you the source code and header files (total 6 files, zipped) at your mail id. Mail me or put up a comment here if any problem in receiving or any remarks about the libraries.

Regards.

CC Dharmani said...

To Hossein:
Hi, I've sent you the complete source code in zip format, as u requested by mail. If any problem in receiving the files, put up your comment here or write to me.

Regards.

Anonymous said...

Hi Dharmani, I want to try your project. would you like to send me the complete files to andi2302@gmail.com
Thanks.

CC Dharmani said...

Hi 'andi',
I've sent you the code on your email id, check it out!

Regards.

CEEJAY said...

Hi Dharmani, this is Chetan from Mumbai.. I'm working on a project which involves Atmega128 and the storing of incoming data into its memory with the corresponding real time value. For this i wish to use the in-built RTC system at timer/counter 2 of Atmega128. But as it seems for your project, you have used an external RTC 'DS1307'. So, i was wondering if the internal RTC would lead us into some bugs. Would you guide us with the above confusion and suggest some alternate method for our requirement. Thank you.

CC Dharmani said...

hi Chetan,
If you use internal Real Time Counter of ATmega128, the programming overhead increases as you have to write a code to keep counting the pulses, convert them into seconds, minutes, hours etc. Also, the program has to keep track of change of the day, month, 30 or 31 day month, leap year etc.
Apart from this, you have to keep the MCU always powered ON. If you provide battery backup, it'll consume more power than an external RTC.

If you use extrenal RTC like DS1307, all the calculation of day/date/month etc. are done inside. Whenevr you want to know the time, you've to just read the registers of the RTC and you'll get current time in hour/minute/sec with date/day and year.
Plus, even if the system is powered off, the RTC keeps running with external 3v lithium cell (which can last for years). So, next time when you power on the system, you'll get current time ready!

So, for your application, to have the real time-stamp on the data stored in memory, it would be much easier to use an ext. RTC. RTC chips are available cheap and they take only two pins of the microcontroller for communication.

Regards.

shahi said...

Hi Dharmani, this is Shiv .I want to try your project can you send me the files regarding this project. My ID is hurricane.shiv@gmail.com

Also help me with the programmer and the software needed for programming the IC and for establishing the connection between the PC n circuit.

Thank you

CEEJAY said...

Hi Dharmani, this is Chetan once again. I really appreciate your efforts to help me out. But, as you pointed out, let me tell you that my requrement is just for the time and not the day, month, etc. So, if the internal RTC can be easily programmed for the timing alone, then i may not have to switch to an external RTC.

Secondly, as you said that the RTC consumes a lot of power and need to be switched on all the time, my application actually needs the system to be turned on all the time. So, i guess, the power consumption may not be an issue for me, but if the programming part is somewhat easy, then i was thinking of doing it with the internal RTC. Otherwise, if you think the other way, please let me know, and also, if you could help me with the coding of the external RTC, if required.
Thanks once again.

chetan8.jain@gmail.com

CC Dharmani said...

To Shiv:

Hi, I've sent you the code by mail. check it out!

swati said...

Hi dhramani sir,

we r working with atmega 32. we r succefully initialise lcd. now we have confussion with adc.
we want the information about temp conversion program with LM35

CC Dharmani said...

Hi Chetan,

since you need only time and the system is powered on all the time, you can do it with the internal RTC also. You have to just take care of any power failure so that you don't loose the current time.

For using internal RTC you have to use Timer/Counter0 (refer to datasheet). Set AS0 bit in ASSR register, connect 32.768KHz crystal between pins TOSC1 & TOSC2. Set timer0 prescaler to 128. This will make timer0 overflow at every 1 sec interval. You can then put in the code to count the seconds and convert them into minutes/hours.

RTCs don't consume lot of power but they need constant power (regular supply or battery back-up) for maintaining time.

If you want to use external RTC, I've given in this post the 'Download Code' link where you can get the DS1307 & I2C libraries.

CC Dharmani said...

Hi Swati,

since LM35 gives voltage output (10mv/C), you can connect the output pin of LM35 with any ADC channel (if you are not using channel-0, then connect it to channel-0).

Refer to my post:
http://www.dharmanitech.com/2008/10/adc-project-with-atmega32.html

There I've given code and schematic on how to use mega32 ADC for measuring voltages. Once you know the voltage o/p from LM35, just to divide it with the sensitivity (10mV/C) to get the temperature in Centigrade.

shahi said...

Hi Dharmani, this is Shiv .Can you suggest me a text book for -Programming of ATMEGA128(AVR) in both C language and ASSEMBLY language..or in case u have any E-Book regarding the same can u mail it to me at hurricane.shiv@gmail.com . I have a month time so i wanted to have through knowledge of the AVR programming.

Thank you...!

CC Dharmani said...

Hi Shiv,
there are some books on AVr, you'll find them if you search on net. But I won't be able to suggest any as I've never gone thru any book on AVR.
I usually prefer to go thru the datasheet, download a compiler and go thru its example programs. Start with a simple port interfacing (like flashing an LED) and then keep learning other modules like UART, TWI, SPI by programming and referring to datasheet.
It won't take longer as there is lot of help available on net for AVRs. You'll get code examples for almost anything in AVR.

satpambobo said...

Dharmani at India, I have old IC paralel EEPROM 27256 from my VGAcard (VIDEO BIOS?) could u design for me the scheme how to display 8 bit data from that? thanks (i want make matrix LED e-toy)

CC Dharmani said...

Hi satpambobo,
27256 is an UV erasable EPROM. For reading from it you need a microcontroller.
I think you want the toy to display variable patterns. If it is so, you can rather use a microcontroller with inbuilt flash (like the AVRs), this will eliminate the need of the 27256 and also, you can erase/rewrite it whenever you want electrically (rather than searching for UV light source to erase 27256).

Regards.

satpambobo said...

thanks 4 u reply. but mine, doesn't have hole glass to erase with UVlight. i think it's Electronicaly EPROM. I found Alan Nishioka Page that use 4040 counter to play 27256.

shahi said...

hi Dharmani. if i wish to use 89c51 ..can u suggest what could be the possible changes in interfacing rtc n eprom u have used for atmega and also what would be the change in programs u have provided...!

CC Dharmani said...

To Shahi:
Hi shiv, left the thought of using avr? :)
Anyways, as 8951 doesn't have i2c in hardware, you'll have to create low level functions to handle i2c bus timings, using two i/o pins of 8951.
In the program which i've provided, you'll have to replace the i2c library with your new library of software i2c. remaining routines you can use without changes.
Search on the net, there are many examples on how to write software i2c routines.

amol said...

can i use same programme for atmega 16? I want to store values of temperature,pressure and level in eeprom and want to display the same value at any time with date and time
Name Amol Suryaji Chaudhari
ID coolchaudhariamol@gmail.com

CC Dharmani said...

Hi amol,
interfacing these RTC & EEPROM will need i2c bus, and since the atmega16 is having it, you can certainly use it.
You'll have to change the program little bit, mostly the header file, to use it with ATmega16.

kopkeporto said...

Hi Dharmani,
I Used your RTC and i2c libraries and I'm very happy with it. I added a function to set the sqw output, my avr is now using the ds1307 rtc and it run a state machine, clocked by the ds1307 sqw on the ext int0 (sec). Very nice!
Now I try to add functions to read and write to the ds1307 sram. For some reason, I do not get back what I write to it. Do have a sample for these functions lying around, or do have a hint why I don ot get the same value back that I wrote to a memory location?
In RTC_routines I added functions for read and write like this:
i2c_sendAddress(DS1307_W)
i2c_sendData(address);
i2c_sendData(IObyte);

Best regards, Kopke

kopkeporto said...

Sorry, made a type in my code, the return type was not good. All is working ok now! Thanks for the inspiration you brought me!

CC Dharmani said...

Glad to know you solved it soon!

Regards.

Anonymous said...

hi Dharmani,
I want complete my project monitoring humidity and temperature, result monitoring save on SD/MMC and display on LCD 20x2,,but i can't display date from ds1307 and valid data from SHT11,please give me complete code on c language i am use compiler codevision avr,,
i am connect
SHT11
pin DATA to ATMega8535 port D2
pin SCK to ATMega8535 port D3

LCD
pin LCD to ATMega8535 port C

SD/MMC 1Gb
ATMega8535 port B5(MOSI) to pin SDO SD/MMC
ATMega8535 port B6(MISO) to pin SDI SD/MMC
ATMega8535 port B7(SCK) to pin SCK SD/MMC
ATMega8535 port B1(T1) to pin CS SD/MMC

RTC DS1307
pin SDA to ATMega8535 port B1
pin SCL to ATMega8535 port B2

serial port (USART) ATMega8535 to PC
you can send code to my mail ardi_sandi302@yahoo.co.id

tanks your attention and solution

CC Dharmani said...

Hi,
nice project! I've sent you the source code files for my project given in here. The files are written in ImageCraft ICCAVR compiler. you can easily convert them into CodeVision by making a few changes.

Regards.

amol said...

sir I want the information regarding pressure sensor,
level sensor and rpm measurement.
give the sensor's names.

Anonymous said...

Hi....

Im trying to interface EEPROM with 8051 in C language. I have written a code also for it, but its not working. Can u send some code related to this on this mail id-
engg.embedded@gmail.com
Thanks in advance...

CC Dharmani said...

Hi,
I've sent you the EEPROM & ic libraries. But, since the AVR controllers are having inbuilt i2c(TWI) bus hardware, the AVR i2c library will not be of much use here. You have to replace it with the software i2c library written for 8051 controllers to use the EEPROM library functions I sent.

Rizki said...

Hi Dharmani,
Your Project is very good.I wanto try your project would you send me the complete files to xrizkix2000@yahoo.com
Thanks.

CC Dharmani said...

Thanks Rizki! I've sent you the files.

Anonymous said...

hi,

Your project is really good to learn from. Thank you!

Could you explain just a bit how the multiplexing of the I2C from the microcontroller to the RTC chip and the FRAM chip is done? It looks like that when you initiate I2C protocal to the FRAM chip, the RTC chip would be affected as well and vice versa. Thanks.

CC Dharmani said...

If you go thru the I2C bus details, you'll find that every device on the I2C bus has a unique address. The microcontroller sends the address on the bus before sending any data, so only the device whose address is matching will respond to the data. All other devices on the same bus would just ignore it.
This is the advantage of using I2C bus, with just two wires, you can connect multiple devices with different addresses. You do not need a separate 'chip select' signal for every device to enable or disable it.

amol said...

I am getting problem with serial communication i have used atmega16 8 Mhz crystal and boud rate 9600
hyper terminal shows only '@@@@@@'
plz solve it

dhinakaran said...

hi..
i'm trying to implement this project.kindly send me library functions you have used.. my id is dhnkrn@gmail.com
regards

imm said...

hi dharmani, i have digitalclock project.
use RTC ds1307 and AT89s51, display 7segment. i wnt to make 5 slave and send with serial communication use rs485. please help me.
thanks

Moses said...

Hi! Dharmani,
I found your site to be very useful. I've managed to interface DS1307 RTC with 89C51RD2 successfully and also able to read & write to the 56Byte RAM available. I want to write the date/ time stamp and temperature to AT24C512 Serial EEPROM. Some how I'm getting an Error. When I run my EEPROM routines It works fine, in combinatio with RTC it fails showing garbage values. Can you please help me with the EEPROM routines? I want to write in locations 0 to 30,000.

If you have any eeprom program please email me

Thanks in advance!

Moses said...

Hi! Dharmani,
I found your site to be very useful. I've managed to interface DS1307 RTC with 89C51RD2 successfully and also able to read & write to the 56Byte RAM available. I want to write the date/ time stamp and temperature to AT24C512 Serial EEPROM. Some how I'm getting an Error. When I run my EEPROM routines It works fine, in combinatio with RTC it fails showing garbage values. Can you please help me with the EEPROM routines? I want to write in locations 0 to 30,000.

If you have any eeprom program please email me at 17.moses@gmail.com

Thanks in advance!

Anonymous said...

hi dharmani, i have digitalclock project.
use RTC ds1307 and AT89s51, display 7segment. i wnt to make 5 slave and send with serial communication use rs485. please help me.
thanks
send me at: imron.polines@gmail.com

Anonymous said...

hi dharmani, i have digitalclock project.
use RTC ds1307 and AT89s51, display 7segment. i wnt to make 5 slave and send with serial communication use rs485. please help me.
thanks
imron.polines@gmail.com

immroon said...

hi dharmani, i have digitalclock project.
use RTC ds1307 and AT89s51, display 7segment. i wnt to make 5 slave and send with serial communication use rs485. please help me.
thanks
imron.polines@gmail.com

Luís said...

hi,

i need to try your porject, could you send me the files? my email is luix_mac@hotmail.com


thanks for your time
luis

Anonymous said...

Hi Dharmani, I'm interested in the DS307 library you mentioned.

Can you send me the files.
Thanks a lot!

Here is my email :

v2102ap@gmail.com

Anonymous said...

Also, if you don't mind, what is the program you used for drawing the schematics? Where can I download it?

Thanks again!

CC Dharmani said...

Hi, I've sent you the files.
I use EAGLE for drawing schematics, you can download it from this link:
http://www.cadsoft.de/download.htm

asif said...

hello

i am using your program and have worked on. But there is a problem how to write data in RAm of DS1307. when i write data in RAm it stops upgrading time. plz help me to solve this

asif said...

you can reply me on asif164@ohtmail.com

Althaf said...

I want to try to implement this RTC and serial EEPROM using I2C bus. Could you plaes send me the complete project files (schematics+sources+libs)
Regards,
Althaf
msheikalthaf@yahoo.com

Anonymous said...

would you send me the complete project file. i just want to learn your project, it seem very interesting.
Regards,
Iman
iman_parta_kusuma@yahoo.com

i will wait for your e-mail...thanks

sumeet singh said...

Great Article ! Can you please help me change the header files to use atmega32 instead of 1280 . i would be greatful if you can send me modified files to webrains@gmail.com

cheers
sumeet

rahul said...

please tell me how to interface i2c to atmega 8535 as i didn't find any sda and scl pin in it

rahul said...

how to interface i2c to atmega 8535

CC Dharmani said...

Hi Rahul,
Atmega8535 is having i2c bus (TWI) on-chip. Pin22 & 23 are SCL & SDA pins respectively. You can use i2c functions provided in this post.

suresh said...

Hi Dharmani sir,
I am from jodhpur presently student of MBM Engg college.
I used your rtc interfacing code for atmega8 and it really worked very
good. I am very thankful to you for this help. Sir, I want to share my
further problem regarding to my project please help me.

It uses timer1 in ctc mode at almost 500ms delay. Each time
it flips a volatile uint8_t TIMER_FLAG. An another code in main program
activates whenever TIMER_FLEG is not zero read rtc and display SS/MM/HH
to hyper terminal. This code also flip a LED each time also. It works quite
well.

Along with timer1 It also uses INT1 in falling edge trigger mode. INT1 ISR
disturbs the previous code and bring the compiler out of previous and send
another message to hyper terminal. It also works quite well.

Problem is that sometime (after few minutes or several minutes) all of
sudden LED stops flipping as uC were gone in sleep mode. As soon as INT1 is
applied LED again starts flipping. I have take a number of tests for debuging
but failed to find fault. microcontroller uses internal 8MHz oscillator.
INT1 is applied through a TSOP1738 (Vout of TSOP is connected at pin D3) and
a normal TV remote. It is not using any type of sleeping mode.

//////////////////////////////////////////////////////////
/* I used timer in no prescale mode for pssible removal of
problem so I used LED_cnt to increase delay*/
////////////////////////////////////////////////////
ISR(TIMER1_COMPA_vect)
{ if(LED_cnt>=50)
{
LED_cnt=0;
TIMER_FLAG=1;
}
else
LED_cnt++;
}
////////////////////////////////////////////////////////////
SIGNAL(SIG_INTERRUPT1)
/* signal handler for external interrupt int1 */
{
INT_flag=1;
}
////////////////////////////////////////////////////////////

//////// main program///////////////////////
void main():
{
while(1)
{
while(!INT_flag)
{
if(TIMER_FLAG)
{
TIMER_FLAG=0;
bit_flip(PORTD,1);
....... .
////////////code to send SS/MM/HH to hyper terminal////////////
........
.......
////////////////////////////////////////////////////////////
}
}
uartsendstring("interrupt called");
INT_flag=0;
}
}

Please suggest me some solution to remove this problem.

Poonam said...

hi, this is poonam .i ma working on same project.can you tell me that why eeprom is used with RTC
can you send me details on poonamkothawade@yahoo.co.in

pradeep said...

Hi i am working on with the rtc1307 with 8051. When i tried entering the time through serial com port through the pc the controller resets again.
I have taken the code from the 1307 datasheet. Plz help
dis is d link of the code

http://www.maxim-ic.com/appnotes.cfm/an_pk/95

and dis is my email:
plz reply

pradeep.mirchandani@gmail.com

Bravo13 said...

Hello! I send mail to author and repost my troubles here
I'm using ATMega16 and AT24C128 EEPROM. Also, I use this datasheet www.atmel.com/atmel/acrobat/doc0670.pdf
First of all I'd want to clarify erasing algorithm. As I see, you use "page write" algorithm to write 0xFF bytes to whole memory. But it's not writing to whole memory, it's write only first page. In datasheet on page 10 quote

If more than 64 data words are
transmitted to the EEPROM, the data word address will “roll over” and previous data will be
overwritten. The address “roll over” during write is from the last byte of the current page to the
first byte of the same page.

I'v write new erasinc procedure, that erasing by pages. If I'm not right - correct me.
Second moment - delay between stop and start conditions. If I try to write two bytes in sequence, MCU hangs up when waiting start condition for second write procedure. But if I make delay between two write procedures, everything is Ok. In datsheet somsing about ACKNOWLEDGE POLLING on page 10 but I don't know how to embed it in your code. But your routines help me great - thank you. Could you help me in my two troubles?