Digital Clock
// REAL TIME CLOCK USING DS1307
//Description: using PIC 16F887 and LED7SEGMENT GEM5461BF
//RA0-3 control LED
//RD0-7 control segment
//RB0-2 Extra Interrupt, setting time
// PIN_B0: key down
// PIN_B1: key up
// PIN_B2: select set time (hour, minute or nothing)
//Perfomed by TRAN TUAN ANH, itc hcm
//Coding for CCS PIC C Compiler
//Last update: 30/10/2013
///////////////////////////////////////////////////////////////////////
#include <16F887.h>
#include <def_877A.h>
#device *=16 ADC=10
#include <ds1307.c>
#include <bcd.c>
#FUSES HS //Use high frenquency
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
//#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
#use fast_io(b)
//matrix for led7segment common anode
byte const LED[10]={0xC0,0xF9,0xA4, 0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 };
#define PIN_DATA PIN_C7 //data for 595
#define PIN_CLOCK PIN_C6 //clock for 595
#define PIN_LED_AM PIN_C5 //display led signal AM-PM
#bit KEY_VOL_UP =0x06.6 //RB6
#bit KEY_VOL_DOWN =0x06.5 //RB5
#bit KEY_ALARM =0x06.4 //RB4
#bit KEY_AM =0x06.3 //RB3
#bit KEY_SET =0x06.2 //RB2
#bit KEY_UP =0x06.1 //RB1
#bit KEY_DOWN =0x06.0 //RB0
#define PIN_LED1 40 //A0
#define PIN_LED2 41 //A1
#define PIN_LED3 42 //A2
#define PIN_LED4 43 //A3
int hour, min, sec, hour_h, hour_l, min_h,min_l, sec_h, sec_l;
int16 blink=0, set_t=0, volume=12;
int al_hour=6, al_min=0, AM=0, ALARM=0,SET_ALARM=0, DISPLAY_MODE=0;
void LedOn(int i);
void Display(int flag, int hour,int min,int sec);
void GetTime();
void Put_Volume_Data(int volume);
void Play_Sound();
//////////////////////////////////////////////////
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
//setup_psp(PSP_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// TODO: USER CODE!!
enable_interrupts(global);
enable_interrupts(int_RB);
ext_int_edge(H_to_L);
TRISD=0x00;
init_DS1307();
GetTime();
if(sec>59) //wrong time value
write_DS1307(0,0);
while(true)
{
if(++blink==2000) blink=0;//reset couter for get the time
if(blink==100) GetTime();
Display(DISPLAY_MODE,hour,min,sec);
if(hour==al_hour && min==al_min)
Play_Sound();
}
}
//////////////////////////////////////////////////
void Play_Sound()
{
//viet code vo day
}
//////////////////////////////////////////////////
void LedOn(int i)
{
output_a(0b11111111);// turn off all
switch (i)
{
case 1:
output_low(PIN_LED1);
break;
case 2:
output_low(PIN_LED2);
break;
case 3:
output_low(PIN_LED3);
break;
case 4:
output_low(PIN_LED4);
}
}
//////////////////////////////////////////////////
void Display(int flag, int hour, int min, int sec)
{
//display for led 7 segment GEM5461BF
int delaytime=200;
if(AM)
{
hour_h = hour%12 /10;
hour_l = hour%12 % 10;
}
else
{
hour_h = hour /10;
hour_l = hour % 10;
}
min_h = min /10;
min_l = min % 10;
sec_h = sec /10;
sec_l = sec %10;
if (flag==0)
{
if(hour_h!=0)
{
LedOn(1);
output_d(LED[hour_h]);
delay_us(delaytime);
}
LedOn(2);
output_d(LED[hour_l]);
if((blink/1000)%2==0) //
output_low(pin_d7); // Compliant Part blinking
delay_us(delaytime);
LedOn(3);
output_d(LED[min_h]);
delay_us(delaytime);
LedOn(4);
output_d(LED[min_l]);
delay_us(delaytime);
}
if (flag==1)
{
LedOn(1);
output_d(LED[hour_h]);
delay_us(delaytime);
LedOn(2);
output_d(LED[hour_l]);
delay_us(delaytime);
output_low(pin_d7); //alway display Compliant Part
}
if (flag==2)
{
LedOn(3);
output_d(LED[min_h]);
delay_us(delaytime);
LedOn(4);
output_d(LED[min_l]);
delay_us(delaytime);
output_low(pin_d7); //alway display Compliant Part
}
if(flag==3)
{
LedOn(3);
output_d(LED[volume/10]);
delay_us(200);
LedOn(4);
output_d(LED[volume%10]);
delay_us(200);
}
}
//////////////////////////////////////////////////
void GetTime()
{
sec = BCDtoDECIMAL(read_DS1307(0));
min = BCDtoDECIMAL(read_DS1307(1));
hour = BCDtoDECIMAL(read_DS1307(2));
}
/////////////////////interupt RB///////////////
#int_RB
void RB_isr()
{
int h,m,s;
h=hour;
m=min;
s=sec;
// dd=date;
// mm=month;
// yy=year;
// dw=day;
/*
if(KEY_VOL_UP==0)
{
delay_us(50);
if(volume<15) volume++;
DISPLAY_MODE=3;
}
if(KEY_VOL_DOWN==0)
{
delay_us(50);
if(volume>0) volume--;
DISPLAY_MODE=3;
}
*/
if (KEY_ALARM==0)
ALARM=!ALARM;
if (KEY_AM==0)
AM=!AM;
if(KEY_SET==0)
{
delay_us(50);
if(KEY_ALARM==!0)
//select for set the time
{
if(set_t<2)
set_t++;
else
set_t=0;
DISPLAY_MODE=set_t;
}
else
//select for set the alarm, hold down "Alarm" key and press "Set" key,
{
if(set_alarm<2)
set_alarm++;
else
set_alarm=0;
DISPLAY_MODE=set_alarm;
}
}
if(KEY_UP==0)
{ //up key pressed
delay_us(50);
switch(set_alarm)
{
case 1:
if(al_hour<23)
al_hour++;
else
al_hour=0;
break;
case 2:
if(al_min<59)
al_min++;
else
al_min=0;
}
switch(set_t){
case 1:
//set hour
if(h<23) h++;
else h=0;
hour=DECIMALtoBCD(h);
write_DS1307(2,hour);
break;
case 2:
//set minute
if(m<58) m++;
else m=0;
min=DECIMALtoBCD(m);
write_DS1307(1,min);
break;
/* case 3:
//set second
if(s<59)s++;
else s=0;
sec=DECIMALtoBCD(s);
write_DS1307(0,sec);
break;
*/
}
}
if(KEY_DOWN==0)
{ //down key pressed
delay_us(20);
switch (set_alarm)
{
case 1:
if(al_hour>0)
al_hour--;
else
al_hour=23;
break;
case 2:
if(al_min>0)
al_min--;
else
al_min=59;
}
switch(set_t){
case 1:
//set hour
if(h>0)
h--;
else
h=23;
hour=DECIMALtoBCD(h);
write_DS1307(2,hour);
break;
case 2:
//set minute
if(m>0) m--;
else m=59;
min=DECIMALtoBCD(m);
write_DS1307(1,min);
break;
/* case 3:
//set second
if(s>0)s--;
else s=59;
sec=DECIMALtoBCD(s);
write_DS1307(0,sec);
break;
*/
}
}
GetTime(); // Very important, reading and displayed immediately.
RBIF=0;
}