Project1 1
Project1 1
DS12C887
In this project, I will show you how to design a simple Digital Clock Circuit
using 8051 and DS12C887 as well as DS1307 RTC Modules.
Introduction
A digital clock displays the time using numbers and it has many
applications like cars, railway stations, houses, offices, etc. in order to
provide accurate time and date. In this type of applications, normally we
use RTC (Real Time Clock) ICs to display the time and date accurately.
The circuit displays the time on LCD. For this clock, we can set the time at
any instant. Here, the clock can work in either 24 hour mode or 12 hour
mode and the RTC chip is configured by programming 8051 controller.
Circuit Principle
Circuit Components
8051 microcontroller
Project PCB
Programming cable
DC Battery or 12V, 1A adaptor
DS12C887 RTC IC
16*2 alphanumeric LCD
Push buttons – 4
Slide switches – 3
2 ceramic capacitors – 33pF
12 MHz crystal
Electrolytic capacitor – 10uF, 16V
Resistor (1/4 watt) – 10k
Pot – 10k
5V DC power supply circuit
Single pin connecting wires
[adsense2]
Circuit Design
The circuit shows you how interface RTC IC to the 8051 controller. Port P0
is used as a data port of Real time clock. Port P2 of controller is connected
to the data pins of LCD. Pins P1.1, P1.2 and P1.3 of controller are
connected to the RS, RW, EN pins respectively. P1.0 is connected to the
RESET of RTC. Push buttons are connected to the P1.4 and P1.5. These are
used set the time. P1.6 is configured as START pin used to run the clock
with time set by the user. P3.3 is connected to the push button used to call
the set_time function.
This IC is used most of the applications to provide accurate time and date.
This IC provides the time in both 12 hour mode and 24 hour mode. This IC
also provides calendar components day, month and year. This RTC uses
internal lithium battery to keep the time and date updated when power is
failed. This IC has 128 bytes of RAM memory. In these 128 bytes of RAM 14
bytes are used for time, date and registers. Remaining 114 bytes are used
to store general purpose data.
The control registers of RTC are accessible only when the power is applied
from external source. This IC requires more than 4.25V power supply and
the control registers are accessible after 200ms when external power is
supplied.
DS12C887 IC
Pin Description
This RTC has 128 bytes of RAM with addresses 00H – 07H. The first ten
locations (00 – 09) are used for clock, calendar and alarm data. 0A – 0D
address locations are used for status and control registers. Remaining
address locations are used to for general data. The following table shows
the address locations for clock, calendar and alarm.
Address Locations for Time, Date and Alarm
This IC has 4 control and status registers namely register A, register B,
Register C, register D. We need to configure all these registers to get the
accurate time and date. In order to configure these registers go through
the DS12C887 Datasheet
Code
#include<reg51.h>
#include<absacc.h>
#define dataport P2
#define port P1
#define lcdport P3
sbit reset = port^0;
sbit rs =port^1;
sbit rw =port^2;
sbit e = port^3;
sbit dig_hr1=port^4;
sbit dig_min1=port^5;
sbit start=port^6;
int min1=0,hr1=0;
int min0=60,hr0=25;
unsigned char temp=60,hr,min,sec,num[60]={0x00,0x01,0x02,
0x03,0x04,0x05,0x06,0x07,0x08,0X09,0X10,0X11,0X12,0X13,
0X14,0X15,0X16,0X17,0X18,0X19,0X20,0X21,0X22,0X23,0X24,
0X25,0X26,0X27,0X28,0X29,0X30,0X31,0X32,0X33,0X34,0X35,
0X36,0X37,0X38,0X39,0X40,0X41,0X42,0X43,0X44,0X45,0X46,
0X47,0X48,0X49,0X50,0X51,0X52,0X53,0X54,0X55,0X56,0X57,
0X58,0X59};
void delay(unsigned int msec )
{
int i ,j ;
for(i=0;i<msec;i++)
for(j=0; j<1275; j++);
}
void lcd_cmd(unsigned char item)
{
dataport = item;
rs= 0;
rw=0;
e=1;
delay(1);
e=0;
return;
}
// function to send data
void lcd_data(unsigned char item)
{
dataport = item;
rs= 1;
rw=0;
e=1;
delay(1);
e=0;
return;
}
void lcd_string(unsigned char *str)
{
int i=0;
while(str[i]!='\0')
{
lcd_data(str[i]);
i++;
delay(1);
}
return;
}
lcd_int(int time_val)
{
int int_amt;
int_amt=time_val/10;
lcd_data(int_amt+48);
int_amt=time_val%10;
lcd_data(int_amt+48);
}
void lcd()
{
lcd_cmd(0x38);
delay(5);
lcd_cmd(0x0C);
delay(5);
lcd_cmd(0x80)
;
delay(5);
}
void set_rtc_time()
{
XBYTE[10]=0x20;
XBYTE[11]=0x82;
XBYTE[0]=0x00;
XBYTE[2]=min;
XBYTE[4]=hr;
XBYTE[7]=0x01;
XBYTE[8]=0x01;
XBYTE[9]=0x10;
XBYTE[1]=0xFF;
XBYTE[3]=0xFF;
XBYTE[5]=0xFF;
XBYTE[11]=0x22;
}
void set_hr1()
{
hr1++;
if(hr1>23)
hr1=0;
lcd_cmd(0xc3);
lcd_int(hr1);
lcd_data(':');
hr0=hr1;
}
void set_min1()
{
min1++;
if(min1>59)
min1=0;
lcd_cmd(0xc6);
lcd_int(min1);
min0=min1;
}
void set_time() interrupt 2
{
lcd_cmd(0x01);
if(start==0)
{
lcd_string("SET TIMING");
lcd_cmd(0xc3);
lcd_int(hr1);
lcd_data(':');
lcd_int(min1);
while(start==0)
{
delay(10);
if(dig_hr1==0)
set_hr1();
if(dig_min1==0)
set_min1();
}
}
lcd_cmd(0x01);
hr=num[hr1];
min=num[min1];
set_rtc_time();
lcd_cmd(0x80);
lcd_string("TIME:");
hr0=25;
min0=60;
}
bcdconv(unsigned char mybyte)
{
unsigned char x,y;
x= mybyte & 0x0F;
x=x | 0x30;
y= mybyte & 0xF0;
y=y>>4;
y=y | 0x30;
lcd_data(y);
lcd_data(x);
}
void read_rtc_display()
{
XBYTE[11]=0x02;
hr=XBYTE[4];
lcd_cmd(0x85);
//if(hr!=hr0)
{
bcdconv(hr);
lcd_data(':')
;
hr0=hr;
}
min=XBYTE[2];
//if(min!=min0)
{
bcdconv(min);
lcd_data(':');
//min0=min;
}
sec=XBYTE[0];
//if(sec!=temp)
{
bcdconv(sec);
//temp=sec;
}
}
void main()
{
reset=1;
lcd();
XBYTE[10]=0x20;
XBYTE[1]=0xFF;
XBYTE[3]=0xFF;
XBYTE[5]=0xFF;
XBYTE[11]=0x02;
lcd_cmd(0x01);
IE=0x84;
lcd_cmd(0x80);
lcd_string("TIME:");
while(1)
{
read_rtc_display();
}
}
Components Required
8051 Microcontroller
8051 Development Board (Optional)
8051 Programmer
DS1307 RTC Module
11.0592MHz Crystal (for 8051)
32.768 KHz Crystal (for DS1307 RTC)
Capacitors – 33pF x 2, 10µF
Resistors – 1KΩ x 2, 10KΩ x 2, 8 x 1KΩ Pull-up, 10KΩ POT
3V Lithium Battery
Push Button
16×2 LCD Display
Code
#include<reg51.h>
#include<string.h>
#define lcd P3
sbit rs=P2^0;
sbit e=P2^1;
sbit c=P0^0;
sbit d=P0^1;
void delay (int);
void cmd (unsigned char);
void display (unsigned char);
void string (char *);
void init (void);
void i2c_start (void);
void i2c_stop (void);
void i2c_write (unsigned char);
unsigned char i2c_read (void);
void i2c_ack (void);
void i2c_noack (void);
void write (unsigned char, unsigned char, unsigned char);
unsigned char read (unsigned char, unsigned char);
void set_time (unsigned char, unsigned char, unsigned char);
int no[10]={48,49,50,51,52,53,54,55,56,57};
unsigned int temp1[3]=0;
void delay (int d)
{
unsigned char i=0;
for(;d>0;d--)
{
for(i=250;i>0;i--);
for(i=248;i>0;i--);
}
}
void cmd (unsigned char c)
{
lcd=c;
rs=0;
e=1;
delay(5);
e=0;
}
void display (unsigned char c)
{
lcd=c;
rs=1;
e=1;
delay(5);
e=0;
}
void string (char *p)
{
while(*p)
{
display(*p++);
}
}
void init (void)
{
cmd(0x38);
cmd(0x0c);
cmd(0x01);
cmd(0x80);
}
void i2c_start (void)
{
c=1;
d=1;
delay(1);
d=0;
delay(1);
}
void i2c_stop (void)
{
c=0;
delay(1);
d=0;
delay(1);
c=1;
delay(1);
d=1;
delay(1);
}
void i2c_write (unsigned char a)
{
char j;
for(j=0;j<8;j++)
{
c=0;
d=(a&0x80>>j)?1:0;
c=1;
}
}
unsigned char i2c_read (void)
{
char j;
unsigned char temp=0;
for(j=0;j<8;j++)
{
c=0;
if(d)
temp=temp|(0x80>>j);
c=1;
}
return temp;
}
void i2c_ack (void)
{
c=0;
delay(1);
d=1;
delay(1);
c=1;
delay(1);
while(d==1);
c=0;
delay(1);
}
void i2c_noack (void)
{
c=0;
delay(1);
d=1;
delay(1);
c=1;
delay(1);
}
void write (unsigned char sa, unsigned char w_addr, unsigned char dat)
{
i2c_start();
i2c_write(sa);
i2c_ack();
i2c_write(w_addr);
i2c_ack();
i2c_write(dat);
i2c_ack();
i2c_stop();
delay(10);
}
unsigned char read (unsigned char sa, unsigned char w_addr)
{
unsigned char buf=0;
i2c_start();
i2c_write(sa);
i2c_ack();
i2c_write(w_addr);
i2c_ack();
i2c_start();
i2c_write(sa|0x01);
i2c_ack();
buf=i2c_read();
i2c_noack();
i2c_stop();
return buf;
}
void set_time (unsigned char hour, unsigned char min, unsigned char sec)
{
unsigned int temp[3];
temp[0]=(((unsigned char)(sec/10))<<4)|((unsigned char)(sec%10));
temp[1]=(((unsigned char)(min/10))<<4)|((unsigned char)(min%10));
temp[2]=(((unsigned char)(hour/10))<<4)|((unsigned char)(hour%10));
write(0xd0,0x00,temp[0]);
write(0xd0,0x01,temp[1]);
write(0xd0,0x02,temp[2]);
}
void main()
{
unsigned char temp=0;
init();
string(" Digital Clock ");
cmd(0xc0);
string(" using 8051 ");
delay(3000);
cmd(0x01);
set_time(12,59,51);
delay(500);
while(1)
{
cmd(0x80);
temp=read(0xd0,0x00);
temp1[0]=((temp&0x7F)>>4)*10 + (temp&0x0F);
temp=read(0xd0,0x01);
temp1[1]=(temp>>4)*10 + (temp&0x0F);
temp=read(0xd0,0x02);
temp1[2]=(temp>>4)*10 + (temp&0x0F);
display(no[(temp1[2]/10)%10]);
display(no[temp1[2]%10]);
display(':');
display(no[(temp1[1]/10)%10]);
display(no[temp1[1]%10]);
display(':');
display(no[(temp1[0]/10)%10]);
display(no[temp1[0]%10]);
}
while(1);
}
Circuit Applications
This project is used in offices, houses, hotels and auto mobiles to
display the time and date.
We can also set the alarm in this project with a little modification.