Sunteți pe pagina 1din 14

/*CPU speed is defined so delay functions can work*/

#define F_CPU 4000000UL


#include <util/delay.h>

/*AVR interrupt library*/


#include <avr/io.h>

#include <avr/interrupt.h>

/*Initial state is RESET*/


unsigned char state=1;
unsigned char display=0;

/*Send out the appropriate number digit for output*/


unsigned char display7seg(unsigned char num);

/*The show() function switches the different segments*/


void show(unsigned char hrs, unsigned char min, unsigned char sec);

/*Initializing minute and second variables*/


unsigned char hours = 12;
unsigned char minutes=58;
unsigned char seconds=58;

unsigned char alarm_hour = 0;


unsigned char alarm_minutes = 0;
unsigned char alarm_seconds = 0;

/*Functions which control the different states*/


void run_state(void);
void set_state(void);
void reset_state(void);
void alarm_state(void);

/*The button_check() function polls PIND for button press*/


void button_check_state(void);
void button_check_setTime(void);
void button_check_setAlarm(void);

/* Declaration of Timer ISR*/


ISR(TIMER1_COMPA_vect);

/* functions to change clock values*/


void set_clock_minutes(void);
void set_clock_hours(void);

/* function to change alarm values*/


void set_alarm_minutes(void);
void set_alarm_hours(void);

/* sound buzzer when alarm conditions are met*/


void alarm(void);

int main(void)
{

/* Make PORTB output*/

DDRB = 0xFF;
/*Make PD4, PD5,PD6 output to switch 7 segs and PD0 for buzzer*/

DDRD = 0b01110001;

/*Enable pull-up resistors on PD1, PD2 and PD3*/


PORTD = 0b0001110;

/*Enable Global Interrupts*/


sei();

while (1)
{
/*show clock values*/
show(hours, minutes, seconds);
button_check_state();
/*Runs the appropriate function given the state*/
switch (state)
{
case 1:
/*Run*/
run_state();
break;
case 2:
/*Set clock*/
set_state();
break;
case 3:
/*Reset clock*/
reset_state();
break;
case 4:
/*alarm*/
alarm_state();
}
}
return 0;
}

