The homepage of David 'daqq' Gustafik
The AVR controlled clock

The AVR controlled clock:

A friend of mine needed a clock into his amplifier as an extra function. So I made him one. It consists only of one AVR processor and one BQ-M512RD (or compatible, with common anodes) LED display. I tried to keep the whole clock as simple as possible, so anyone can build one...

Here's the schematic [DOWNLOAD GIF]

And the photo of the device:

photo

The source code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <stdio.h>



#define _s_A  2
#define _s_B  0
#define _s_C  6
#define _s_D  4
#define _s_E  3
#define _s_F  1
#define _s_G  7
#define _s_dot 5

const unsigned char segs[] =
{
    _BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F),    //0
    _BV(_s_B) | _BV(_s_C),    //1
    _BV(_s_A) | _BV(_s_B) | _BV(_s_D) | _BV(_s_E) | _BV(_s_G),    //2
    _BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_G),  //3
    _BV(_s_B) | _BV(_s_C) | _BV(_s_F) | _BV(_s_G),    //4
    _BV(_s_A) | _BV(_s_C) | _BV(_s_D) | _BV(_s_F) | _BV(_s_G), //5
    _BV(_s_A) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G), //6
    _BV(_s_A) | _BV(_s_B) | _BV(_s_C), //7
    _BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G),//8
    _BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_F) | _BV(_s_G),//9
   
    _BV(_s_A) | _BV(_s_B) | _BV(_s_C) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G),    //A
    _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G),    //B
    _BV(_s_A) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F), //C
    _BV(_s_B) | _BV(_s_C) | _BV(_s_D) | _BV(_s_E) | _BV(_s_G), //D
    _BV(_s_A) | _BV(_s_D) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G), //E
    _BV(_s_A) | _BV(_s_E) | _BV(_s_F) | _BV(_s_G) //F

};



#define _ms(n) (17*n)

void wait(unsigned int a)    //basic wait
{                           
    volatile unsigned int b,c;
    for(b=0;b!= a; b++)for(c=0;c!= 50;c++);
    return;
}



unsigned char prescale=0;
unsigned char sec=0;
unsigned char min_1=0;
unsigned char min_10=0;
unsigned char hour_1=0;
unsigned char hour_10=0;
unsigned char show_t=0;


ISR(TIMER1_OVF_vect)
{
    if(++prescale == 225){prescale = 0;sec++;};
    if(sec>59){min_1++;sec=0;};
    if(min_1>9){min_1=0;min_10++;};
    if(min_10>5){min_10=0;hour_1++;};
    if(hour_1>9){hour_1=0;hour_10++;};
    if(hour_10>1 && hour_1>3){hour_1=0;hour_10=0;};
   
    if(++show_t==4) show_t=0;
    switch(show_t)
    {
        case 0:    //show minutes
            PORTC = 0x04;
            PORTD = (~segs[min_1]);
            break;
        case 1:    //show 10 minutes
            PORTC = 0x08;
            PORTD = (~segs[min_10]);
            break;
        case 2:    //show hours
            PORTC = 0x10;
            PORTD = (~segs[hour_1]) & ~_BV(_s_dot);
            break;
        case 3:    //show 10hours
            PORTC = 0x20;
            PORTD = (~segs[hour_10]);
            break;
        default:
            show_t = 0;
            break;
    }   
    return;
}


#define B1() (bit_is_clear(PINB,3))
#define B2() (bit_is_clear(PINB,4))
#define B_WAIT 300

#define nop() asm volatile ("nop;")

int main(void)
{

    TIMSK = 0x04;
    TCCR1B = 0x01;

    DDRD = 0xFF;
    DDRC = 0x3F;
    DDRB = 0x00;
    PORTB = 0xFF;
   
    sei();
    while(1)
    {
        if(B1())
        {
            wait(_ms(B_WAIT));
            min_1++;
            sec=0;
        }
        if(B2())
        {
            wait(_ms(B_WAIT));
            hour_1++;
            sec=0;
        }
    }
}

Sorry for the lack of comments. It was a really simple project, so I didn't need em. Enjoy!

Here is the project folder (source, hexfile) and the schematic in Eagle format: [DOWNLOAD]

Update: Radek Stybnar made a nice little clock based on my design:

Radeks AVR Clock

 
bottombar