/***********************************************************
*
* LED-es óra SHIFT regiszterekkel
*
************************************************************
*
* ATmega8
* 74HC595 Shift regiszter
*
************************************************************
*
* 74HC595 bekötése: GND -> GND
*
* Vcc -> VCC
* OE -> GND
* MR -> VCC
*
* Q0-Q7 - Out
* Q7' - Serial Out
*
************************************************************
*
* 74HC595 működése:
*
* Hogy ha a SH_CP értéke alacsonyról magasra változik,
* akkor a Shift regiszter beolvasssa DS értékét.
* Ahogy az adat léptetve lessz, elmenti a belső
* memóriájába.
* Ha az ST_CP értéke alacsonyról magasra változik,
* akkor a memóriában tárolt adatot kirakja a
* kimenetekre.
*
************************************************************
*
* Portkiosztás:
*
* Óra beállítása PB4
* Perc beállítása PB3
*
* Óra Data PD3
* Óra Latch PD4
* Óra Clk PD5
*
* Perc & másodperc Data PC0
* Perc & másodperc Latch PC1
* Perc & másodperc Clk PC2
*
***********************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <stdio.h>
#include <util/delay.h>
//=============================Definek==============================
#define Min() (bit_is_clear(PINB,3))
#define Hour() (bit_is_clear(PINB,4))
#define nop() asm volatile ("nop;")
volatile unsigned char prescale=0;
volatile unsigned char sec=1, sec_a=1;
volatile unsigned char min=1, min_a=1;
volatile unsigned char hour=1;
volatile unsigned char my_nop_delay=0;
ISR(TIMER1_OVF_vect)
{
if(++prescale == 225){prescale = 0; sec++; sec_a++;};
if(sec>59) {min++; min_a++; sec=1;};
if(sec_a>60) {sec_a=1; sec=1;};
if(min>59) {hour++; min=1;};
if(min_a>60) {min_a=1; min=1;};
if(hour>12) {hour=1;};
for (my_nop_delay=1;my_nop_delay<22;my_nop_delay++){nop();}
if(Min())
{
min++;
min_a++;
prescale = 0;
sec=0;
sec_a=0;
while (Min()); // Addig "vár" a program amég nem engedem fel az aktuális billentyűt
_delay_ms(10); // Mini késleltetés, mert hogy ha az ujjam lassan engedem fel,
}
if(Hour())
{
hour++;
prescale = 0;
sec=0;
sec_a=0;
while (Hour()); // Addig "vár" a program amég nem engedem fel az aktuális billentyűt
_delay_ms(10); // Mini késleltetés, mert hogy ha az ujjam lassan engedem fel,
}
return;
}
//========================Saját header filek=========================
#include "bit_operations.h" // Bitműveletek: bs,bc,btg
//=========================Saját függvények==========================
void _delay_10ms (unsigned int v) { while(v--) _delay_ms(10); } // 10ms késleltetés
void Hour_DS (int); // Data kiküldése (0/1)
void Hour_SH_CP (void); // Shift regiszter feltöltése
void Hour_ST_CP (void); // Kirakása a kimenetre
void Min_sec_DS (int); // Data kiküldése (0/1)
void Min_sec_SH_CP (void); // Shift regiszter feltöltése
void Min_sec_ST_CP (void); // Kirakása a kimenetre
//==============================
int main (void)
//==============================
{
TIMSK = 0x04;
TCCR1B = 0x01;
DDRD = 0xFF;
DDRC = 0x3F;
DDRB = 0x00;
PORTB = 0xFF;
sei();
int x=0;
while (1)
{
for (x=0;x<12;x++)
{
if (x==(12-hour))
{
Hour_DS (1); // Adat megadása
Hour_SH_CP (); // Beolvastatom
}
else
{
Hour_DS (0); // Adat megadása
Hour_SH_CP (); // Beolvastatom
}
}
if (((60-min_a)== 0)||((60-min_a)==59)||((60-min_a)==58)||
((60-min_a)==57)||((60-min_a)==56)) //5
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||// Az "órák" megjelenítése a
//perc és msodperc sávban
(x==30) || (x==35) || (x==40) || (x==45) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==55)||((60-min_a)==54)||((60-min_a)==53)||
((60-min_a)==52)||((60-min_a)==51)) //10
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
(x==30) || (x==35) || (x==40) || (x==45) || (x==55))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==50)||((60-min_a)==49)||((60-min_a)==48)||
((60-min_a)==47)||((60-min_a)==46)) //15
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
(x==30) || (x==35) || (x==40) || (x==50) || (x==55))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==45)||((60-min_a)==44)||((60-min_a)==43)||
((60-min_a)==42)||((60-min_a)==41)) //20
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
(x==30) || (x==35) || (x==45) || (x==50) || (x==55))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==40)||((60-min_a)==39)||((60-min_a)==38)||
((60-min_a)==37)||((60-min_a)==36)) //25
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
(x==30) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==35)||((60-min_a)==34)||((60-min_a)==33)||
((60-min_a)==32)||((60-min_a)==31)) //30
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
(x==35) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==30)||((60-min_a)==29)||((60-min_a)==28)||
((60-min_a)==27)||((60-min_a)==26)) //35
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==30) ||
(x==35) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==25)||((60-min_a)==24)||((60-min_a)==23)||
((60-min_a)==22)||((60-min_a)==21)) //40
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==25) ||(x==35) ||
(x==30) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==20)||((60-min_a)==19)||((60-min_a)==18)||
((60-min_a)==17)||((60-min_a)==16)) //45
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==10) || (x==25) || (x==20) ||(x==35) ||
(x==30) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==15)||((60-min_a)==14)||((60-min_a)==13)||
((60-min_a)==12)||((60-min_a)==11)) //50
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==5 ) || (x==15) || (x==25) || (x==20) ||(x==35) ||
(x==30) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)==10)||((60-min_a)== 9)||((60-min_a)== 8)||
((60-min_a)== 7)||((60-min_a)== 6)) //55
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==0 ) || (x==15) || (x==10) || (x==25) || (x==20) ||(x==35) ||
(x==30) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
if (((60-min_a)== 5)||((60-min_a)== 4)||((60-min_a)== 3)||
((60-min_a)== 2)||((60-min_a)== 1)) //60
{
for (x=0;x<60;x++)
{
if ((x==(60-sec_a)) ||
(x==(60-min_a)) ||
(x==5 ) || (x==15) || (x==10) || (x==25) || (x==20) ||(x==35) ||
(x==30) || (x==45) || (x==40) || (x==55) || (x==50))
{ Min_sec_DS (1); Min_sec_SH_CP (); }
else
{ Min_sec_DS (0); Min_sec_SH_CP (); } }
Min_sec_ST_CP ();
Hour_ST_CP ();
}
}
}
//=========================Külső függvények==========================
//----------------Data kiküldése (0/1)-----------------
void Hour_DS (int bit)
{
if (bit==0) bc (PORTD,3); // Adat láb értéke = 0
if (bit==1) bs (PORTD,3); // Adat láb értéke = 1
}
//-------------Shift regiszter feltöltése--------------
void Hour_SH_CP (void)
{
bc (PORTD,5); // Alacsonyról magasra kell állítani, ezért a biztonság
// kedvéért alacsonyra teszem.
bs (PORTD,5); // Magas szintre teszem SH_CP - t így beolvassa DS értékét
_delay_us(25); // Várok, hát ha túl gyors a proci
bc (PORTD,5); // Visszaállítom SH_CP - t alacsonyba
}
//---Latch megrángatása, az adatot a kimenetre teszi---
//----------------Kirakása a kimenetre-----------------
void Hour_ST_CP (void)
{
bc (PORTD,4); // Alacsonyról magasra kell állítani, hogy kitegye a kimenetre,
// ezért a biztonság kedvéért alacsonyra teszem.
bs (PORTD,4); // Magas szintre teszem ST_CP - t így beolvassa DS értékét
_delay_us(25); // Várok, hát ha túl gyors a proci
bc (PORTD,4); // Visszaállítom ST_CP - t alacsonyba
}
/****************************************************************************************/
/****************************************************************************************/
/****************************************************************************************/
//----------------Data kiküldése (0/1)-----------------
void Min_sec_DS (int bit)
{
if (bit==0) bc (PORTC,0); // Adat láb értéke = 0
if (bit==1) bs (PORTC,0); // Adat láb értéke = 1
}
//-------------Shift regiszter feltöltése--------------
void Min_sec_SH_CP (void)
{
bc (PORTC,2); // Alacsonyról magasra kell állítani, ezért a biztonság
// kedvéért alacsonyra teszem.
bs (PORTC,2); // Magas szintre teszem SH_CP - t így beolvassa DS értékét
_delay_us(25); // Várok, hát ha túl gyors a proci
bc (PORTC,2); // Visszaállítom SH_CP - t alacsonyba
}
//---Latch megrángatása, az adatot a kimenetre teszi---
//----------------Kirakása a kimenetre-----------------
void Min_sec_ST_CP (void)
{
bc (PORTC,1); // Alacsonyról magasra kell állítani, hogy kitegye a kimenetre,
// ezért a biztonság kedvéért alacsonyra teszem.
bs (PORTC,1); // Magas szintre teszem ST_CP - t így beolvassa DS értékét
_delay_us(25); // Várok, hát ha túl gyors a proci
bc (PORTC,1); // Visszaállítom ST_CP - t alacsonyba
}