Предлагаем схему простых часов на АВР, которые можно встроить в какое-нибудь свое устройство или использовать как законченное устройсво. Она состоит только из микроконтроллера AVR processor and и четырехзначного дисплея с общим анодом.
Схема часов на AVR (нажмите для увеличения):
Фото готового устройства:
Код программы часов:
#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;
}
volatile unsigned char prescale=0;
volatile unsigned char sec=0;
volatile unsigned char min_1=0;
volatile unsigned char min_10=0;
volatile unsigned char hour_1=0;
volatile unsigned char hour_10=0;
volatile 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;
}
}
}
Прошивку, исходник и схему в формате Eagle можно скачать отсюда