Digital-Clock / clock.c
clock.c
Raw
/* 
 * 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 <stdio.h>
#include <stdlib.h>
#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;
}
 */