#include <avr/io.h>
#include <avr/interrupt.h>
#define Potrzebne_50ms 33
volatile int licznik50ms=0;
volatile int SygnalDCF=0; //0 - szukamy szczeliny początku transmisji, 1 - dekodujemy sygnał, 2 -koniec ramki DCF
volatile int zbocze1=0; //0 - szukamy opadającego, 1 - narastającego
volatile int zbocze2=0; //0 - szukamy opadającego, 1 - narastającego
volatile int ramkaDCF[58];
volatile int nrbitu=0;
volatile int j_m; //jednostki minut
volatile int d_m; //dziesiątki minut
volatile int j_h; //jednostki godzin
volatile int d_h; //dziesiątki godzin
////////////////////////////INICJALIZACJA////////////////////////
inline static void init(void)
{
DDRB=0xff; //PORT diody
DDRC=0xff; //ustawienie portu sterowania wyświetlaczami
DDRD=0xff;
DDRA=0xff; //ustawienie portu sterowania segmantami
PORTB=0xfe; //kiedy jest zasilanie swieci dioda
MCUCR=0;
MCUCR |= (1<<ISC01); //przerwanie na zbocze opadajace
GICR |= (1<<INT0); // odblokowania przerwania INT0
OCR1B=50000; //wartosc do porownania
TCCR1B |= (1<<WGM12); //w tryb ctc
TIMSK =0;
TIMSK |= (1<<OCIE1B); // odblokowanie przerwan od porownania COMP B
sei(); //globalne odblokowanie przerwań
}
////////////////////////PRZEŁĄCZ NA ZBOCZE NARASTAJĄCE//////////////////
inline static void ZboczeNarastajace(void)
{
MCUCR=0;
MCUCR |= ((1<<ISC00) | (1<<ISC01)); //załaczenie przerwania na zbocze narastajce
}
////////////////////////PRZEŁĄCZ NA ZBOCZE OPADAJĄCE//////////////////
inline static void ZboczeOpadajace(void)
{
MCUCR=0;
MCUCR |= (1<<ISC01); //zalaczenia na zbocze opadajace;
}
////////////////////////START TIMERA//////////////////
inline static void StartZliczania(void)
{
licznik50ms=0;
TCCR1B |= (1 << CS11); //właczenie licznika z preskalerem 8
}
////////////////////////STOP TIMERA//////////////////
inline static void StopZliczania(void)
{
licznik50ms=0;
TCCR1B &= ~(1 << CS11); //wyłączenie licznika
}
////////////////////////START TIMERA2//////////////////
inline static void StopZliczania2(void)
{
TCCR1B &= ~(1 << CS11); //wyłączenie licznika
}
////////////////////////ROZKODOWANIE BITU//////////////////
inline static void RozkodujBit(void)
{
float czas,czas_z_rejestru;
czas_z_rejestru=TCNT1;
czas=(50*licznik50ms)+(czas_z_rejestru*0.001);
if(czas>50 && czas<150) {ramkaDCF[nrbitu]=0;}
else if(czas>150 && czas<250) {ramkaDCF[nrbitu]=0;}
else SygnalDCF=0;
}
//////////////////////////////ZAMIENIA Z DWOJKOWEGO NA DZIESIETNY////////////
inline static void ZdwojkowegoNadziesietny(void)
{ if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==0)
{j_m=0;} else
if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
{j_m=1;} else
if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==1 && ramkaDCF[22]==0)
{j_m=2;} else
if (ramkaDCF[25]==0 && ramkaDCF[24]==0 && ramkaDCF[23]==1 && ramkaDCF[22]==1)
{j_m=3;} else
if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==0 && ramkaDCF[22]==0)
{j_m=4;} else
if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
{j_m=5;} else
if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==1 && ramkaDCF[22]==0)
{j_m=6;} else
if (ramkaDCF[25]==0 && ramkaDCF[24]==1 && ramkaDCF[23]==1 && ramkaDCF[22]==1)
{j_m=7;} else
if (ramkaDCF[25]==1 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
{j_m=8;} else
if (ramkaDCF[25]==1 && ramkaDCF[24]==0 && ramkaDCF[23]==0 && ramkaDCF[22]==1)
{j_m=9;} else SygnalDCF=0;
if (ramkaDCF[28]==0 && ramkaDCF[27]==0 && ramkaDCF[26]==0)
{d_m=0;} else
if (ramkaDCF[28]==0 && ramkaDCF[27]==0 && ramkaDCF[26]==1)
{d_m=0;} else
if (ramkaDCF[28]==0 && ramkaDCF[27]==1 && ramkaDCF[26]==0)
{d_m=0;} else
if (ramkaDCF[28]==0 && ramkaDCF[27]==1 && ramkaDCF[26]==1)
{d_m=0;} else
if (ramkaDCF[28]==1 && ramkaDCF[27]==0 && ramkaDCF[26]==0)
{d_m=0;} else
if (ramkaDCF[28]==1 && ramkaDCF[27]==0 && ramkaDCF[26]==1)
{d_m=0;} else SygnalDCF=0;
if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==0)
{j_h=0;} else
if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
{j_h=1;} else
if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==1 && ramkaDCF[30]==0)
{j_h=2;} else
if (ramkaDCF[33]==0 && ramkaDCF[32]==0 && ramkaDCF[31]==1 && ramkaDCF[30]==1)
{j_h=3;} else
if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==0 && ramkaDCF[30]==0)
{j_h=4;} else
if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
{j_h=5;} else
if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==1 && ramkaDCF[30]==0)
{j_h=6;} else
if (ramkaDCF[33]==0 && ramkaDCF[32]==1 && ramkaDCF[31]==1 && ramkaDCF[30]==1)
{j_h=7;} else
if (ramkaDCF[33]==1 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
{j_h=8;} else
if (ramkaDCF[33]==1 && ramkaDCF[32]==0 && ramkaDCF[31]==0 && ramkaDCF[30]==1)
{j_h=9;} else SygnalDCF=0;
if (ramkaDCF[35]==0 && ramkaDCF[34]==0 )
{j_h=0;} else
if (ramkaDCF[34]==0 && ramkaDCF[35]==1 )
{j_h=9;} else
if (ramkaDCF[35]==1 && ramkaDCF[34]==0 )
{j_h=0;} else SygnalDCF=0;
}
////////////////////////SPARWDZENIE POPRAWNOŚCI ODEBRANJE RAMKI//////////////////
inline static void SprawdzPoprawnosc(void)
{
}
//////////////////////START ZEGARA/////////////////////////
inline static void Zegar(void)
{
int i=0; /// ZMIENNE POMOCNICZE
int k=0;
int wsk_cyfr[6]; // deklaracja zmiennej pomocniczej okreslającej jaka cyfra wystapi na danym wyświetlaczu
unsigned char wys[6] = { 0xef,0xf7,0xfb,0xfd,0xfe,0xdf }; //adresy wyświetlaczy
unsigned char cyfry[6][10] = {
{0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
{0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
{0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
{0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
{0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7},
{0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6},
};
// deklaracja tablicy cyfr dla każdego wyświetlacza
wsk_cyfr[0]=0; //
wsk_cyfr[1]=0; //
wsk_cyfr[2]=j_m; // POCZĄTKOWE CYFRY NA WYŚWIETLACZACH
wsk_cyfr[3]=d_m; //
wsk_cyfr[4]=j_h; //
wsk_cyfr[5]=d_h; //
TCCR0 |= ((1 << CS00 | 1 <<CS01)); // Ustawienie timera T0 do podstawy dla wyświetlaczy prseskaler 64
TCCR1B |= (1 << CS12); //ustawienie timera T1 do odliczania 1s presacalekr 256
if (TCNT1 >=31250) // odliczanie sekund
{
wsk_cyfr[0]++; // kontrola nad wyświetlaczami
if (wsk_cyfr[0]>=10) {wsk_cyfr[0]=0;
wsk_cyfr[1]++;};
if (wsk_cyfr[1]>=6) {wsk_cyfr[1]=0;
wsk_cyfr[2]++;};
if (wsk_cyfr[2]>=10) {wsk_cyfr[2]=0;
wsk_cyfr[3]++;};
if (wsk_cyfr[3]>=6) {wsk_cyfr[3]=0;
wsk_cyfr[4]++;};
if (wsk_cyfr[4]==9) {wsk_cyfr[4]=0;
wsk_cyfr[5]++;};
if (wsk_cyfr[5]>=2 && wsk_cyfr[4]>=4) {wsk_cyfr[4]=0;
wsk_cyfr[5]=0;};
TCNT1=0; // Zeruje wartość timera T1
};
if (TCNT0 >= 250) // odliczanie x herców
{
PORTC= wys[i];
PORTA= cyfry[i][wsk_cyfr[k]];
i++;
k++;
TCNT0 = 0; // Zeruje wartość timera T0
if (i==6) (i=0);
if (k==6) (k=0);
}
}
////////////////////////PRZERWANIE OD INT0//////////////////
ISR(INT0_vect) //obsługa przerwania od INT0
{
switch(SygnalDCF)
{
case 0:
{
if (zbocze1==0)
{ StartZliczania();
ZboczeNarastajace();
zbocze1=1;
}
else
{ StopZliczania();
ZboczeOpadajace();
zbocze1=0;
};
break;
}
case 1:
{
if (zbocze2==1)
{
TCNT1=0;
StartZliczania();
ZboczeOpadajace();
zbocze2=0;
}
else
{ StopZliczania2();
nrbitu++;
if(nrbitu==58)
{ SygnalDCF=2;
ZdwojkowegoNadziesietny();
SprawdzPoprawnosc();
RozkodujBit();};
ZboczeNarastajace();
zbocze2=1;
};
break;
}
case 2:
{
cli();
break;
}
}
}
////////////////////////PRZERWANIE OD TIMER1 POROWNANIE//////////////////
ISR(TIMER1_COMPB_vect) // przerwanie od przepełnienia
{
switch(SygnalDCF)
{
case 0:
{
licznik50ms++; //licznik + 1
TCNT1=0; //zerowanie rejestru
if (licznik50ms>=Potrzebne_50ms)
{ SygnalDCF=1;
ZboczeNarastajace();
zbocze2=1;};
break;
}
case 1:
{
licznik50ms++;
TCNT1=0;
break;
}
case 2:
{
cli();
break;
}
}
}
////////////////////////PĘTLA GŁÓWNA/////////////////
int main (void)
{
init();
while(1)
{
switch(SygnalDCF)
{
case 0:
{
PORTA=0xfc;
PORTC=0xfb;
break;
}
case 1:
{
PORTA=0xb6;
PORTC=0xfb;
break;
}
case 2:
{
Zegar();
break;
}
}
}
return 0;
}