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

Timer w BASCOM na 89C2051 - opóźnienie kilku sekund na minutę, jak poprawić?

chaos 28 Sty 2004 17:27 5934 11
REKLAMA
  • #1 494266
    chaos

    Poziom 12  
    Posty: 268
    Pomógł: 1
    Ocena: 12
    Witam
    Zmowu timery :)
    Zrobilem sobie timerek, ktory ma odlicza czas do 24h i testuje go. W czasie testow zauwazylwem ze puzni sie kilka (ok.5) sekund na minute.
    Przejzalem posty na elektrodzie i nie moge nic wymyslic.

    zaladowana do timera wartosc dotyczy kwarcu 11.0592, ale probowalem wyliczyc dla innych kwarcow i wzzkazania byly jeszcze mniej dokladne.

    pomiar dokonywalem stoperem w zegarku.

    listing ponizej jest jest taki testowy, generujacy dzwiek po 1 minucie.

    co robie nie tak.



    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte
    Dim Licz As Byte
    Dim Pip_flag As Byte
    Declare Sub Biper
    Declare Sub M
    Config Timer1 = Timer , Gate = Internal , Mode = 1
    Enable Interrupts
    Enable Timer1
    Load Timer1 , 4150
    On Timer1 Przerwanie

    'Enable Timer1


    Godziny = 0
    Minuty = 0
    Sekundy = 0
    Licz = 0
    Pip_flag = 0

    Set P3.0 'LED
    Set P3.1 'BUZZER
    Set P3.2 'PRZYCISK


    'Start Timer1
    Start Timer1

    Do
    If Pip_flag = 1 Then
    Sound P3.1 , 100 , 10
    If P1.7 = 0 Then
    Pip_flag = 0
    End If
    End If
    'print licz
    Loop

    Przerwanie:
    'podprogram PRZERWANIE
    Incr Licz
    'If Licz = 25 Then
    If Licz = 15 Then 'odliczanie 1s przerwanie
    Licz = 0
    Incr Sekundy
    'zwiekszaj zmienna SEKUNDY po wystapieniu przerwania
    If P3.0 = 0 Then
    Set P3.0
    Else
    Reset P3.0
    End If



    End If

    If Sekundy = 60 Then 'WARUNEK: jesli zmienna SEKUNDY bedzie = 60
    Sekundy = 0 'ustaw ja na 0
    Incr Minuty
    'zwieksz zmienna MINUTY o 1
    End If 'koniec warunku


    If Minuty = 60 Then 'WARUNEK: jezeli zmienna MINUTY bedzie = 60
    Minuty = 0 'ustaw ja na 0
    Incr Godziny 'zwieksz zmienna GODZINY o 1
    End If
    'koniec warunku
    If Godziny = 24 Then 'WARUNEK: jezeli zmienna GODZINY bedzie = 24
    Godziny = 0 'to ustaw jej wartosc na 0
    End If



    If P3.7 = 0 Then
    If Minuty = 1 Then
    Pip_flag = 1
    Godziny = 0
    Minuty = 0
    Sekundy = 0
    End If
    End If


    Return
  • REKLAMA
  • #2 494411
    cyberdar
    Poziom 31  
    Posty: 1465
    Pomógł: 161
    Ocena: 73
    Jak przyglądałem się TIMER'om w Bascomie to zauważyłem, że coś jest popieprzone z trybami. Jedyny tryb który działa mi jako tako to tryb drugi. W symulacji widać jak są załadowane rejestry i jak się w nich wszystko zmienia. W pozostałych trybach jest coś nie tak. Jeśli ktoś już się z tym spotkał niech coś napisze. Pozdrawiam.
  • REKLAMA
  • #3 494506
    chaos

    Poziom 12  
    Posty: 268
    Pomógł: 1
    Ocena: 12
    nie wiem co u ciebie jest nie tak, ale u mnie w mode 1 w symulacji jest wszystko w pozadku tzn. widac jak sie zmieniaja TL1 iTH1.
    Nie moge tylko obliczyc jaka wartosc zaladowac do timera, aby wyliczal mi 1 sekunde. Doswiadczalnie zauwazylem ze moj program puzni sie 3 sekundy na minute!
    Co zrobilem nie tak.
    Pozdrawiam
  • #4 494513
    alexiel
    Poziom 15  
    Posty: 211
    Pomógł: 1
    Witam ja bym zmienił kwarc na 12Mhz to będzie rozdzielczość co 1us i wtedy timer ustaw na 50ms (50000) i masz równy czas .
    Nie wiem jak jest w bascomie ale asemblerze instrukcją ORL THL,#wartość można skorygować wartość licznika żeby odmierzał równy czas.
  • REKLAMA
  • #5 494524
    crazy_phisic
    VIP Zasłużony dla elektroda
    Posty: 2244
    Pomógł: 278
    Ocena: 131
    Musisz zaladowac do licznika w momencie obslugi przerwania wartosc Timer1=Timer1+4150 i wszystko bedzie smigac az milo :) sam nad tym sie glowilem tydzien heheh
  • #6 494525
    Tdv
    Poziom 34  
    Posty: 2237
    Pomógł: 150
    Ocena: 53
    Facet, zacznij od przejrzenia jakieś dokumentacji do '51. Nie dziwne, że Ci tyle późni bo przerwanie jest u Ciebie generowane co 71,111111 ms, a nie tak jak zdaje się chciałeś co 66,66666ms.
    Po pierwsze to trzeba ładować każdorazow licznik w obsłudze przerwania, a po drugie to dlaczego chcesz liczyć takie bezsensy jak 66,6666ms? Nie prościej odliczać np.50ms i co 20 przerwanie inkrementowć sekundy?
    Dla 50ms wpisujesz do TH1 liczbe (4C)hex, TL1 zostaw w spokoju i tak na poczatku obslugi przerwania za każdym razem. Wtedy zegarek powinien zaczac liczyc z dokladnością dostrojenia kwarcu.
  • #7 494529
    crazy_phisic
    VIP Zasłużony dla elektroda
    Posty: 2244
    Pomógł: 278
    Ocena: 131
    Moja odpowiedz byla chyba za szybka, najpierw przelicz tak jak radzi Tdv a pozniej zastosuj te procedure....
  • #8 495023
    W.K
    Poziom 15  
    Posty: 139
    Pomógł: 1
    Nie wnikając w obliczenia chciałbym zwrócić uwagę na bascomowe polecenie Load timer1.Polecenie to w zamierzeniu autora powinno dokonać przeliczenia 65536 - 4150 = 61385 i wynik załadować do timera
    A w rzeczywistości to jest tak:
    Load Timer1 , 4150 powoduje zapis:TL1=0xCA , TH1=0xCA -patrz symulator Bascom.
    Daje to wartość początkową timera 51914 , czyli "przekręcenie" nastąpi po 13622 imp. zeg.
    Jest to błąd tego polecenia(w trybie 2 jest ok.).Aby uzyskać zamierzony efekt zamiast Load Timer1 , 4150
    można wpisać:
    TL1 = &HC9
    TH1 = &HEF
    Wartość początkowa timera1 0xEFC9 = 61385,czyli"przekręci się" po 4150 imp.
    Ciekawostka jest również w Bascom AVR z tym poleceniem.Jeżeli to kogoś zainteresuje to chętnie podzielę się moimi spostrzeżeniami.
  • REKLAMA
  • #9 495237
    Tdv
    Poziom 34  
    Posty: 2237
    Pomógł: 150
    Ocena: 53
    Wpisywaie do TL przez TL1 = &HC9 powoduje, że zegarek będzie niedokładny ze względu na to, że nigdy nie wiesz ile po ilu cyklach maszynowych ta instrukcja zostanie wykonana, szczególnie jeżeli program powstał w BASCOMie. Co do BASCOMa i jego poleceń, no cóż...
  • #10 495440
    W.K
    Poziom 15  
    Posty: 139
    Pomógł: 1
    Jak napisałem nie wnikam w sedno tego zegarka,chodziło mi tylko o zwrócenie uwagi na błąd polecenia Load Timer1 ,...
  • #11 498471
    chaos

    Poziom 12  
    Posty: 268
    Pomógł: 1
    Ocena: 12
    Dzieki, dzieki, dzieki.
    Juz wszystko jasne. Nie ladowalem timera w przerwaniu.
    A ta dziwna wartosc to pozostalosc po probach z roznymi kwarcami. Zapomnialem ja zmienic przed wyslaniem posta. sorry.
    Jeszcze raz wielki THX
    Pozdrawiam
  • #12 4807188
    jokii
    Poziom 1  
    Posty: 1
    Witam,
    może i temat wyczerpany ale może coś dorzuce od siebie.
    Ostatnio tez tobiełem ot taki zegarek i napotkalem na te same problemy z BASCOM'em dokładność udało mi się zwiększyć zastepując komende "LOAD TIMERx" asemblerowymi "mov"
    Przykład zamieszczam poniżej może się komus przyda.
    (kwarc 12MHz)

    Dim Sekundy As Byte , Minuty As Byte , Godziny As Byte , Przeladow As byte
    Config Lcd = 16 * 2
    Config Timer1 = Timer , Gate = Internal , Mode = 1

    Mov tl1,#h'DC
    Mov th1,#h'B


    Cls


    On Timer1 Przerwanie_timera
    Enable Timer1
    Enable Interrupts
    Start Timer1




    Do

    Loop

    Przerwanie_timera:

    Mov tl1,#h'DC
    Mov th1,#h'B




    Incr Przeladow



    If Przeladow = 16 Then
    Incr Sekundy
    Przeladow = 0
    End If

    If Sekundy = 60 Then
    Incr Minuty
    If Minuty = 60 Then
    Incr Godziny
    Minuty = 0
    End If
    Sekundy = 0
    End If

    If Godziny = 100 Then
    Godziny = 0
    End If


    If Godziny < 10 Then
    Lcd "0"
    End If
    Lcd Godziny ; ":"

    If Minuty < 10 Then
    Lcd "0"
    End If
    Lcd Minuty ; ":"

    If Sekundy < 10 Then
    Lcd "0"
    End If
    Lcd Sekundy
    Home


    Return


    'licznik liczy 62500 cykli wiec początkowa wartość TH1:TL1=0xBDC (3036)
    'jak gdzieś się rypsnąłem to sorry - dopiero "raczkuje" w tych sprawach

Podsumowanie tematu

✨ Dyskusja dotyczy problemu niedokładności timera w BASCOM dla mikrokontrolera 89C2051, gdzie zegar opóźnia się o kilka sekund na minutę. Główną przyczyną jest nieprawidłowe ładowanie wartości do rejestrów timera oraz brak ponownego załadowania licznika w obsłudze przerwania. W BASCOM polecenie "Load Timer1, wartość" działa niezgodnie z oczekiwaniami w trybie 1, powodując błędne ustawienie rejestrów TH1 i TL1, co skutkuje niedokładnym odmierzaniem czasu. Zaleca się ręczne ustawianie rejestrów TH1 i TL1 w przerwaniu, np. poprzez asemblerowe instrukcje "mov", aby uzyskać precyzyjne wartości startowe licznika. Dodatkowo sugerowano stosowanie kwarcu 12 MHz dla lepszej rozdzielczości i prostszego obliczania wartości timera. Proponowane jest także odliczanie przerwań co 50 ms i inkrementacja sekund po 20 przerwaniach, co poprawia dokładność. Podsumowując, kluczowe jest poprawne przeliczanie i ustawianie wartości licznika w przerwaniu oraz wybór odpowiedniego kwarcu, aby timer działał z wymaganą precyzją.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA