Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Odliczanie czasu. Co w zamieszczonym kodzie powoduje złe odliczanie?

kRzaQ 05 Mar 2007 20:34 3184 13
  • #1
    kRzaQ
    Level 11  
    Witam.

    Mam taki oto problem.. piszę w bascomie program, którym potrzebuję dosc precyzyjnie odmierzac czas za pomoca timera, ale jak patrze na efekty to czas odliczany nijak się ma do tego co mi pokazuje zegarek.. zakladam ze moj zegarek chodzi dobrze :) (bo chodzi dobrze).. wiec raczej problem jest z mikrokontrolerem i moim pisaniem.... Podaje kod ów licznika i proszę o poradę co moge robic nie tak. Program liczy odcinki sekundowe i zapala/gasi diodkę.


    $regfile = "m8def.dat"
    $crystal = 8000000


    Config Timer0 = Timer , Prescale = 8
    Config Portd = Output

    On Timer0 Liczsekundy


    Dim Licz200us As Integer

    Enable Interrupts
    Enable Timer0

    Load Timer0 = 250



    Do
    Loop
    End



    Liczsekundy:

    Load Timer0 = 250
    Incr Licz200us

    If Licz200us = 4000 Then

    Licz200us = 0
    Toggle Portd.0

    End If
    Return



    pozdrawiam
  • #2
    starob
    Level 28  
    kRzaQ wrote:
    Witam.

    proszę o poradę co moge robic pozdrawiam


    1.poczytać forum a nie od razu post
    2.dać sobie spokój z bascom
    3.uczyć się i myć ręce

    Temat niedawno wałkowany na forum (dwa razy) tylko poszukać i poczytać. Nawet nie dostaniesz linka:cry:

    podpowiedz

    Enable Timer0

    Load Timer0 =0



    Do
    Loop
    End



    Liczsekundy:

    Load Timer0 = 250 wywalić

    resztę przerobić

    więcej nie wyciśniesz
  • #3
    kRzaQ
    Level 11  
    Dziekuje serdecznie.
    Rzeczywiscie teraz odnalazlem gdzies na forum cos co mi moze ulatwi.. tyle ze asma nie znam jeszcze dobrze, a to co powinno wedlug "podrecznika" chodzic.. powinno chodzic.


    Aha.. rozumiem, że wartość początkową timera mam wstawić 0, żeby od razu generował przerwanie, a potem co?.. przy "liczsekundy" mam zrobić 1000000 ?

    Wtedy tez chyba będzie to opoznienie i to tez dosc znaczne?
  • #4
    crazy_phisic
    VIP Meritorious for electroda.pl
    Przestawiłeś w Fuse bitach częstotliwość zegara? Jeśli nie, to twój procesor pracuje nie na 8MHz tylko na 1MHz. Co się tyczy wartości wpisywanej do licznika... - nie wydaje Ci się że po to wymyślono preskaler aby uniknąć stosowania zmiennych o wartościach 10^6? Przecież nie musisz odmierząc tak małych porcji czasu ;)
  • #5
    starob
    Level 28  
    Nie wiem co to za procek i pewnie go nie znam.
    Ile czasu będzie trwać przewinięcie licznika 16bitów
    Pierwszy raz wygeneruje odrazu ale następne (jeżli to licznik 16bit) to
    z 65536 tyknięć
    może zastosować (jak jest taka możliwość licznik 8bit)
    Zasada - w przerwaniu nie przeładowywać licznika wartością początkową (ma się sam kręcić od 0 do 0 )
    To jest jadna z przyczyn niedokładności
  • #6
    kRzaQ
    Level 11  
    Nie przestawialem fusebitów bo jest on taktowany zewnetrznym kwarcem 8Mhz.. A co do tego 10^6.. hmm... zielony jestem jeszcze i tak sobie jakos wymyśliłem, że jak zrobię takie taktowanie to będę mógł sobie dobierać wyższe czestotliwosci co da mi dokładniejsze wyniki... oczywiscie mogę się mylić i dlatego szukam tutaj rozwiazania...

    Dodano po 58 [sekundy]:

    To jest licznik 8 bitowy. a mikrokontroler to ATMEGA 8
  • #7
    crazy_phisic
    VIP Meritorious for electroda.pl
    kRzaQ wrote:
    Nie przestawialem fusebitów bo jest on taktowany zewnetrznym kwarcem 8Mhz...


    :) Skoro tak twierdzisz, odłącz do testów kwarc i zobacz co się stanie...
  • #8
    starob
    Level 28  
    to przewinięcie 0 do 255 trwa xx usek licz interwały
    xx aż będzie 1sek, a licznik niech sam się kręci w koło. Oczywiście przerwanie musi być obsłużone natychmiast.
    Nie da się programować w baskomie bez znajomości sprzętu
    Oczywiście co było nie powiedziane mam nadzieje, że mówimy o niedokładności kilku minut na dobę
  • #9
    kRzaQ
    Level 11  
    Ok.. w fusebitach mam ustawiony external XTAL czyli idzie zgodnie z kwarcem.

    Nie rozumiem tylko czemu taki kod:

    $regfile = "m8def.dat"
    $crystal = 8000000


    Config Timer0 = Timer , Prescale = 256
    Config Portd = Output
    Portd = &B11111111

    On Timer0 Liczsekundy


    Dim Liczus As Integer

    Enable Interrupts
    Enable Timer0

    Load Timer0 = 250




    Do
    Loop
    End



    Liczsekundy:

    Timer0 = Timer0 + 6 'bo 256-250 daje 6 :D
    Incr Liczus

    If Liczus = 125 Then

    Liczus = 0
    Toggle Portd.0

    End If
    Return

    Dziala poprawnie....


    Docelowo potrzebuje generować impulsy krótsze od 1 sekundy.. bo między 0,9ms a 20ms

    Dlatego robie takie dziwne preskalery.. gwoli jasności.
  • #10
    starob
    Level 28  
    Bez mojej znajomości Atmegi dalej to będzie
    .."prowadził ślepy kulawego".. -więcej nie potrafie
  • #11
    kRzaQ
    Level 11  
    Ok. I tak wielkie dzieki za pomoc. Poszperam i moze jakos dojde do tego czemu sie to dzieje w taki sposob... Podrecznik z ktorego korzystam niestety nie jest dość wyczerpujacy widac...

    Oczywiscie jesli ktos ma jakies pomysly to jestem wdzieczny za wzselka pomoc...

    Pozdrawiam.
  • #12
    crazy_phisic
    VIP Meritorious for electroda.pl
    Powiedzmy że dla szukanych czasów 0.9 - 20ms najmniejszym "krokiem" regulacji będzie 0.08ms. Wtedy konfigurujesz Timer0 do pracy z preskalerem 64 i otrzymujesz 8MHz/64 = 125kHz czemu odpowiada czas 8us. Teraz wpisując do timera wartość początkową = 246 otrzymujesz 256-246=10 a zatem przerwanie od Timer0 zgłaszane będzie co 10x0.008=0.08ms.
    W obsłudze przerwania zwiększasz tylko określony licznik zmiennej i masz regulacje z krokiem 0.08ms w przedziale dla zmiennej Byte od 0.08ms do 255x0.08=20.4ms.

    (Przenieś warunek sprawdzania wartości zniennej do pętli głownej, nie ma najmniejszego sensu wydłużania obsługi przerwania dodatkowymi operacjami)

    Ps. Na pewno pomoże Ci kalkulator czasów:
    http://www.edw.com.pl/index.php?module=ContentExpress&file=index&func=display&ceid=69&meid=22

    --
  • #13
    starob
    Level 28  
    crazy_phisic wrote:
    Timer0 zgłaszane będzie co 10x0.008=0.08ms.

    --


    prawie co 0.080ms, jak pomnożysz to "prawie"*255 to już może być dużo.
    Budując zegarek - to w skali doby to może być już kilka minut - już nie "prawie" tylko dużo zadużo.
    Specjaliście od pomiarów nie trzeba tego tłumaczyć.
    Oczywiście jest to do zrobienia,ale nie tak łatwo
    Proponuje https://www.elektroda.pl/rtvforum/topic688057.html
  • #14
    crazy_phisic
    VIP Meritorious for electroda.pl
    Procedura podana w listingu powyżej
    
     Timer0 = Timer0 + "nasza wartość"
    

    zapewni dostateczną dokładność... ;)