Even I have posted about βDS1307 + PIC16F877Aβ, I didnβt have chance to make a real prototype of the clock. I have done only on the simulation software.
Today, I have received a comment about that post. ah_bear followed my code and schematic on that post but the clock didnβt work. This is because the code on that post is for reading time from DS1307 so there must be some values in the DS1307 before you can read. The solution is simple. Just place setting time codes before reading codes.
This time, I have made a real prototype to confirm that itβs working. There is no setting buttons. If you want to make a real usable clock you have to implement the button interfaces (I may make one and post it here). The photo of my working prototype is featured below. Please check out my flikr at http://flickr.com/photos/punkky/ for more photos.
The schematic of the clock is very simple. Please note that the schematic does not show power supply to the PIC16F877A and the DS1307, you have to connect them by youself. If you are new to PIC/LCD interface please seeΒ MikroC βHello World!β LCD exampleΒ .
The source code:
//DS1307Β RTCΒ InterfacingΒ withΒ PIC16F877A
//CodedΒ byΒ [email protected]
//Compiler:Β mikroCΒ 8.0.0
//http://picnote.blogspot.com
//05/01/2009
//UseΒ withΒ yourΒ ownΒ riskunsignedΒ shortΒ read_ds1307(unsignedΒ shortΒ addressΒ );
voidΒ write_ds1307(unsignedΒ shortΒ address,unsignedΒ shortΒ w_data);
unsignedΒ shortΒ sec;
unsignedΒ shortΒ minute;
unsignedΒ shortΒ hour;
unsignedΒ shortΒ day;
unsignedΒ shortΒ date;
unsignedΒ shortΒ month;
unsignedΒ shortΒ year;
unsignedΒ shortΒ data;
charΒ time[9];
charΒ ddate[11];
unsignedΒ charΒ BCD2UpperCh(unsignedΒ charΒ bcd);
unsignedΒ charΒ BCD2LowerCh(unsignedΒ charΒ bcd);
voidΒ main(){
I2C_Init(100000);Β //DS1307Β I2CΒ isΒ runningΒ atΒ 100KHz
PORTBΒ =Β 0;
TRISBΒ =Β 0;Β //Β ConfigureΒ PORTBΒ asΒ output
TRISCΒ =Β 0xFF;
Lcd_Init(&PORTB);Β //Β InitializeΒ LCDΒ connectedΒ toΒ PORTB
Lcd_Cmd(Lcd_CLEAR);Β //Β ClearΒ display
Lcd_Cmd(Lcd_CURSOR_OFF);Β //Β TurnΒ cursorΒ off
Lcd_Out(1,Β 1,Β βTIME:β);
Lcd_Out(2,Β 1,Β βDATE:β);
//SetΒ Time
write_ds1307(0,0x80);Β //ResetΒ secondΒ toΒ 0Β sec.Β andΒ stopΒ Oscillator
write_ds1307(1,0x10);Β //writeΒ minΒ 27
write_ds1307(2,0x01);Β //writeΒ hourΒ 14
write_ds1307(3,0x02);Β //writeΒ dayΒ ofΒ weekΒ 2:Monday
write_ds1307(4,0x05);Β //Β writeΒ dateΒ 17
write_ds1307(5,0x01);Β //Β writeΒ monthΒ 6Β June
write_ds1307(6,0x09);Β //Β writeΒ yearΒ 8Β β>Β 2008
write_ds1307(7,0x10);Β //SQWEΒ outputΒ atΒ 1Β Hz
write_ds1307(0,0x00);Β //ResetΒ secondΒ toΒ 0Β sec.Β andΒ startΒ Oscillator
while(1)
{
sec=read_ds1307(0);Β //Β readΒ second
minute=read_ds1307(1);Β //Β readΒ minute
hour=read_ds1307(2);Β //Β readΒ hour
day=read_ds1307(3);Β //Β readΒ day
date=read_ds1307(4);Β //Β readΒ date
month=read_ds1307(5);Β //Β readΒ month
year=read_ds1307(6);Β //Β readΒ year
time[0]Β =Β BCD2UpperCh(hour);
time[1]Β =Β BCD2LowerCh(hour);
time[2]Β =Β β:β;
time[3]Β =Β BCD2UpperCh(minute);
time[4]Β =Β BCD2LowerCh(minute);
time[5]Β =Β β:β;
time[6]Β =Β BCD2UpperCh(sec);
time[7]Β =Β BCD2LowerCh(sec);
time[8]Β =Β β\0β;
ddate[0]Β =Β BCD2UpperCh(date);
ddate[1]Β =Β BCD2LowerCh(date);
ddate[2]Β =β/β;
ddate[3]Β =Β BCD2UpperCh(month);
ddate[4]Β =Β BCD2LowerCh(month);
ddate[5]Β =β/β;
ddate[6]Β =Β β2β;
ddate[7]Β =Β β0β;
ddate[8]Β =Β BCD2UpperCh(year);
ddate[9]Β =Β BCD2LowerCh(year);
ddate[10]Β =Β β\0β;
Lcd_Out(1,6,time);
Lcd_Out(2,6,ddate);
Delay_ms(50);
}
}
unsignedΒ shortΒ read_ds1307(unsignedΒ shortΒ address)
{
I2C_Start();
I2C_Wr(0xd0);Β //addressΒ 0x68Β followedΒ byΒ directionΒ bitΒ (0Β forΒ write,Β 1Β forΒ read)Β 0x68Β followedΒ byΒ 0Β β>Β 0xD0
I2C_Wr(address);
I2C_Repeated_Start();
I2C_Wr(0xd1);Β //0x68Β followedΒ byΒ 1Β β>Β 0xD1
data=I2C_Rd(0);
I2C_Stop();
return(data);
}
unsignedΒ charΒ BCD2UpperCh(unsignedΒ charΒ bcd)
{
returnΒ ((bcdΒ >>Β 4)Β +Β β0β);
}
unsignedΒ charΒ BCD2LowerCh(unsignedΒ charΒ bcd)
{
returnΒ ((bcdΒ &Β 0x0F)Β +Β β0β);
}
voidΒ write_ds1307(unsignedΒ shortΒ address,unsignedΒ shortΒ w_data)
{
I2C_Start();Β //Β issueΒ I2CΒ startΒ signal
//addressΒ 0x68Β followedΒ byΒ directionΒ bitΒ (0Β forΒ write,Β 1Β forΒ read)Β 0x68Β followedΒ byΒ 0Β β>Β 0xD0
I2C_Wr(0xD0);Β //Β sendΒ byteΒ viaΒ I2CΒ (deviceΒ addressΒ +Β W)
I2C_Wr(address);Β //Β sendΒ byteΒ (addressΒ ofΒ DS1307Β location)
I2C_Wr(w_data);Β //Β sendΒ dataΒ (dataΒ toΒ beΒ written)
I2C_Stop();Β //Β issueΒ I2CΒ stopΒ signal
}