logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega8] [Atmega8][Bascom] Jak ustawić timer 2-bajtowy na przerwanie co sekundę?

Wojtek001 05 Lip 2012 18:32 6080 47
REKLAMA
  • #1 11074988
    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?
  • REKLAMA
  • #2 11075062
    LordBlick
    VIP Zasłużony dla elektroda
    Preprocesor twoim przyjacielem:
    Kod: text
    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
  • #3 11075092
    Wojtek001
    Poziom 15  
    A jak jest w BASCOMIE / uC domyślnie ? Tzn. ja nie ustawiałem żadnego trybu pracy timera.
  • #4 11075101
    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... ;)
  • #5 11075111
    stanleysts
    Poziom 27  
    CTC trzeba wybrać natomiast domyślnym trybem jest ten z przepełnieniem.
  • #6 11075131
    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: .
  • REKLAMA
  • #7 11075161
    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
  • #8 11075170
    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.
  • #9 11075469
    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?
  • #10 11075500
    stanleysts
    Poziom 27  
    Wiem o tym, przerwanie jest generowane, gdy przepełnimy licznik czyli po 65536.
  • Pomocny post
    #11 11075665
    Konto nie istnieje
    Konto nie istnieje  
  • #12 11075697
    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 ?
  • #13 11075837
    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.
  • #14 11077155
    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ć.
  • #15 11077383
    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.
  • #16 11078050
    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?
  • REKLAMA
  • #17 11078184
    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
  • #18 11078239
    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 ...
  • #19 11078444
    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.
  • #20 11079426
    Dar.El
    Poziom 41  
    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.
  • #21 11079496
    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 ;)
  • #22 11080073
    Konto nie istnieje
    Konto nie istnieje  
  • #23 11080260
    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.
  • #24 11084380
    Nawigator
    Poziom 33  
    Ewentualnie można poczytać jakieś noty Atmela na temat liczników, te i dalsze:
    AVR091 www.atmel.com/Images/doc4298.pdf
    AVR130 www.atmel.com/Images/doc2505.pdf

    po coś je publikują...

    Inna rzecz to poprawnie dobrany kwarc i właściwe pojemności do masy.

    N.
  • #26 11124507
    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) ?
  • #27 11124935
    Konto nie istnieje
    Poziom 1  
  • #28 11125170
    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?
  • #29 11125524
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #30 11125585
    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.
REKLAMA