This project is based on the timer/counter 0 example. It shows time, date and temparature on 7 segment displays. Instead of the LCD display the time is shown on a four digit 7 segment display with common cathode. The date and temparature is shown on a 7 segment LED display with comon anode.

The ATMEGA328 is used to control the display, the ATMEGA8 can also be used. The circuit use 6 I/O pins from port B and 2 I/O pins from port C to control the digits and 8 I/O pins from port D to control the segments of each digit. The temperature is read from a LM335 temperature sensor.  


 

 The core of the circuit is the ATMEGA328 microcontroller. The four segment LED display is connected to PORTC and PORTD. With multiplexing the data will be show on the display. Via the I/O port of PORTB and PORTC the digits are switched on and off while PORTD select the segments.

 LED display

 


The circuit is build on a prototyping board and is connected with flatcables to the ATMEGA328 board. The ATMEGA328 board contains the microcontroller and other parts.

LED clock pic2


The software code is written in C and developed with the WINAVR compiler. See here how to work with the C-compiler, and here how to program the microcontroller

// program name: RTC clock LED display 
// last update: 01-feb-2016
// author: www.avrprojects.net
// target device : ATMEGA8/328
// software code: WINAVR

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define F_CPU = 16000000;

unsigned char time_count;

volatile unsigned char second;

const char DaysInMonth [12] = {31,28,31,30,31,30,31,31,30,31,30,31};


// Example of __TIME__ string: "09:30:19"
// 01234567
/*
#define COMPILE_HOUR (((__TIME__[0]-'0')*10) + (__TIME__[1]-'0'))
*/
//char TIME[] = __TIME__;
char hour = 17;
char minute = 30;
char day = 31;
char month = 1;
char year = 16;

unsigned char d1, d2, d3, d4,d5,d6,d7,d8,d9,d10,d11,d12;

const unsigned char LED[12] = {
0b11000000, //0
0b11111001, //1
0b10100100, //2
0b10110000, //3
0b10011001, //4
0b10010010, //5
0b10000010, //6
0b11111000, //7
0b10000000, //8
0b10010000, //9
0b10011100, //gr
0b11000110, //C
};

const char dp = 0b10000000;

char data[4];

// Timer 0 overflow interrupt service routine
// increase the the seconds and calculate the minutes, hours, days and months.
ISR(TIMER0_OVF_vect)
{
//set timer to 256-250 = 6
TCNT0= 6;

++time_count;
if (time_count == 250)

{time_count = 0; // set to 0
second++; // increase second
if (second > 59 )
{second = 0;
minute++;
if (minute > 59)
{minute = 0;
hour++;
if (hour > 23)
{hour = 0;
day++;
char LastMonthDay = DaysInMonth[month-1];
if (day > LastMonthDay)
{
day = 1;
month++;
}
}
}
}
}
}

// this function read the value of ADC channel 0
unsigned int read_adc(void)
{
ADCSRA |= 1<<ADSC; //start conversion;
while (ADCSRA&(1<<ADSC)); //wait conversion end
{
return ADCW;
}
}

void display(char digit1,char digit2, char digit3, char digit4, char digit5, char digit6, char digit7, char digit8, char digit9, char digit10, char digit11, char digit12)
{
int delay = 1;
PORTC = 0b00000100;
PORTD = ~digit9;
_delay_ms(delay);
PORTC = 0b00001000;
PORTD = ~digit10;
_delay_ms(delay);
PORTC = 0b00010000;
PORTD = ~digit11;
_delay_ms(delay);
PORTC = 0b00100000;
PORTD = ~digit12;
_delay_ms(delay);
PORTC = 0b00000000;


PORTB = 0b00000001;
PORTD = digit1;
_delay_ms(delay);

PORTB = 0b00000010;
PORTD = digit2 &0b01111111;
_delay_ms(delay);

PORTB = 0b00000100;
PORTD = digit3;
_delay_ms(delay);

PORTB = 0b00001000;
PORTD = digit4;
_delay_ms(delay);

PORTB = 0b00010000;
PORTD = ~digit5;
_delay_ms(delay);

PORTB = 0b00100000;
PORTD = ~digit6 |0b10000000;
_delay_ms(delay);
PORTB = 0b00000000;

PORTC = 0b00000001;
PORTD = ~digit7 ;
_delay_ms(delay);

PORTC = 0b00000010;
PORTD = ~digit8;
_delay_ms(delay);
PORTC = 0b00000000;
}

void display_test (void)

{
int delay = 100;
PORTC = 0b00000100;
PORTD = 0b01111111;
_delay_ms(delay);
PORTC = 0b00001000;
PORTD = 0b01111111;
_delay_ms(delay);
PORTC = 0b00010000;
PORTD = 0b01111111;
_delay_ms(delay);
PORTC = 0b00100000;
PORTD = 0b01111111;
_delay_ms(delay);
PORTC = 0b00000000;

PORTB = 0b00000001;
PORTD = 0b10000000;
_delay_ms(delay);
PORTB = 0b00000010;
PORTD = 0b10000000;
_delay_ms(delay);
PORTB = 0b00000100;
PORTD = 0b10000000;
_delay_ms(delay);
PORTB = 0b00001000;
PORTD = 0b10000000;
_delay_ms(delay);

PORTB = 0b00010000;
PORTD = 0b01111111;
_delay_ms(delay);
PORTB = 0b00100000;
PORTD = 0b01111111;
_delay_ms(delay);
PORTB = 0b00000000;

PORTC = 0b00000001;
PORTD = 0b01111111;
_delay_ms(delay);
PORTC = 0b00000010;
PORTD = 0b01111111;
_delay_ms(delay);
PORTC = 0b00000000;
}


int main (void)
{
DDRD = 0xFF; // PORTD as output
DDRB = 0xFF; // PORTB as output
DDRC = 0xFF; // PORTC as output

//adc init
ADMUX = 0b0000000; // set ADC5
ADCSRA = 0b10000110; //set ADEN(bit7), precale by 64

//set timer 0 prescaler to clk/256*/
TCCR0 = 0b00000100;
// enable Timer 0 overflow interrupt*/
TIMSK = 0x01;
sei();

display_test();

while(1)
{
/*
int rawdata = read_adc();
float millivolt = (rawdata/1024.0)*5000;
char celcius = millivolt/10; 
*/
d1 = LED[hour/10];
d2 = LED[hour%10];
d3 = LED[minute/10];
d4 = LED[minute%10];
d5 = LED[day/10];
d6 = LED[day%10];
d7 = LED[month/10];
d8 = LED[month%10]; 
d9 = LED[2];
d10 = LED[0];
d11 = LED[10];
d12 = LED[11];

display(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12);
}

}