DS1307 Based Hand Clock with seven segment display using PIC16F877A (Code)
//------Project by { ZAKI }--"facebook.com / Zaki Semel"----------//
//------Project { Clock Hand }---For Pic16f877a & 7 Segment 4, Anode-------//
//*****************************************************************************//
char second, minute, hour, day, date, month, year;
char second_d1, second_d2, minute_d1, minute_d2, hour_d1, hour_d2;
char date_d1, date_d2, month_d1, month_d2, year_d1, year_d2, year_d3, year_d4;
char convert, hold;
char seg[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //Segment 0-9
//----Buttons-----------------------------//
#define Button1 PORTC.f0 //Show Date & Second, Date & Second ++
#define Button2 PORTC.f1 //Change Time & Date
#define Button3 PORTC.f2 //Show Time & No Save Time & Date
#define Button4 PORTC.f5 //Show Year
//----In Interrupt-----------------------------------//
#define GotoTime 0
#define GotoSecond 1
#define GotoDate 2
#define GotoYear 3
#define GotoClear 4
//----Hour 12 (AM-PM)---------------------//
#define AM PORTE.f0 //Hour12(AM)
#define PM PORTE.f1 //Hour12(PM)
//-----Display Time------------------//
void DisplayTime()
{
char x;
second_d1 = seg[second /10];
second_d2 = seg[second %10];
minute_d1 = seg[minute /10];
minute_d2 = seg[minute %10];
hour_d1 = seg[hour /10];
hour_d2 = seg[hour %10];
date_d1 = seg[date /10];
date_d2 = seg[date %10];
month_d1 = seg[month /10];
month_d2 = seg[month %10];
year_d1 = seg[year /10];
year_d2 = seg[year %10];
year_d3 = seg[year /10];
year_d4 = seg[year %10];
}
//----I2C Read for IC DS1307----------------//
void ReadI2C()
{
i2c1_start();
i2c1_wr(0xd0);
i2c1_wr(0);
i2c1_repeated_start();
i2c1_wr(0xd1);
second = i2c1_rd(1);
minute = i2c1_rd(1);
hour = i2c1_rd(1);
day = i2c1_rd(1);
date = i2c1_rd(1);
month = i2c1_rd(1);
year = i2c1_rd(0);
i2c1_stop();
}
//----Transform Time for IC DS1307------------------//
void TransformTime()
{
second =((second & 0xf0)>>4)* 10 +(second & 0x0f);
minute =((minute & 0xf0)>>4)* 10 +(minute & 0x0f);
hour =((hour & 0xf0)>>4)* 10 +(hour & 0x0f);
day =((day & 0xf0)>>4)* 10 +(day & 0x0f);
date =((date & 0xf0)>>4)* 10 +(date & 0x0f);
month =((month & 0xf0)>>4)* 10 +(month & 0x0f);
year =((year & 0xf0)>>4)* 10 +(year & 0x0f);
}
//----Start Time for IC DS1307------------------------------//
void StartTime(char second, char minute, char hour, char day, char date, char month, char year)
{
i2c1_start();
i2c1_wr(0xd0);
i2c1_wr(0);
i2c1_wr(second);
i2c1_wr(minute);
i2c1_wr(hour);
i2c1_wr(day);
i2c1_wr(date);
i2c1_wr(month);
i2c1_wr(year);
i2c1_wr(0x10); // 1Hz
i2c1_stop();
}
//----Save Time & Date for Change------------------//
void SaveTime()
{
i2c1_start();
i2c1_wr(0xd0);
i2c1_wr(0);
i2c1_wr(dec2bcd(second));
i2c1_wr(dec2bcd(minute));
i2c1_wr(dec2bcd(hour));
i2c1_wr(dec2bcd(day));
i2c1_wr(dec2bcd(date));
i2c1_wr(dec2bcd(month));
i2c1_wr(dec2bcd(year));
i2c1_stop();
}
//----Hour 12 (AM-PM)----------------------//
void Hour12_AM_PM()
{
if (hour < 0x12)
{
if (hour == 0)
{
hour = 0x12;
AM = 1;
}
else AM = 1;
}
else if (hour == 0x12)
{
PM = 1;
}
else if (hour > 0x12 && hour < 0x20)
{
hour = hour - 0x12;
PM = 1;
}
else if (hour == 0x20)
{
hour = 0x08;
PM = 1;
}
else if (hour == 0x21)
{
hour = 0x09;
PM = 1;
}
else if (hour == 0x22)
{
hour = 0x10;
PM = 1;
}
else if (hour == 0x23)
{
hour = 0x11;
PM = 1;
}
}
//----Show Date & Second for Button1-------------------//
void DateSecond(char set)
{
switch(set)
{
case 0: convert = GotoDate; break; //Goto Date in Interrupt
case 1: convert = GotoSecond; break; //Goto Second in Interrupt
}
}
//----Show Date & Second for Button1-------------------//
void MenuDateSecond()
{
char set;
set = 0;
while(1)
{
ReadI2C();
Hour12_AM_PM();
TransformTime();
DisplayTime();
DateSecond(set);
if (Button1 == 0){hold = 1;}
if (Button1 == 1 && hold == 1)
{
hold = 0;
set++;
if (set > 1)
{
delay_ms(2);
convert = GotoTime; //Goto Time in Interrupt
break;
}
}
//-----------------------------//
if (set >= 1)
{
if (Button2 == 1) //---Second = 0
{
second = 0;
SaveTime(); //---Save Time
}
}
}
}
//*****************************************//
//----Change Time & Date for Button2----------------------//
void SetChangeTime(char set)
{
switch(set)
{
case 0:
hour_d1 = hour_d2 = 0xff; delay_us(500);
break;
case 1:
minute_d1 = minute_d2 = 0xff; delay_us(500);
break;
case 2:
date_d1 = date_d2 = 0xff; delay_us(500);
break;
case 3:
month_d1 = month_d2 = 0xff; delay_us(500);
break;
case 4:
year_d3 = year_d4 = 0xff; delay_us(500);
break;
}
}
//----Change Time & Date for Button2----------------------//
void ChangeTime(char set, char change)
{
switch(set)
{
case 0:
if (change == 0)
{
hour ++;
if (hour > 23) hour = 0;
}
break;
case 1:
if (change == 0)
{
minute ++;
if (minute > 59) minute = 0;
}
break;
case 2:
if (change == 0)
{
date ++;
if (date > 31) date = 1;
}
break;
case 3:
if (change == 0)
{
month ++;
if (month > 12) month = 1;
}
break;
case 4:
if (change == 0)
{
year ++;
if (year > 99) year = 0;
}
break;
}
}
//----Change Time & Date for Button2----------------------//
void MenuChangeTime()
{
char set;
set = 0;
while(1)
{
DisplayTime();
SetChangeTime(set);
if (Button2 == 0){hold = 1;}
if (Button2 == 1 && hold == 1)
{
hold = 0;
set ++;
if (set > 4) //Save Time
{
convert = GotoTime; //Goto Time in Interrupt
second = 0;
SaveTime();
break;
}
if (set > 1) convert = GotoDate; //Goto Interrupt
if (set > 3) convert = GotoYear; //Goto Interrupt
}
if (Button1 == 1) //Time & Date ++
{
SetChangeTime(set);
ChangeTime(set, 0); //Time & Date ++
}
if (Button3 == 1) //No Save, Goto Normal Time
{
convert = GotoTime; //Goto Time in Interrupt
break;
}
}
}
//----Clear Display-------------------------//
void ClearDisplay()
{
while(1)
{
convert = GotoClear; //Goto Clear in Interrupt
ReadI2C();
TransformTime();
portE = 0;
if (Button1 == 0 && Button2 == 0){hold = 1;}
if (Button1 == 1 && hold == 1) //Show Date & Second
{
hold = 0;
convert = GotoDate; //Goto Interrupt
MenuDateSecond(); //Goto MenuDateSecond();
break;
}
if (Button2 == 1 && hold == 1)
{
hold = 0;
convert = GotoTime; //Goto Time in Interrupt
MenuChangeTime();
break;
}
if (Button3 == 1)
{
convert = GotoTime; //Goto Time in Interrupt
break;
}
if (Button4 == 1)
{
convert = GotoYear; //Goto Year in Interrupt
break;
}
}
}
//----Interrupt-------------------------------//
void Interrupt()
{
if (convert == GotoSecond) //Show Second
{
portd = 1; portb = 0xff; delay_ms(1);
portd = 2; portb = 0xff; delay_ms(1);
portd = 4; portb = second_d1; delay_ms(1);
portd = 8; portb = second_d2; delay_ms(1);
}
if (convert == GotoTime) //Show Time(Hour & Minute)
{
portd = 1; portb = hour_d1; delay_ms(1);
portd = 2; portb = hour_d2 + 128; delay_ms(1);
portd = 4; portb = minute_d1; delay_ms(1);
portd = 8; portb = minute_d2; delay_ms(1);
}
if (convert == GotoDate) //Show Date(Date & Month)
{
portd = 1; portb = date_d1; delay_ms(1);
portd = 2; portb = date_d2 + 128; delay_ms(1);
portd = 4; portb = month_d1; delay_ms(1);
portd = 8; portb = month_d2; delay_ms(1);
}
if (convert == GotoYear) //Show Year
{
portd = 1; portb = 0xa4; delay_ms(1);
portd = 2; portb = 0xc0; delay_ms(1);
portd = 4; portb = year_d3; delay_ms(1);
portd = 8; portb = year_d4; delay_ms(1);
}
if (convert == GotoClear) //Clear Display
{
portd = 1; portb = 0xff; delay_ms(1);
portd = 2; portb = 0xff; delay_ms(1);
portd = 4; portb = 0xff; delay_ms(1);
portd = 8; portb = 0xff; delay_ms(1);
}
intcon = 0b10100000;
}
//*********** Main *******************************************//
void main()
{
trisB = 0; trisC = 0xff; trisD = 0; trisE = 0;
option_reg = 0b10000000; intcon = 0b10100000; //Registers
i2c1_init(100000); //Init I2C(IC DS1307)
StartTime(0x00, 0x00, 0x00, 0, 0x21, 0x03, 0x17); //Start Time
while(1)
{
ReadI2C();
Hour12_AM_PM();
TransformTime();
DisplayTime();
delay_ms(10);
ClearDisplay(); //Goto ClearDisplay()
}
}
DS1307 Based Hand Clock with seven segment display using PIC16F877A (Schematic Diagram)
The post DS1307 Based Hand Clock with seven segment display using PIC16F877A appeared first on PIC Microcontroller.