ATMega16 AVR Microcontroller LCD Digital Clock
ATMega16 AVR Microcontroller LCD Digital Clock
ATMega16 AVR Microcontroller LCD Digital Clock
Digital Clock
The ATMega16 LCD 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 an alphanumeric liquid
crystal display (LCD).
Note: Although this AVR project was designed around the ATMega16 the project could
have utilized another microcontroller such as an ATMega32, ATMega8515, etc.
The figure below gives the circuit diagram for the ATmega16 LCD Digital Clock.
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.
Below is the AVR C implementation of the entire code for the ATMega16 based LCD
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 LCD digital clock in operation is presented at the end of this page.
/*
* LCD-Digital-Clock.c
*
* Written in AVR Studio 5
* Compiler: AVR GNU C Compiler (GCC)
*
* Created: 12/22/2011 6:34:36 PM
* Author: AVR Tutorials
* Website: www.AVR-Tutorials.com
*/
#define LCD_RS_PIN 5
#define LCD_RW_PIN 6
#define LCD_ENABLE_PIN 7
#define SET_HOUR 3
#define SET_MINUTE 4
int main(void)
{
unsigned char i;
LCD_init();
LCD_goto(1,2);
LCD_print("AVR-Tutorials");
LCD_goto(2,4);
LCD_print(time);
TCCR1B = (1<<CS12|1<<WGM12);
OCR1A = 15625-1;
TIMSK = 1<<OCIE1A;
sei();
while(1)
{
if(!(LCD_CNTRL_PIN & (1<<SET_HOUR)))
{
hours++;
if(hours > 23)
hours = 0;
}
if(!(LCD_CNTRL_PIN & (1<<SET_MINUTE)))
{
minutes++;
if(minutes > 59)
minutes = 0;
}
_delay_ms(250);
}
}
LCD_CNTRL_PORT |= (1<<LCD_ENABLE_PIN);
_delay_us(2);
LCD_CNTRL_PORT &= ~(1<<LCD_ENABLE_PIN);
_delay_us(100);
}
LCD_CNTRL_PORT |= (1<<LCD_ENABLE_PIN);
_delay_us(2);
LCD_CNTRL_PORT &= ~(1<<LCD_ENABLE_PIN);
_delay_us(100);
}
void LCD_init()
{
LCD_CNTRL_DDR = 0xFF;
LCD_CNTRL_PORT = 0x00;
LCD_DATA_DDR = 0xFF;
LCD_DATA_PORT = 0x00;
_delay_ms(10);
LCD_send_command(0x38);
LCD_send_command(0x0C);
LCD_send_command(0x01);
_delay_ms(10);
LCD_send_command(0x06);
}
/* This function moves the cursor the line y column x on the LCD
module*/
void LCD_goto(unsigned char y, unsigned char x)
{
unsigned char firstAddress[] = {0x80,0xC0,0x94,0xD4};
LCD_send_command(firstAddress[y-1] + x-1);
_delay_ms(10);
}
while(string[i]!=0)
{
LCD_send_data(string[i]);
i++;
}
}
void LCD_update_time()
{
unsigned char temp;
LCD_goto(2,4);
itoa(hours/10,temp,10);
LCD_print(temp);
itoa(hours%10,temp,10);
LCD_print(temp);
LCD_print(":");
itoa(minutes/10,temp,10);
LCD_print(temp);
itoa((minutes%10),temp,10);
LCD_print(temp);
LCD_print(":");
itoa(seconds/10,temp,10);
LCD_print(temp);
itoa(seconds%10,temp,10);
LCD_print(temp);
}
/*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;
LCD_update_time();
}