Простые часы на AVR

simple avr clock1Предлагаем схему простых часов на АВР, которые можно встроить в какое-нибудь свое устройство или использовать как законченное устройсво. Она состоит только из микроконтроллера AVR processor and и четырехзначного дисплея с общим анодом.

Схема часов на AVR (нажмите для увеличения):

simple avr clock sch

Фото готового устройства:

simple avr clock1

Код программы часов:

 

#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 можно скачать отсюда

Загрузка...