Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Atmega8][Bascom] Wartość wpisywana do timera

Wojtek001 05 Lip 2012 18:32 5471 47
  • #1 05 Lip 2012 18:32
    Wojtek001
    Poziom 15  

    Mam problem z którym próbuje uporać się już od dłuższego czasu. Nie wiem jaką wartość powinienem wpisać do timera dwu bajtowego aby uzyskać przerwanie co sekundę. Nie pytałbym się tu o takie rzeczy ale nawet w książce "Mikrokontrolery dla początkujących" autor oblicza wartość timera pisząc sprzeczne równanie!
    Od razu mówię że programuje w BASCOMIE jeśli to ma jakieś znaczenie.

    Dane:
    Preskaler = 1024
    Częstotliwość taktowania = 16 000 000 Hz

    A więc jeśli mam częstotliwość taktowania 16Mhz, Preskaler równy 1024 i używam timera 2-bajtowego do odmierzania sekundy to muszę wpisywać do niego wartość równą 49910 czy 49911?
    Policzyłem obie jak duże znaczenie ma ta różnica wartości. Wynosi : 1s / ( 16 000 000 hz/ 1024) = ok. 0,000064 s <-- na każdą sekundę czyli po 4 h nagromadzi się różnica równa 0,000064 s * 3600 * 4 = 0,9216.

    I rzeczywiście zegar śpieszy się po 4h o ok. 1 s względem zegara online ! Czy to wynik blednie wpisanej wartości (ja wpisałem 49 911) czy może zwykła niedokładność kwarcu?


    Maksymalna wartość tego timera równa się 65535 ale przejście do podprogramu przerwania następuje dopiero gdy timer się "przekręci" (? <- tego nie jestem pewny proszę o potwierdzenie) czyli jakby cykl później
    więc 65535 + 1 = 65536 <-- i właśnie tu nie jestem pewny czy powinno być 65535 czy 65536 ?

    Sekunda zajmuje 1 000 000 uS czyli 16 000 000 cyki zegara. Preskaler jest ustawiony na 1024 czyli 16 000 000 / 1024 = 15 625

    65536 - 15625 = 49911
    Dobrze? Czy powinno być 49910?

    0 29
  • #2 05 Lip 2012 18:55
    LordBlick
    VIP Zasłużony dla elektroda

    Preprocesor twoim przyjacielem:

    Kod: C
    Zaloguj się, aby zobaczyć kod
    W zalezności o tego, czy używasz trybu CTC(Licznik sam się zeruje po dojściu do wartości z OCR1A, więc wpisujemy na początku do tego rejestru programu wartość z przedostatniej linijki), czy Overflow(w obsłudze przerwania co przerwanie trzeba załadować nową wartość), stosujesz zamienne wartości z dwóch ostatnich linijek. Serio nie było takiego czegoś w książce ?
    P.S. Używaj w tytule tematu znaczników w rodzaju[Atmega2012][C], łatwiej udzielić odpowiedzi, używając odpowiedniej noty katalogowej :P

    0
  • #3 05 Lip 2012 19:02
    Wojtek001
    Poziom 15  

    A jak jest w BASCOMIE / uC domyślnie ? Tzn. ja nie ustawiałem żadnego trybu pracy timera.

    0
  • #4 05 Lip 2012 19:05
    LordBlick
    VIP Zasłużony dla elektroda

    To zajrzyj do noty katalogowej odpowiedniego procesora odnośnie trybów pracy licznika. Podany wyżej sposób obliczania jest dość przejrzysty, można sobie to policzyć nawet na piechotę na kalkulatorze.

    Wojtek001 napisał:
    Tzn. ja nie ustawiałem żadnego trybu pracy timera.
    A powinieneś, w końcu sprzęt trzeba najpierw przyszykować do pracy... ;)

    0
  • #5 05 Lip 2012 19:09
    stanleysts
    Poziom 27  

    CTC trzeba wybrać natomiast domyślnym trybem jest ten z przepełnieniem.

    0
  • #6 05 Lip 2012 19:14
    Wojtek001
    Poziom 15  

    Jestem niemal pewny, że nie używam trybu CTC (sam to powinieneś zauważyć bo wynika to z moich przytoczonych obliczeń).

    Program działa tak że na początku każdego przerwania ładowana jest nowa wartość do licznika (ta co miałem wątpliwości 49910 albo 49911). Czyli trzeba na pewno 49 910? Bo niestety muszę zegarek rozbierać :cry: .

    0
  • #7 05 Lip 2012 19:24
    stanleysts
    Poziom 27  

    No ja jestem za to pewny ze nie używasz CTC bo wtedy by to inaczej działało. Wg mnie 49911. 65536-15625

    0
  • #8 05 Lip 2012 19:26
    LordBlick
    VIP Zasłużony dla elektroda

    Wojtek001 napisał:
    Bo niestety muszę zegarek rozbierać
    No niestety w tym trybie nie uzyskasz stabilnej sekundy, tym bardziej, ze Bascom w obsłudze przerwania może robić zbędne bzdury i jeszcze nie raz ten zegarek będziesz rozbierał. Do konstrukcji czasomierza najbardziej się nadaje asynchroniczny licznik Timer2 w trybie CTC, taktowany specjalnym rezonatorem kwarcowym 32768Hz do zegarków, lub zewnętrzny układ RTC.

    0
  • #9 05 Lip 2012 20:53
    Wojtek001
    Poziom 15  

    stanleysts napisał:
    Wg mnie 49911. 65536-15625
    A wiesz o tym że przecież wartości 65536 timer nigdy nie osiągnie ? No chyba że uwzględniasz tu to ,że skok do procedury przerwania odbywa się gdy Timer osiągnie wartość 0 następnego cyklu.

    Kiedy miąłem wpisane 49911 po 3 godzinach zegar przyśpieszył o sekundę - z obliczeń mi wyszło żeby to skorygować to musiał bym wpisywać 49910 i tak też ustawiłem - zobaczymy co z tego będzie.

    A może to jest tak że skok do procedury przerwania odbywa się gdy Timer osiąga maksymalną wartość czyli 65535 (przepełnia się)? <- wiem że to pewnie wszystko w notach jest ale bariera językowa nie pozwala mi skorzystać.

    PS: LordBlick czyli w końcu twierdzisz (nie używam CTC),że powinna być wartość 49910?

    0
  • #10 05 Lip 2012 21:02
    stanleysts
    Poziom 27  

    Wiem o tym, przerwanie jest generowane, gdy przepełnimy licznik czyli po 65536.

    0
  • Pomocny post
    #11 05 Lip 2012 21:43
    30402
    Użytkownik usunął konto  
  • #12 05 Lip 2012 21:52
    mirekk36
    Poziom 42  

    Wojtek001 napisał:
    stanleysts napisał:
    Wg mnie 49911. 65536-15625
    A wiesz o tym że przecież wartości 65536 timer nigdy nie osiągnie ?


    No kurczę jak to nie osiągnie ? ;) to sugerujesz, że on liczy od 1 ? czy od 0 ? ;)

    Przecież za chwile sam się dobrze domyślasz.
    Wojtek001 napisał:
    No chyba że uwzględniasz tu to ,że skok do procedury przerwania odbywa się gdy Timer osiągnie wartość 0 następnego cyklu.


    Eeeeh to jest niestety pokłosie myślenia z Bascoma. Wyobraź sobie, że timer 16-bitowy to taka tablica, a wartości tych elementów zaczynają się od 0 a kończą na wartości 65535 - to ile jest tych elemenów ?

    Prostsze wyobraź sobie że masz timer 2 bitowy - tak 2 bitowy a nie bajtowy ;) czyli maksymalnie przez ile można nim podzielić ? przez 3 czy przez 4 ? jak myślisz ?

    załóżmy, że taktowanie procesora to 8Hz ;) a ! taki wolny procesor, załóżmy że masz dostępny jeden preskaler = 4 i go ustawiasz. Wychodzi więc na to żeby uzyskać 1 sekundę to trzeba podzielić jeszcze timerem 2-bitowym przez 2 prawda ?

    no to co chcesz zrobić tak:

    4 - 2 = 2 i w przerwaniu będziesz ładował wartość = 2 do timera (odpowiednik twojego 49911)

    czy tak:

    4 - 2 - 1 = 1 i w przerwaniu będziesz ładował wartość = 1 (odpowiednik twojego 49110)

    toż chyba teraz widzisz jak na dłoni że jak zrobisz ten drugi sposób to:

    timer będzie miał wartość = 1,
    zliczy raz - i będzie miał wartość = 2
    zliczy dwa - i będzie miał wartość = 3 (ale jeszcze się przecież nie przepełni!)
    zliczy trzy - i będzie miał =0 (zero) więc się przepełni i wykona przerwanie, w którym mu zapiszesz znowu wartość = 1

    więc przez ile będzie podział ??????? no przez TRZY ;) a chcieliśmy przez 2 dla naszego procka taktowanego 8Hz i preskalera = 4 ;)

    teraz w końcu jaśniej ?

    0
  • #13 05 Lip 2012 22:21
    LordBlick
    VIP Zasłużony dla elektroda

    Czysto informacyjnie - licznik domyślnie liczy w górę, stad odejmowanie wartości CTC(właściwa wartość do odliczenia przez licznik) od 65535.

    Wojtek001 napisał:
    PS: LordBlick czyli w końcu twierdzisz (nie używam CTC),że powinna być wartość 49910?
    Nie twierdzę nic w tej kwestii, ponieważ obsługa tego przerwania w Bascom nie jest dokładna i nie nadaje się do odliczania sekund w zegarze. W przypadku CTC jeszcze by uszło, bo licznik sam się przeładowuje, ale dokładność też nie będzie idealna, trzeba zrobić procedurę korygująca co ileś godzin.
    Kodem w Bascom niestety nie podratuję, bo się w meandry tego języka nigdy nie zagłębiałem. Poznawałem AVR-y od wydrukowania w całości noty katalogowej od AT90S8515 i pilnego tworzenia programów w asemblerze w/g zamieszczonej tamże listy rozkazów . W tamtych czasach Bascom nie był popularny.

    0
  • #14 06 Lip 2012 12:35
    Wojtek001
    Poziom 15  

    A więc każdy i wszędzie mówi coś innego (to forum nie jest jedynym źródłem w którym szukałem informacji na ten temat).

    LordBlick Nie wiem czemu piszesz żeby odejmować od 65535 skoro przerwanie nastąpi gdy licznik osiągnie 0 kolejnego cyklu czyli jakby wartość 65536?

    Zresztą ustawiłem w końcu 49911 i zegar mi się spieszy o 4 sekundy / 12 godzin. Z obliczeń wynika że można było by to idealnie skorygować poprzez zamianę 49911 na 49910. Jednak spieszenie zegara może wynikać z wysokiej temperatury a co za tym idzie niedokładności kwarca .W zimę sytuacja się może odwrócić.

    0
  • #15 06 Lip 2012 13:47
    LordBlick
    VIP Zasłużony dla elektroda

    Wojtek001 napisał:
    Nie wiem czemu piszesz żeby odejmować od 65535
    Zastanów się chwilę jeszcze nad tym, co trzeba odejmować od 65535, jak jak to obliczam (nie korzystam z żadnych podpowiedzi, tylko używam własnej głowy) - przejrzyj moje wcześniejsze wpisy i powinno być to już jasne.

    0
  • #16 06 Lip 2012 17:45
    Wojtek001
    Poziom 15  

    Po raz kolejny rozbierałem zegar żeby zamienić tą wartość. Tym razem wpisałem 49910. Minęły 3h i zegar wciąż działa idealnie (a w przypadku 49911 już po 3h pojawiał się błąd jednej sekundy). Oczywiście nową wartość ładuje do timera natychmiast w podprogramie przerwania.

    Teraz już jestem pewny że trzeba użyć wartości 49910.
    Nie wiem jednak czemu z moich obliczeń wynika że należy użyć 49911 - zresztą mirekk właśnie stara mi się udowodnić (na swoim blogu też) że taka wartość powinna być.

    Dodano po 4 [minuty]:

    stanleysts napisał:
    Wiem o tym, przerwanie jest generowane, gdy przepełnimy licznik czyli po 65536.

    Jak to mam rozumieć. Procek ustawia bit flagi timera natychmiast gdy pojawi się tam maksymalna wartość czy dopiero gdy pojawia się 0 następnego cyklu (gdy timer się przekręci)?
    Mówisz o wartości 65536 która do dwóch bajtów się po prostu nie zmieści więc
    masz na myśli ,że po zerze następnego cyklu?

    0
  • #17 06 Lip 2012 18:18
    mirekk36
    Poziom 42  

    Podałem ci taki prosty przykład - na małych liczbach - kurczę aż się dziwię że to stanowi jakiś problem i że trzeba to rozważać prawie jakby to zależało od interpretacji tego co poeta miał na myśli.

    Proszę przeczytaj to wyżej - gdzie założyłem że procek jest taktowany 8 Hz ;) ... no toż tam widać jak na dłoni o co chodzi - i odnieś się do tego.

    8 Hz, preskaler = 4 i timer 2-bitowy .... czyli timer, który może dzielić przez 4 jeśli będzie dochodziło do przepełnienia. Ale przecież fizycznie liczby w nim możliwe to tylko 0,1,2,3 - tymczasem do obliczeń bierzesz 4 - bo masz 4 wartości

    tak samo z liczbą dwubajtową, bierzesz 65536 chociaż taka liczba nie jest możliwa do zapisania na dwóch bajtach ale za to mieści dokładnie tyle wartości od 0 do 65535

    0
  • #18 06 Lip 2012 18:30
    janbernat
    Poziom 38  

    Do tego że numer porządkowy zaczyna się od zera trzeba się przyzwyczaić.
    Element 1 2 3 ...
    Numer elementu 0 1 2 ...

    0
  • #19 06 Lip 2012 19:39
    Wojtek001
    Poziom 15  

    mirekk36 Rozumiem twoje rozumowanie jednk nie zgadza mi się to z praktyką. Z tego co piszesz wynika że trzeba by wpisywać wartość 49911. Kolega LordBlick, Saabotaz i jego kalkulator twierdzą jednak że trzeba wpisać tam 49910 <-- i tego nie rozumiem, próbuje więc sobie to tłumaczyć w jakiś (być może pokrętny i nie właściwy) sposób. Niemniej przy 49910 zegar jest dużo dokładniejszy (nie przyśpiesza już o sekundę na 4h) dlatego twierdzę że tam powinna być taka wartość. Może po prostu mam lekko szybszy kwarc.

    Dodano po 9 [minuty]:

    mirekk ja myślę że jest inne wytłumaczenie na tą wartość 65536. Po prostu oznaczamy w ten sposób że chodzi nam o 65536. tyknięcie czyli moment gdy w timerze jest już fizycznie 0 następnego cyklu.
    Ty mówisz że dlatego że tyle jest możliwych liczb w dwubajcie. Ale przecież gdy odejmiemy wartość CTC to to zero nam się jakby gubi bo timer liczy od wartości CTC a nie od zera...
    zresztą nieważne, oba wytłumaczenia w efekcie sprowadzają się do tego samego.

    Ja jednak dalej nie rozumiem czemu powinno być wpisane do timera 49910? nie zgadza się to np. z wytłumaczeniem mirka.

    0
  • #20 06 Lip 2012 23:55
    Dar.El
    Poziom 40  

    Różnica 200ppm w częstotliwości kwarcu jest możliwa do osiągnięcia, więc nie ma co gdybać. Gdy wpiszesz 65535, będziesz miał przepełnienie co 1 takt, dla 65534 co 2 takty. Resztę sam policz.

    0
  • #21 07 Lip 2012 00:32
    mirekk36
    Poziom 42  

    Dar.El napisał:
    Gdy wpiszesz 65535, będziesz miał przepełnienie co 1 takt, dla 65534 co 2 takty. Resztę sam policz.


    hyhyhy no rzeczywiście jeszcze prostsze wytłumaczenie, no prościej już się nie da chyba ;)

    chcesz odliczyć 1 impuls to: 65536 - 1 --> wpisujesz 65535
    chcesz odliczyć 2 impulsy to: 65536 - 2 --> wpisujesz 65534

    a jak chcesz odliczyć 15625 impulsów to: 65536 - 15625 = 49911 ;)

    A z trybem CTC wszystko ci się myli ponieważ, w tym trybie ustawiasz OCR na 15625 ale takiej wartości timer nigdy nie osiągnie ponieważ następuje od razu jego wyzerowanie. Czyli de'facto owszem zlicza 15625 impulsów ale od 0 do 15624 ;)

    0
  • #22 07 Lip 2012 11:04
    30402
    Użytkownik usunął konto  
  • #23 07 Lip 2012 12:08
    mirekk36
    Poziom 42  

    Saabotaz napisał:
    Jak by nie gdybać to lepszym rozwiązaniem jest podłączenie kwarcu zegarkowego + trymerek. Ewentualnie PCF (ten scalak zegarkowy) gdy chcesz długie i programoodporne utrzymanie aktualnego czasu.

    Lepiej jednak użyć tryb CTC. Bo jak pisałem, przed wejściem do przerwania Bascom odkłada ci rejestry na stos i wprowadza opóźnienie zanim załadujesz timer. W CTC timer ładuje się sam, masz więcej czasu na obsłużenie przerwania i nie jest krytyczne czasowo.

    Ostatecznie zrób wstawkę w ASM. Wklej tutaj swój kod z przerwania, może da się go przyśpieszyć.


    Ja też od początku staram się to autorowi wyjaśnić i dokładnie popieram każde zdanie powyżej. Absolutna racja i wskazanie dobrej drogi.

    0
  • #25 08 Lip 2012 21:24
    M. S.
    Poziom 34  

    Jak masz problem z obliczeniami to w Bascomie jest jeszcze instrukcja

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #26 19 Lip 2012 23:31
    Wojtek001
    Poziom 15  

    Saabotaz napisał:

    Ostatecznie zrób wstawkę w ASM. Wklej tutaj swój kod z przerwania, może da się go przyśpieszyć.


    Wiem że procek za czym skoczy do podprogramu przerwania robi jeszcze dużo rzeczy poza moimi plecami, ale w moim przypadku jest to pożądane - mój zegar przecież śpieszy . Tak więc robienie wstawek asembler-owych i próbowanie na siłę zbliżyć się do teoretycznej sekundy nic nie da, bo efekt będzie się pogłębiać - zegar będzie śpieszył jeszcze bardziej.

    Zastanawiałem się nawet żeby dodatkowo opóźnić wpisywanie wartości do timera np. wpisując instrukcje "waitus 11" natychmiast na początku podprogramu przerwania . Bo na razie zegar śpieszy mi się o 1s/ 24h i wynika z tego że należało by opóźnić go jeszcze o 11us na sekundę? Nie wiem czy opłaca mi się męczyć (tzn. czy np. w zimie kiedy będą nieco niższe temperatury mi się nie rozreguluje - ale przecież wewnątrz mieszkania temperatura mimo wszystko utrzymuje się na względnie stałym poziomie przez cały rok a kwarc aż tak wrażliwy na paro stopniowe zmiany temperatur nie jest) ?

    0
  • #27 20 Lip 2012 08:31
    emarcus
    Poziom 35  

    Wojtek001 napisał:
    Saabotaz napisał:

    Ostatecznie zrób wstawkę w ASM. Wklej tutaj swój kod z przerwania, może da się go przyśpieszyć.


    Wiem że procek za czym skoczy do podprogramu przerwania robi jeszcze dużo rzeczy poza moimi plecami, ale w moim przypadku jest to pożądane - mój zegar przecież śpieszy . Tak więc robienie wstawek asembler-owych i próbowanie na siłę zbliżyć się do teoretycznej sekundy nic nie da, bo efekt będzie się pogłębiać - zegar będzie śpieszył jeszcze bardziej.



    NIE!..
    Tu nie masz racji, bo błąd "zegarka" nie jest powodowany błędnym programowaniem lub środowiskiem lecz samym kwarcem.

    Wstawka assemblerowa, lub cały program tworzony w ASM lub "C" nic tu nie zmieni.

    Od momentu wystąpienia przerwania OVF1, processor ma bardzo dużo czasu na odłlożenie niektórych rejestrów na stos i załadować timer1 ustalona wartością. Obsługa stosu w jedna stronę 'kosztuje' 32 cykle zegarowe, kilka cykli na wpis do timera (tryb pracy "Normal") + pozostała obsługa stosu "w drugą strone" i ewentualne drobne operacje zerowania zmiennych, flagi (to co masz wpisane w obsłudze przerwania) zajmą powiedzmy dodatkowo 60 cykli zegarowych, które już i tak są po wpisie do timera, gdy tymczasem następny impuls do timera wystapi po upływie 1024 cykli zegarowych, taki masz prescaler. Więc gdzie masz problem?

    Popatrz na taką sytuację.
    Normalnej jakości kwarc jest produkowany w tolerancji +/- 20ppm. (lichsze - z odrzutu, kwalifikowane jako 'surplus' - dla niektórych kojarzy się to jako nadprodukcja, są sprzedawane tanio lub czasem nieuczciwie jako te normalne mają tolerancję rzędu +/- 50 ppm -'parts per million' ).
    Co oznacza ta tolerancja +/-20 ppm i jakie sa jej skutki?
    16 MHz kwarc przy tej tolerancji może 'produkować' falę o częstotliwoci pomiędzy 16 000 320Hz a 15 999 680Hz.
    Przeliczając te odchylenia na pracę timera (pomijając wahania częstotliwości powodowane zmianami temperatury) otrzymamy że w górnym skrajnym przypadku zegar będzie spieszył 1.727 sec/dobe, natomiast w dolnej odchyłce będzie opóźniony 1.728 sec/dobę.
    Jeżeli u ciebie występuje odchyłka tylko 1 sec/dobe to możesz spokojnie stwierdzić że kwarc jest w normie i jest nawet lepszy niż dopuszczalna granica.
    Jakiekolwiek sugerowane "poprawki" w programie w postaci waitus pogorszą działanie programu.
    Mimo że przyjmuje się że oscylator z kwarcem produkuje sciśle określoną częstotliwość, to możesz jednak próbować ją w małym stopniu korygować - zmieniając wartość capacitorów tam użytych; -być może to wystarczy.
    Na przykład: zamiast oba po 18 pF, daj jeden 18 a drugi 33 (27) lub inne kombinacje i obserwuj zmiany.
    Kwarce "zegarkowe" 32 kHz są dokładniejsze. Kombinacja takiego rezonatora z asynchr. timerem2 jako RTC a reszta na wewn. oscylatorze jest z pewnością lepszym rozwiązaniem. Patrz datasheet.

    P.s Nie chce tu kommentować wypowiedzi w tej dyskusji , ale niektóre "wyjaśnienia" pracy i konfiguracji timerow były 'nieco' nie ścisłe a nawet powiedziałbym błędne, albo wprowadzające w błąd czytelnika.

    e marcus

    0
  • #28 20 Lip 2012 09:58
    Wojtek001
    Poziom 15  

    emarcus napisał:

    Jakiekolwiek sugerowane "poprawki" w programie w postaci waitus pogorszą działanie programu.

    Czemu? Wiem że polecenie waitus zatrzymuje program całkowicie uniemożliwiając mu robienie też innych rzeczy ale przecież to tylko 11uS, potem procek by miał całe 999989uS czasu dla normalnej obsługi programu.

    A swoją drogą: może ktoś doświadczony powie o ile może zmienić się częstotliwość kwarcu w zimie (mówimy tu o temperaturze w mieszkaniu)? I co ważne: logicznie myśląc wraz ze spadkiem temperatury częstotliwość spada?

    0
  • #29 20 Lip 2012 11:48
    30402
    Użytkownik usunął konto  
  • #30 20 Lip 2012 12:12
    LordBlick
    VIP Zasłużony dla elektroda

    Saabotaz napisał:
    pod ten 16MHz podłącz trymer, częstościomierz i dostrój się tak jak trzeba.
    I dołóż stabilizację temperaturową z grzaniem i chłodzeniem.... ;)
    Albo dołóż kostkę ethernetową i pobieraj czas z serwera ntp.
    Albo przerób na DCF.

    0