Mam pytanie, bo juz szukam i szukam, ale jakos porzadnej odpowiedz nie moge znalesc.. Da sie zrobic na zewnetrzym kwarcu 8MHz porzadny zegar czasu rzeczywistego?? Narazie napisalem sobie taki programi z obsluga przepelnienia (preskaler 32):
SIGNAL (SIG_OVERFLOW2){ TCNT2=6; if(licznik++==1000){ //1000 przepelnien odpowiada 1 s licznik=0; sekundy++; }
}
No ale po 1 h to juz ma jakies 3 sekundy spoznienia... Cos zle napisalem, czy po prostu nie da sie na takim kwarcu tego zrobic dokladnie?? Czytalem ze powodem tego mzoe byc ustawianie wartosci TCNT2 w przerwaniu.. Ale nadal nie wiem czy to wogole jest mozliwe???? I jeszcze jedno pytanie.. Bo tez na to nie znalazlem odpowiedzi :) EEPROM to pamiec nieulotna, tzn ze nawet jak odlacze zasilanie to dane zostaja w niej.. Tak? I nie ma zadnych problemow zeby z programu cos do niej zapisac??
Didn't find your answer? Ask the community — no account required.
B
Bogdan Gutknecht
Da siê. Porz±dno¶æ zegara zale¿y tylko od kwarcu (i prawid³owego programu).
Dobrze czyta³e¶ - to jest ta przyczyna. Wybierz sobie jaki¶ tryb z automatycznym prze³adowywaniem. Twoje prze³adowanie nie jest pierwsz± instrukcj± w przerwaniu!!!! Jest tam przed ni± pewna (jaka? - nale¿a³oby to sprawdziæ w listingu) ilo¶æ instrukcji.
Je¶li chcesz bardzo dok³adnie to mo¿esz jeszcze dorzuciæ co jaki¶ czas korekcjê.
Tak mo¿na zapisaæ, ale ten zapis trwa parê milisekund i nale¿y o tym pamiêtaæ.
Z
Zibias
U¿ytkownik "Pan Samochodzik" snipped-for-privacy@tlen.pl napisa³ w wiadomo¶ci news: snipped-for-privacy@g10g2000cwb.googlegroups.com...
Jest jeszcze taka mo¿liwo¶æ ¿e kwarc i owszem jest, ale fuse-bit ustawione s± tak ¿e chodzi wewnêtrzny generator 8MHz. On nie jest specjalnie dok³adny i tu mo¿e le¿eæ problem.
P
Pan Samochodzik
8Mhz zewnetrze jest ustawione, to wewnetrzne to "prawie nie dziala" :)
Co to znaczy automatyczne przeladowywanie?? Mozesz troche prosciej??
P
Piotr Gałka
U¿ytkownik "Pan Samochodzik" snipped-for-privacy@tlen.pl napisa³ w wiadomo¶ci news: snipped-for-privacy@g10g2000cwb.googlegroups.com...
Wybacz, ale nie dam rady tego , jedyne co to moge na oko.. Tak sadzilem ze cos kolo 3-4 s, wiec napisz jak zmienic, zeby bylo ok...
M
Marcin Stanisz
Dnia 18 May 2006 07:09:31 -0700, Pan Samochodzik napisał(a):
To znaczy, że będziesz mógł pominąć tę instrukcję: TCNT2=6; Procesor zrobi to za ciebie automatycznie. Reszta w manualu, bo nawet typu procesora nie podałeś.
Pozdrawiam Marcin Stanisz
P
Piotrek Sz.
Pan Samochodzik snipped-for-privacy@tlen.pl napisał(a):
Uruchom timer w trybie CTC , jeśli takowy tryb posiada ;)
Piotrek
P
Piotr Galka
Uzytkownik "Pan Samochodzik" snipped-for-privacy@tlen.pl napisal w wiadomosci news: snipped-for-privacy@y43g2000cwc.googlegroups.com...
Ok, przerobilem na tryb CTC, teraz funkcja wlaczajaca i przerwanie wygladaja tak:
void timer2_init (void) { //wlaczamy timer2
TCCR2 |= (1 << CS21); //preskaler 32 dla timer2 TCCR2 |= (1 << CS20); TCCR2 |= (1 << WGM21); //Clear Timer on Compare (z OCR2) OCR2 = 250; //zerowanie kiedy osiagnie 250 a nie 255
licznik=0; sekundy=0; minuty=0; godziny=0;
TIMSK |= (1 << OCIE2); //wlaczamy przerwanie dla CTC TIMSK |= (1 << TOIE2); //wlaczamy przerwanie dla timera2
}
I przerwanie:
SIGNAL (SIG_OUTPUT_COMPARE2){
if(licznik++==1000){ //1000 przepelnien odpowiada 1 s licznik=0; sekundy++; zmien++; }
}
Biore sie za testowanie.. Ale jezeli widzicie jakis blad to krzyczcie :)
P
Pan Samochodzik
No dobra, to powiedzmy ze to nawet bedzie dzialac, ale zapomnialem dodac jednej rzeczy... Bo tak na prawde to chce wlozyc ten zegarek to urzadzenia, ktore odbiera podczerwien itp.. No i uzywam tam przerwan z INT0 i INT1 w momencie odbierania sygnalu podczerwieni ( niezbyt czesto, powiedzmy 20 razy na dobe). Czy przy takich warunkach jest jest taki zegar w stanie normalnie funkcjonowac, czy jednak powinienem dolozyc zewnetrzny kwarc zegarkowy???? Program na tej samej zasadzieby byl, prawda?? A tak wogole to chyba uklad bedzie na ATmega 8, albo 16 jezeli mi zabraknie pinow...
P
Pan Samochodzik
No i nie dziala.. po godzinie to juz jakies 10 sekund roznicy jest.... :/
Z
Zbych
Piotr Galka przemówił ludzkim głosem:
Taka różnica _może_ być spowodowana przez tą linię:
zmienna licznik jest inkrementowana po zakończeniu porównania, a powinna być przed.
P
Piotrek Sz.
Pan Samochodzik snipped-for-privacy@tlen.pl napisał(a):
Bo nie chce Ci sie pomyśleć(policzyc) :) void timer2_init (void) { //wlaczamy timer2
TCCR2 |= (1 << CS21); //preskaler 32 dla timer2 TCCR2 |= (1 << CS20); TCCR2 |= (1 << WGM21); //Clear Timer on Compare (z OCR2) OCR2 = 249; //zerowanie też "trwa" ;) asm("sei"); licznik=0; sekundy=0; minuty=0; godziny=0;
TIMSK |= (1 << OCIE2); //wlaczamy przerwanie dla CTC TIMSK |= (1 << TOIE2); //wlaczamy przerwanie dla timera2
}
SIGNAL (SIG_OUTPUT_COMPARE2){
if(++licznik==1000){ //na to zwrócił uwagę któryś z kolegów licznik=0; sekundy++; zmien++; }
}
Piotrek
P
Pan Samochodzik
No wiem wiem, juz to zmienilem i sprawdzam.. Jutro sie okaze :) A jak z tymi kwestiami juz nie dotyczacymi samego zegara?? Moze to tak dzialac rownolegle do innych przerwan??
P
Piotr Gałka
U¿ytkownik "Zbych" snipped-for-privacy@onet.pl napisa³ w wiadomo¶ci news:e4kv07$3g1$ snipped-for-privacy@nemesis.news.tpi.pl...
Ju¿ pisz±c ¿e opó¼nienie powinno byæ 3,6s/h (czyli, ¿e wynika z programu a nie z kwarca) kombinowa³em aby sam to znalaz³. P.G.
P
Pan Samochodzik
jak juz napisalem:
No wiem wiem, juz to zmienilem i sprawdzam.. Jutro sie okaze :) A jak z tymi kwestiami juz nie dotyczacymi samego zegara?? Moze to tak dzialac rownolegle do innych przerwan??
Odpowie mi ktos ??
M
Michal Lankosz
Jesli juz twój zegar bedzie dzialal tak jak poradzili poprzednicy (tryb CTC) to spokojnie mozna uzywac i innych przerwan. W przypadku, gdy obslugujesz np. wspomniany odbiornik podczerwieni i w tym czasie przyjdzie przerwanie zegara, to trudno - spóznisz sie z jego obsluga, ale za to nastepnym razem zapewne wejdziesz do niej szybciej. Srednia wartosc czestotliwosci obslugi przerwan zegarowych bedzie stala (taka, jaka sobie zadales), tylko pojawi sie jitter - niewielkie odstepstwa od chwili, w której miala by sie ona zaczac. Jak duze? - zalezy od szybkosci procedur pozostalych przerwan. Oczywiscie obsluga kazdego przerwania musi byc krótsza od czestotliwosci ich generowania. Zatem odbiór podczerwieni nie moze blokowac przerwan (np. umieszczajac w nim petle opózniajace) bo zgubisz sygnaly zglaszajace przerwania od timera!
Pozdrawiam, Michal Lankosz
M
MariuszC
Napisz kod tak, aby wartość wpisywana do licznika była jak najmniejsza gdy licznik liczy w górę, albo jak największa gdy licznik liczy w dół. Zalecałbym też napisanie obsługi przerwania w assemblerze z modyfikatorami funkcji, które spowodują, że kompilator nie utworzy żadnej instrukcji procesora, nawet "reti"; poniżej przykładowy kod który ma wykonać 2 instrukcje TCNT0 = TIMERINITIALVALUE; ++g_byTicks;
Powyżej wykorzystałem r17 do przechowania stanu flag __SREG__, a r16 służy mi do wykonania operacji: wpisania wartości do timera oraz inkrementacji g_byTicks.
A poniżej kod funkcji w C oraz wygenerowany z niej kod assemblerowy
Zobacz że procesor wkłada dodatkową pracę w odkładanie/zdejmowanie rejestrów __zero_reg__ i __tmp_reg__ na stos, co mogłem spokojnie pominąć w moim kodzie assemblerowym.
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.