Witam ponownie, znalazłem wcześniej na elektrodzie program zegarka na LCD 2x16, który niestety nie działał prawidłowo (migały niezrozumiałe znaki na lcd). W celach edukacyjnych postanowiłem przerobić procedury obsługi wyświetlacza, co dało efekt końcowy jaki teraz mam czyli działający program zegara na LCD, ale jest jeden problem. Zegar odmierza 1 sek w ciągu rzeczywistych 8 sek. Poniżej instrukcje odpowiadające za przerwania. Czy może mi wytłumaczyć w jaki sposób jest tu odmierzany czas?
Z tego co zrozumiałem z poniższego zapisu liczenie odbywa się przy użyciu Timera0 ustawionego na CS01 (0x02) clk8(w komentarzach wpisane jest że 4?), co daje dla F_CPU 8000000 / 8 - 1000000 impulsów na 1 sek., liczenie zaczyna się od 9 do 255 (czyli do 247).
Według komentarzy w poniższym kodzie zegar jest podzielony przez 4? W ciągu sekundy mają się wykonać 249 przepełnienia tak?
Niestety ale nie ogarniam tego , czy może mi ktoś napisać jak to jest liczone?
Z tego co zrozumiałem z poniższego zapisu liczenie odbywa się przy użyciu Timera0 ustawionego na CS01 (0x02) clk8(w komentarzach wpisane jest że 4?), co daje dla F_CPU 8000000 / 8 - 1000000 impulsów na 1 sek., liczenie zaczyna się od 9 do 255 (czyli do 247).
Według komentarzy w poniższym kodzie zegar jest podzielony przez 4? W ciągu sekundy mają się wykonać 249 przepełnienia tak?
Niestety ale nie ogarniam tego , czy może mi ktoś napisać jak to jest liczone?
SIGNAL (SIG_OVERFLOW0) //funkcja obsługująca przerwanie od timera0
{
TCNT0=9; //wpisanie do licznika timera0 wartosci poczatkowej
stala0++; //w clu sktócenia cyklu zliczania(powinno byc 10 dla rezonatora 8MHz
if(stala0>249) //ale ze względu na to że rezonator ma 8.000400MHz wpisane jest 9 w celach kompensacji)
{ //timer0 zlicza impulsy zegara podzielone przez 4 czyli w ciągu sekundy było by 2000000 impulsów(zakładając że do TCMC0 wpisujemy za każdym razem 5) (pojemność timera0 i tak wynosi tylko 255)
stala0=0; //dzięki preskalerowi = 2 tych impulsów będzie 1000000 czyli 16 * 250 * 250.
stala1++;
if(stala1>15)
{
stala1=0;
sekundy++;
}
}
...
}
TIFR=1<<TOV0;
}
SIGNAL (SIG_INTERRUPT1) //obsługa przerwania z wejścia int 1
{
b=0; //ustaw stałą b na zero
GIMSK=0<<INT1; //zablokuj przerwanie z wejścia INT1
}
int main(void)
{
....
TIMSK=1<<TOIE0; //w rejestrze maskowania przerwań(TIMSK) wpisz 1 na miejsce bitu TOIE0 (zezwolenie na przerwanie od układu timera0 spowodowane przepełnieniem)
TCNT0=9; //wpisz wartośc poszątkową do licznika timera0
TCCR0=0x02; //preskaler ustaw na 2 (CLK/8)
GIMSK=1<<INT1; //włacz przerwanie z INT1
MCUCR=0x02; //przerwanie z INT1 wyzwalane zboczem opadającym
...