Tuesday, 24 December 2013

ATMEGA 16 SEVEN SEGMENT DIGITAL CLOCK

In this ATMega16 AVR project we will be designing and implementing a digital clock with the aid of a Atmel AVR ATMega16 microcontroller and Seven Segment Displays.

Note: Although this AVR project was designed around the ATMega16 the project could have utilized another microcontroller such as an ATMega32, ATMega8515, etc.

 


ATMega16 Digital Clock Operation
 
Our digital clock operates as follows. When the circuit is powered up the clock starts at "00:00:00" for "HH:MM:SS". There are two push-button switches used to set the time. Switch SW1 is for setting the minutes, when this button is pressed the minutes in increase until it reaches 59 then reset and start counting from 0. Switch SW2 is for setting the hours.


Hardware Description for the ATMega16 Digital Clock

The figure below gives the circuit diagram for the ATmega16 Seven Segment Display Digital Clock. One feature to note in that all seven segment displays are driven by the same port (PortB). The microcontroller through controls from PortC indicate which seven segment display each digit is displayed on. Note that these Seven Segment Displays are common cathode display.









Important Note: In order for our digital clock to work correctly the internal oscillator of the ATMega16 AVR microcontroller must be enabled and set to 4MHz.
Software for the ATMega16 Digital Clock
Below is the AVR C implementation of the entire code for the ATMega16 based digital clock. The code was implemented and built using AVR Studio 5. Be reminded that the internal clock of the ATMega16 microcontroller should be enabled and programmed to operate at 4MHz for the AVR C code to operate correctly. A video of the digital clock in operation is presented at the end of this page.
Below is the AVR C code for the ATMega16 Based Digital Clock. This code was written in AVR Studio 5.
 CODING FOR SEVEN SEGMENT DIGITAL CLOCK


#define F_CPU  4000000UL
#include <avr/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
 
#define SegDataPort                       PORTB
#define SegDataPin                        PINB
#define SegDataDDR                      DDRB
 
#define SegCntrlPort                      PORTC
#define SegCntrlPin                        PINC
#define SegCntrlDDR                     DDRC
 
/*Global Variables Declarations*/
unsignedchar hours =0;
unsignedchar minutes =0;
unsignedchar seconds =0;
 
/*Function Declarations*/
/*****************************************************************************/
/*Decimal Digit (0-9) to Seven Segment Values Encoder*/
unsignedchar DigitTo7SegEncoder(unsignedchar digit,unsignedchar common);
 
/*Timer Counter 1 Compare Match A Interrupt Service Routine/Interrupt Handler*/
ISR(TIMER1_COMPA_vect);
 
/*Main Program*/
/*****************************************************************************/
int main(void)
{
SegDataDDR=0xFF;
SegCntrlDDR=0x3F; 
SegCntrlPort=0xFF; 
TCCR1B =(1<<CS12|1<<WGM12);
OCR1A =15625-1;
 TIMSK =1<<OCIE1A;
 sei();
  
 while(1)
{
/* Set Minutes when SegCntrl Pin 6 Switch is Pressed*/
                               if((SegCntrlPin&0x40)==0)
{              
_delay_ms(200);
if(minutes <59)
minutes++;
else
minutes=0;
}
/* Set Hours when SegCntrl Pin 7 Switch is Pressed*/                                            
                               if((SegCntrlPin&0x80)==0)
{              
  _delay_ms(200);
 if(hours <23)
 hours++;
  else
hours=0;
}                                              
SegDataPort=DigitTo7SegEncoder(seconds%10,1);
SegCntrlPort= ~0x01;
SegDataPort=DigitTo7SegEncoder(seconds/10,1);
SegCntrlPort= ~0x02;
SegDataPort=DigitTo7SegEncoder(minutes%10,1); 
 SegCntrlPort= ~0x04;
 SegDataPort=DigitTo7SegEncoder(minutes/10,1);
SegCntrlPort= ~0x08;
SegDataPort=DigitTo7SegEncoder(hours%10,1);
SegCntrlPort= ~0x10;
SegDataPort=DigitTo7SegEncoder(hours/10,1);
SegCntrlPort= ~0x20;
 }
  return0;
}
 
/*
* Function Description:
* Encode a Decimal Digit 0-9 to its Seven Segment Equivalent.
*
* Function Arguments:
* digit - Decimal Digit to be Encoded
* common - Common Anode (0), Common Cathode(1)
* SegVal - Encoded Seven Segment Value 
*
* Connections:
* Encoded SegVal is return in the other G-F-E-D-C-B-A that is A is the least
* significant bit (bit 0) and G bit 6.
*/
unsignedchar DigitTo7SegEncoder(unsignedchar digit,unsignedchar common)
{
 unsignedcharSegVal; 
 switch(digit)         
{              
case0:    if(common ==1)   SegVal=0b00111111;
 else
SegVal= ~0b00111111;
  break;
  case1:    if(common ==1)   SegVal=0b00000110;
  else 
   SegVal= ~0b00000110;
   break;
case2:    if(common ==1)   SegVal=0b01011011;
 else
SegVal= ~0b01011011;
break;
 case3:    if(common ==1)   SegVal=0b01001111;
else 
SegVal= ~0b01001111;
 break;
  case4:    if(common ==1)   SegVal=0b01100110;                    
   else
  SegVal= ~0b01100110;
   break;
   case5:    if(common ==1)   SegVal=0b01101101;
    else                                       
  SegVal= ~0b01101101;
   break;
  case6:    if(common ==1)   SegVal=0b01111101;
   else                                       
SegVal= ~0b01111101;                                                            
break;                                
case7:    if(common ==1)   SegVal=0b00000111; 
else                                       
SegVal= ~0b00000111;                                                              
break;                               
 case8:    if(common ==1)   SegVal=0b01111111;                                                              
else                                       
SegVal= ~0b01111111;                                                              
break;                                
case9:    if(common ==1)   SegVal=0b01101111;                                                              
else                                      
 SegVal= ~0b01101111;                                   
}                                            
 returnSegVal;
}
 
/*Timer Counter 1 Compare Match A Interrupt Service Routine/Interrupt Handler*/
ISR(TIMER1_COMPA_vect)
{
 seconds++;
  if(seconds ==60)
  {                               
 seconds=0;                                
minutes++;                
}                
if(minutes ==60)                
{                                
minutes=0;                                
hours++;                                             
}                
if(hours >23)                                
hours=0;
} 

No comments:

Post a Comment

share your thoughts