void show(unsigned char hrs, unsigned char min, unsigned char sec){

/*Segment to display hours*/

/*Display number in TENS position*/


if (hrs < 10)
{
PORTB = display7seg(111);// blank out zeros
PORTD = 0b01011110;
_delay_us(100);
}
else
{
PORTB = display7seg(hrs/10);
PORTD = 0b01011110;
_delay_us(100);
}
/*Display number in ONES position*/
PORTB=display7seg(hrs % 10);
PORTD = 0b00011110;
_delay_us(50);
/*Segment to display minutes*/

/*Display number in TENS position*/


PORTB=display7seg(min/10);
PORTD = 0b01101110;
_delay_us(50);

/*Display number in ONES position*/


PORTB=display7seg(min % 10);
PORTD = 0b00101110;
_delay_us(50);

/*Segment to display seconds*/

/*Display number in TENS position*/


PORTB=display7seg(sec/10);
PORTD = 0b01001110;
_delay_us(50);

/*Display number in ONES position*/


PORTB=display7seg(sec % 10);
PORTD = 0b00001110;
_delay_us(50);

void run_state(void)
{
show(hours, minutes, seconds);
/*Timer 1 is configured and started*/
TCCR1B=(1<<CS12|1<<WGM12);

/*Put appropriate value for OCR1A*/


OCR1A= 1953;

/*Output Compare Interrupt Enabled*/


TIMSK=(1<<OCIE1A);
state = 1;
show(hours, minutes, seconds);
//check if clock value equals alarm
alarm();

void set_state(void)
{
/*stop timer*/
TCCR1B=0;

while(state == 2)
{
// while in set state determine which button is pressed
button_check_setTime();
show(hours, minutes, seconds);
}

void reset_state(void)
{
//stop timer and set clock to default values
TCCR1B = 0;
hours = 12;
minutes = 0;
seconds = 0;
state = 1;
show(hours, minutes, seconds);

void alarm_state()
{
while (state == 4)
{
// check which button is pressed while in the alarm state
button_check_setAlarm();
show(alarm_hour, alarm_minutes, alarm_seconds);
}
}

void button_check_state(void)
{

/*Test if the switch on PD1 is pressed (set time)*/


if (!(PIND & 0b00000010))
{
/*De-bounce pressed switch */
_delay_ms(50);
state = 2;
}

/* Test if the switch on PD2 (reset clock to 12:00) is pressed */


if (!(PIND & 0b00000100))
{
_delay_ms(50);
/*De-bounce pressed switch */
state = 3;
}

/*if PD3 pressed (set alarm) clock*/


if (!(PIND & 0b00001000))
{
_delay_ms(150);
/*De-bounce pressed switch */
state = 4;
}

void button_check_setTime(void)
{
if (!(PIND & 0b00000010))
{
/*De-bounce pressed switch */
_delay_ms(50);
//if switch on PD1 is pressed set state to 1 (run state)
state = 1;
}
if (!(PIND & 0b00000100))
{
/*De-bounce pressed switch */
_delay_ms(50);
// if switch on PD2 is pressed increment clock minutes
set_clock_minutes();
}
if (!(PIND & 0b00001000))
{
/*De-bounce pressed switch */
_delay_ms(50);
// if switch on PD3 is pressed increment clock hours
set_clock_hours();
}

void button_check_setAlarm()
{
if (!(PIND & 0b00001000))
{
_delay_ms(50);
//if switch on PD3 is pressed set state to 1 (run state)
state = 1;
}
if (!(PIND & 0b00000010))
{
_delay_ms(150);
// if switch on PD3 is pressed increment clock hours
set_alarm_hours();
}
if (!(PIND & 0b00000100))
{
_delay_ms(150);
// if switch on PD3 is pressed increment clock hours
set_alarm_minutes();
}
}

void set_clock_hours()
{
if (hours == 12)
{
hours = 1; // ensures that hour is within range
}
else
{
hours++;
}
}

void set_clock_minutes()
{
if (minutes == 59)
{
minutes = 0;// ensure that minute is within range
}
else
{
minutes++;
}
}

void set_alarm_hours()
{
if (alarm_hour == 12)
{
alarm_hour = 0;// ensures that hour is within range
}
else
{
alarm_hour++;
}
}

void set_alarm_minutes()
{
if (alarm_minutes == 59)
{
alarm_minutes = 0;// ensure that minute is within range
}
else
{
alarm_minutes++;
}
}

ISR (TIMER1_COMPA_vect)
{
if (seconds==59)
{
seconds=0;
if (minutes==59)
{
minutes=0;
if (hours == 12)
{
hours = 1;
}
else
{
hours++;
}
}
else
{
minutes++;
}

}
else
{
seconds++;
}
}

void alarm()
{
if ((hours == alarm_hour) && (minutes == alarm_minutes))
{
//if alarm minutes and hours equals clock minutes and hour activate buzzer
with output 1 to PD0
PORTD = 0b00001111;
}
else
{
//if alarm criterea not met do not activate buzzer
PORTD = 0b00001110;
}
}

unsigned char display7seg(unsigned char num)


{
switch (num)
{
case 0:
display = 0b00111111;
break;
case 1:
display = 0b00000110;
break;
case 2:
display = 0b01011011;
break;
case 3:
display = 0b01001111;
break;
case 4:
display = 0b01100110;
break;
case 5:
display = 0b01101101;
break;
case 6:
display = 0b01111101;
break;
case 7:
display = 0b00000111;
break;
case 8:
display = 0b01111111;
break;
case 9:
display = 0b01100111;
break;
case 111: // special case used to blank zeros
display = 0b00000000;// use to blank out zeros
break;

}
return display;
}