/* * File: clock.c * Author: Bassem * * Created on June 2, 2019, 8:14 PM * clock with pic16f877a and DS1307 * * notes: * ds1307 data is in BCD * * /*7 segment configuration ------B5------- / / / / B6 B4 / / / / ------B3------- / / / / B0 B2 / / / / ------B1------- B7 */ #include #include #include "config.h" #include "I2C.h" #define pause 5000 //multiplexer time delay between digits in us #define btndelay 50 //time between each press of a button in ms void Print(unsigned int ,unsigned int ); void setTime(int,int); int BCDToDecimal(int ); int DecimalToBCD (int ); void Alarm(int *x, int *y); //int Buzzer(); void main() { TRISB = 0; PORTB = 0x00; TRISD = 0; ADCON1 = 0x07; //set all PORTA,PORTE as digital I/O TRISA1 = 1; //pin A1 input TRISA2 = 1;// pin A2 input TRISA3 = 1; int hours, minutes; int AlarmState = 0; // 0 for off 1 for on int AlarmHour = 12, AlarmMinute = 0; I2C_Master_Init(100000); //ds1307 I2C frequency 100khz //setTime(0x12,0x00); to set time the first time later the ds1307 will keep the time using a battery while(1) { I2C_Master_Start(); I2C_Master_Write(0xD0); //DS1307 address + write bit I2C_Master_Write(0x02); // hours address I2C_Master_RepeatedStart(); I2C_Master_Write(0xD1);//address+ read bit hours = I2C_Master_Read(0);//0 to ack I2C_Master_Stop(); hours = hours & 0b00011111; hours = BCDToDecimal(hours); I2C_Master_Start(); I2C_Master_Write(0xD0); //DS1307 address + write bit I2C_Master_Write(0x01); // minutes address I2C_Master_RepeatedStart(); I2C_Master_Write(0xD1);//address+ read bit minutes = I2C_Master_Read(0); minutes = BCDToDecimal(minutes); I2C_Master_Stop(); Print(hours,minutes); if( RA1 == 1 )// set hours { __delay_ms(btndelay);//to prevent registering multiple presses if(RA1 == 1) { hours++; if(hours == 13) { hours = 1; } hours = DecimalToBCD(hours); minutes = DecimalToBCD(minutes); setTime(hours, minutes); } } if( RA2 == 1 )// set minutes { __delay_ms(btndelay);//to prevent registering multiple presses if(RA2 == 1) { minutes++; if( minutes == 60) { minutes = 0; } hours = DecimalToBCD(hours); minutes = DecimalToBCD(minutes); setTime(hours, minutes); } } if (RA3 == 1) { __delay_ms(btndelay); if(RA3 == 1) { Alarm(&AlarmHour,&AlarmMinute); AlarmState = 1; /* if(RA1 == 1 && RA2 == 1)// press the 2 btns simultaneously to turn alarm off { AlarmState = 0; } */ } } if (AlarmState == 1) { RD4 = 1; RB7 = 1; if(hours == AlarmHour && minutes == AlarmMinute) { PORTB=0x00; for (int i = 0; i<20 ; i++) { RD4 = 1; RB7 = 1; __delay_ms(1000); RD4 = 0; RB7 = 0; __delay_ms(1000); } AlarmState = 0; RD4 = 0; RB7 = 0; /* AlarmState = Buzzer(); RD4 = 0; RB7 = 0; */ } } } } void Print(unsigned int hour, unsigned int min) { // unsigned int const seg[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//0-9 in 7seg different 7 segment wiring unsigned int const seg[10] = {0x77,0x14,0x3B,0x3E,0x5C,0x6E,0x6F,0x34,0x7F,0x7E};//0-9 in 7seg int hour1 = hour/10; int hour2 = hour%10; int min1 = min/10; int min2 = min%10; PORTD = 0x00;//to prevent ghosting PORTB = 0x00;//same PORTB = seg[hour1]; RD7 = 1; __delay_us(pause); PORTD = 0x00; PORTB = 0x00; PORTB = seg[hour2]; RB7 = 1; RD6 = 1; __delay_us(pause); PORTD = 0x00; PORTB = 0x00; PORTB = seg[min1]; RB7 = 1; RD5 = 1; __delay_us(pause); PORTD = 0x00; PORTB = 0x00; PORTB = seg[min2]; RD4 = 1; __delay_us(pause); } void setTime(int hrs, int min) { I2C_Master_Start(); I2C_Master_Write(0xD0); //DS1307 address + write bit I2C_Master_Write(0x00); // seconds address I2C_Master_Write(0x00); //00 sec I2C_Master_Stop(); I2C_Master_Start(); I2C_Master_Write(0xD0); //DS1307 address + write bit I2C_Master_Write(0x01); // min address I2C_Master_Write(min); // min in bcd I2C_Master_Stop(); hrs = hrs | 0b01100000; //12hr mode an in PM I2C_Master_Start(); I2C_Master_Write(0xD0); //DS1307 address + write bit I2C_Master_Write(0x02); // hours address I2C_Master_Write(hrs); I2C_Master_Stop(); } int BCDToDecimal(int BCD) { return (((BCD>>4)*10) + (BCD & 0xF)); } int DecimalToBCD (int Decimal) { return (((Decimal/10) << 4) | (Decimal % 10)); } void Alarm(int *x,int *y) { while(1) { Print (*x,*y); RD7 = 1; RB7 = 1; __delay_us(pause); if (RA1 == 1) { __delay_ms(btndelay); if(RA1 == 1) { *x = *x+1; } if( *x == 13) *x = 1; } if(RA2 == 1) { __delay_ms(btndelay); if(RA2 == 1) { *y = *y+1; } if(*y == 60) *y = 0; } if (RA3 == 1) //press RA3 to set save the time { __delay_ms(btndelay); if(RA3 == 1) { RD7 = 0; RB7 = 0; break; } } } } /* int Buzzer() { while(1) { for(int i = 0; i < 2000; i++)//2khz for 1 sec { RD0 = 1; __delay_us(250); RD0 = 0; __delay_us(250); } __delay_ms(1000); if(RA3 == 1) { break; } } return 0; } */