void display_segment(short int b);
void display (unsigned short a, unsigned short p);
void init_ds3231(void);
void write_ds3231(unsigned short address, unsigned short data1);
void select_digit(unsigned short mn, unsigned short hr);
void Buzzer(void);
unsigned short read_ds3231(unsigned short address);
unsigned short read_button(void);
unsigned int ADCRead(unsigned char channel);
unsigned int read_display_temp(void);
void main(){
unsigned short a, hr, mn, a100, a10, a1, i, key, sec;
unsigned int tmp_C, Val1;
TRISA = 0x01;
TRISB = 0x01; //INT input at RB0
TRISC = 0X00; //SCL-RC3, SDA-RC4
PORTB = 0xff;
CMCON = 0x07; //disable comperators
ADCON1 = 0b11001110;
I2C1_Init(100000);
init_ds3231();
for(;;){ sec = 0x00;
if((read_ds3231(0x0F) & 0x01)==0b1) {
mn = (0x7F & read_ds3231(0x01));
hr = (0x1F & read_ds3231(0x02));
//if((read_ds3231(0x0E) & 0b00100000)==0b00100000){
tmp_C = read_display_temp();
a100 = tmp_C/100;
a10 = (tmp_C/10)%10;
a1 = tmp_C%10; //}
write_ds3231(0x0F, (read_ds3231(0x0F) & 0b11111110));} //clear flag 0x0F.F0
do
{
display(hr, 1);
display(mn, 3);
PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
PORTA.F4 = 0; PORTA.F5 = 1; PORTC.F2 = 1;
display_segment(a100); //T100(1st digit of TT.T)
delay_ms(5);
PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
PORTA.F4 = 1; PORTA.F5 = 0; PORTC.F2 = 1;
display_segment(a10); //T10 (2nd digit of TT.T)
delay_ms(5);
PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 0;
display_segment(a1); //Tf (Fraction digit of TT.T)
delay_ms(5);
if(abs((read_ds3231(0x00))-sec)>0) PORTC.F6=~PORTC.F6; //blinking LED every second
sec=read_ds3231(0x00);
if(read_button()==1)select_digit(mn, hr);
if (mn == 0x00) Buzzer();
if((read_ds3231(0x0F) & 0b00000001)==0x01) break;
} while((read_ds3231(0x0F) & 0b00000001)==0x00);}
}
void display (unsigned short a, unsigned short p){
switch(p){
case 1 :{
PORTC.F0 = 0; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
display_segment(a>>4); //Hr10
delay_ms(5);
PORTC.F0 = 1; PORTA.F1 = 0; PORTA.F2 = 1; PORTA.F3 = 1;
PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
display_segment(a & 0x0F); //Hr1
delay_ms(5);} break;
case 3 : {
PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 0; PORTA.F3 = 1;
PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
display_segment(a>>4); //mn10
delay_ms(5);
PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 0;
PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
display_segment(a & 0x0F); //mn1
delay_ms(5); } break;
}}
void init_ds3231(){
I2C1_Start();
I2C1_Wr(0xD0); //address of ds3231 setting 15/4/2015 11:20:20AM,sunday
I2C1_Wr(0X00); //address of sec register, 00h
I2C1_Wr(0x50); //data of sec register, 50h
I2C1_Wr(0x59); //data for minute register at 01h address 59-0101 1001
I2C1_Wr(0x51); //data of hr register,0101 0001 =11 at 02h
I2C1_Wr(0x01); //data of day register, 01-07,sunday=01 at 03h ok
I2C1_Wr(0x15); //data of date register, 01-31, day-15=0001 0101 at 04h
I2C1_Wr(0x06); //data of month register, 01-12, june=0000 0110 at 05h
I2C1_Wr(0x15); //data of yr register, 00-99, 15=0001 0101 at 06h
I2C1_Wr(0x00); //data of alarm1 at 07h
I2C1_Wr(0x80); //data of alarm1 at 08h
I2C1_Wr(0x80); //data of alarm1 at 09h
I2C1_Wr(0x80); //data of alarm1 at 0Ah
I2C1_Wr(0x00); //data of alarm2 at 0Bh
I2C1_Wr(0x00); //data of alarm2 at 0Ch
I2C1_Wr(0x00); //data of alarm2 at 0Dh
I2C1_Wr(0x25); //osc running, conv enable, alarm at 00 sec 0010 0101 address 0Eh
I2C1_Stop(); }
void write_ds3231(unsigned short address, unsigned short data1){
I2C1_Start();
I2C1_Is_Idle();
I2C1_Wr(0xD0);
I2C1_Is_Idle();
I2C1_Wr(address);
I2C1_Is_Idle();
I2C1_Wr(data1);
I2C1_Is_Idle();
I2C1_Stop();}
unsigned short read_ds3231(unsigned short address) {
unsigned short data1=0;
unsigned short i;
I2C1_Start();
I2C1_Wr(0xD0);
I2C1_Wr(address);
I2C1_Repeated_Start();
I2C1_Wr(0xD1);
data1 = I2C1_Rd(0u);
I2C1_Start();
for(i=0;;i++) {
if (I2C1_Wr(0xD1)==1){I2C1_start();}
else break; }
I2C1_Is_Idle();
I2C1_Stop();
return(data1);}
void display_segment(short int u){
switch(u){
case 0 : PORTB = 0b01111110; break; //0 ; segment a=PortB.F1, g=PORTB.F7
case 1 : PORTB = 0b00001100; break;
case 2 : PORTB = 0b10110110; break;
case 3 : PORTB = 0b10011110; break;
case 4 : PORTB = 0b11001100; break;
case 5 : PORTB = 0b11011010; break;
case 6 : PORTB = 0b11111010; break;
case 7 : PORTB = 0b00001110; break;
case 8 : PORTB = 0b11111110; break;
case 9 : PORTB = 0b11011110; break;}} //9
void select_digit(unsigned short mn, unsigned short hr){
unsigned short key;
PORTA.F4 = PORTA.F5 =PORTC.F2=1;
for(;;){
display(mn, 3);
//PORTA.F3 = PORTA.F2 = 0;
Delay_ms(1000); //blinking mn10, mn1
if(PORTA.F0==0){
key = read_button();
while(key==2){
mn = Bcd2Dec(mn);
mn++;
if(mn > 59) mn = 0;
mn = Dec2Bcd(mn);
display(mn, 3);
delay_ms(300);
key = read_button();}}
display(hr, 1);
Delay_ms(1000);
//PORTC.F0 = PORTA.F1 = 0;
//PORTC.F0 = PORTA.F1 = 1; Delay_ms(1000); // blinking hr10, hr1
if(PORTA.F0==0){
key = read_button();
while(key==2){
hr = Bcd2Dec(hr);
hr++;
if(hr > 12)hr = 0;
hr = Dec2Bcd(hr);
display(hr, 1);
delay_ms(300);
key = read_button();}
if(key==3){
hr=0b00011111&hr;
hr=0b01000000|hr;
write_ds3231(0x02, hr);
write_ds3231(0x01, mn);}}
if(key==3)break;}}
unsigned short read_button(void){
unsigned int Vin=0;
unsigned short val=0;
TRISA = 0x01;
ADCON1 = 0b11001110;
Vin = ADCRead(0);
if((Vin > 30) && (Vin < 250)) val = 1; // select hr or min
if((Vin > 410) && (Vin < 470)) val = 2; // increase value of hr or min
if((Vin > 600) && (Vin < 670)) val = 3; // come out from change loop
return val;}
unsigned int ADCRead(unsigned char channel){
unsigned char l_byte, h_byte;
unsigned int ADR;
l_byte=h_byte=ADR=0;
ADCON0 = 0b01000101;
delay_us(40); //Acquisition Delay
GO_DONE_bit = 1; //Set GO_DONE bit to start conversion
while (GO_DONE_bit == 1); //Wait for bit to be cleared
//If bit is cleared, this means conversion is over
l_byte = ADRESL;
h_byte = ADRESH;
ADR = (h_byte<<8)|l_byte;
return ADR;}
unsigned int read_display_temp(void){
unsigned short T_fraction, tempU, tempL, test;
unsigned int tmp_C;
T_fraction=tempU=tempL=test=tmp_C = 0;
tempU = read_ds3231(0x11);
tempL = (read_ds3231(0x12)) >> 6;
if (tempU & 0x80){
tempU = ~tempU + 1;
PORTC.F5 = 1;} //whether tmp is negitive
else PORTC.F5 = 0;
if (tempL == 0b00) T_fraction = 0;
else if (tempL == 0b01) T_fraction = 2;
else if (tempL == 0b10) T_fraction = 5;
else T_fraction = 7;
tmp_C = tempU*10 + T_fraction;
return (tmp_C);}
void Buzzer(){
short int i;
Sound_Init(&PORTC, 1);
for (i = 0; i < 5; i++) {
Sound_Play(800, 1000);
Sound_Play(0, 700);
if(i==4) Sound_Play(800, 1400);
}}