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

[ATmega16][BASCOM] Precyzja timer0 przy zegarze 8MHz

FoxTech 22 Lut 2009 15:27 2762 19
REKLAMA
  • #1 6187884
    FoxTech
    Poziom 20  
    Szanowni koledzy czy ktoś z was może mi powiedzieć jaką mogę osiągnąć precyzję przy odmierzaniu czasu przy wykorzystaniu układu ATmega16 z zewnętrznym zegarem 8.000 MHZ(rezonator kwarcowy)?
    Morduje to już drugi dzień i nie mogę zrobić tego w sposób precyzyjny - na każde odmierzone 10 minut atmege spieszy o ok 20s - taka zwłoka jest dla mnie niedopuszczalna - do przyjęcia było by ok 5 minut na dobę.
    Czy taka zwłoka jest w ogóle możliwa do osiągnięcia przy 8MHZ kwarcu czy konieczne bedzię użycie wewnętrznego RTC z kwarcem zegarkowym ?
    Potrzebuję napisać program którego jednym z podprogramów będzie minutnik odmierzający czas od 1 godziny do 48 godzin (długość odmierzanego czasu będzie wybierana klawiszami).

    W poniższym listingu przedstawiam wykorzystywany listing odmierzający ilość sekund.

    
    
    'Przykład programu odmierzającego 1 sekundowe odcinki czasu z wykorzystaniem timer0
    'Timer0 będzie odmierzał dokładnie 1 sekundę 8MHz/64/250/500 = 1 sekunda
    '$regfile = "m16def.dat"                                     'rejestry mikrokontrolera atmega16
    '$crystal = 8000000                                          'częstotliwo.ć taktowania mikrokontrolera
    'Config Pinb.1 = Output                                      'linia pb1 jako wyj.cie
    Config Timer0 = Timer , Prescale = 256                      'deklaracja timera jako czasomierzab z prescalerem 64
    
    On Timer0 Przerwanie_co_8ms                                 'deklaracja jaka etykieta obsługuje przepełnienie od timer0
    Dim Licznik As Integer                                      'zmienna licznikowa
    Dim Sek As Integer
    Enable Interrupts                                           'odblokowanie globalnych przerwań
    Enable Timer0                                               'odblokowanie przerwania od przepełnienia timer0
    Timer0 = 6                                                  'wpisanie warto.ci początkowej 6 do timera, czyli timer będzie zliczał 250 (256-6) impulsów
    Licznik = 0                                                  'wyzerowanie zmiennej licznikowej
    Sek = 0                                                     'wyzerowanie zmiennej sekundnika
    
    Do
    
     Upperline : Lcd "  " ; Sek
                                                              'petla główna programu
    Loop
    End                                                         'koniec programu
    
    Przerwanie_co_8ms:                                          'podprogram przerwania od przepełnienia timer0 wywolywanego co 2 ms
     Counter0 = Counter0 + 6                                    'ustawienie początkowej warto.ci timera0 poprzez dodanie do niego warto.ci 6 (odliczone zostanie dokładnie kolejne 250 impulsów)
     Incr Licznik                                               'zwiększenie licznika
     If Licznik = 125 Then                                      'je.li zmienna licznik równa się 500 (czyli odliczone zostało 500*2ms=1sek), to
     Incr Sek                                                   'dodaj jedna sekunde na wyswietlaczu
    Licznik = 0                                                 'wyzeruj zmienną licznik
    End If
    Return  
  • REKLAMA
  • #2 6187930
    dawid512
    Poziom 32  
    Jak masz ustawione fuse bity? Po za tym dlaczego te 2 linijki masz jako komentarz?
    Cytat:
    '$regfile = "m16def.dat" 'rejestry mikrokontrolera atmega16
    '$crystal = 8000000 'częstotliwo.ć taktowania mikrokontrolera
  • #3 6187969
    FoxTech
    Poziom 20  
    te linijki zaremowałem ponieważ ustawiłem to ręcznie w opcjach bascomu - dziękuję za cenną uwage poprawie to.

    co do fusebitów użyam avr burn-o-mat
    hfuse=99
    lfuse=E6

    w opcji frequency range zaznaczone 3-8Mhz.
  • REKLAMA
  • #4 6188052
    dawid512
    Poziom 32  
    Dziwne że to działa bo masz ustawione na zew. generator RC. Zmień to na
    hfuse=99
    lfuse=CF
  • #5 6188508
    FoxTech
    Poziom 20  
    Zastosowałem się do rady, podane przez kolege ustawienia zostawiają włączony JTAG (na PorcieC mam LCD) co pozwoliłem sobie zmienić.

    Efekt::

    burn-o-mat wyświetla wesoły komunikat:
    "ERROR readind flash"
    "ERROR writing flash" etc etc

    Wygląda na no że ubiłem właśnie ATmege ??
  • #6 6188705
    ZbeeGin
    Poziom 39  
    Jak już odzyska kolega władzę w krainie ATMega16, to zainteresuj się trybem CTC pracy tego licznika. Jest do tego odpowiedni parametr:

    CONFIG TIMER0 = TIMER, PRESCALE = 256, CLEAR TIMER = 1

    Tylko pamiętaj aby skorzystać z przerwania porównania a nie z przerwania przepełnienia.
  • #7 6189708
    dawid512
    Poziom 32  
    A czy kolega ma podłączony kwarc 8MHz z kondensatorami? Jeżeli nie to nie uzyskasz komunikacji z uc.
  • #8 6190387
    FoxTech
    Poziom 20  
    Tak kwarc jest z kondensatorami 22pF. Ten egzemplarz Atmegi potraktowany Powyższymi fusebitami wylądował już w pawlaczu.
    Fusebity ustawione w obecnym uc to:
    hfuse=c9
    lfuse=ff

    Z tak ustawionymi fuse bitami układ spieszy "tylko" 12s na godzine.
    Czy taka precyzja jest standardem przy odmierzaniu czasu w ten sposób, czy może da się z tym coś jeszcze zrobić?
  • REKLAMA
  • #9 6190540
    dawid512
    Poziom 32  
    Coś masz nie tak, spróbuj dać kondensatory 33pF.
  • #10 6190639
    FoxTech
    Poziom 20  
    Spróbuję z tymi kondensatorami,
    Czy fusebity są dobrze ustawione?
    Jaki rozrzut(s) powinienem mieć w przypadku prawidłowego funkcjonowania układu ?
  • REKLAMA
  • #12 6190792
    FoxTech
    Poziom 20  
    Pozwolę sobie zacytować sam siebie:

    FoxTech napisał:
    Zastosowałem się do rady, podane przez kolege ustawienia zostawiają włączony JTAG (na PorcieC mam LCD) co pozwoliłem sobie zmienić.

    Efekt::

    burn-o-mat wyświetla wesoły komunikat:
    "ERROR readind flash"
    "ERROR writing flash" etc etc

    Wygląda na no że ubiłem właśnie ATmege ??


    Czy efekty nie będą takie same?
    Jaki rozrzut(s) powinienem mieć w przypadku prawidłowego funkcjonowania układu ?(obecnie spieszy 12s na godzinę)
    Co złego jest w zaproponowanych prze zemnie fusebitach?
  • #13 6190874
    Konto nie istnieje
    Poziom 1  
  • #14 6192079
    grzesiug
    Poziom 12  
    Podłączę się pod temat ponieważ mam podobny problem.
    W atmega8 mam prawie identyczny program do odmierzania 1s (przepisany z książki).Do uC mam dołączony kwarc 8MHz poprzez 2 x 30 pF, żadnych fusbitów nie ustawiałem, problem polega na tym, że 1s trwa około 10 sekund. Gdzie szukać problemu??

    
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Pinc.2 = Output
    Config Pind.7 = Output
    Led Alias Portc.2
    Przekaznik Alias Portd.7
    Config Timer0 = Timer , Prescale = 256
    
    On Timer0 Odmierz_1s
    
    Dim Licz_8ms As Byte
    
    Enable Interrupts
    Enable Timer0
    Load Timer0 = 250
    
    Do
    Loop
    End
    
    Odmierz_1s:
    
    Load Timer0 = 250
    Incr Licz_8ms
    
    If Licz_8ms = 125 Then
    
    Licz_8ms = 0
     Toggle Przekaznik
     Toggle Led
    
     End If
     Return    
       
  • #16 6192695
    grzesiug
    Poziom 12  
    Teraz nie co lepiej(1s= około 2s), możesz mi wytłumaczyć jak to wyliczyć i dlaczego zmiana częstotliwości??
  • #17 6192757
    dawid512
    Poziom 32  
    Jest taki fajny programik nazywa sie: Kalkulator AVR. Zmiana czestotliwosci dlatego ze nie ruszales fuse bitow ktore standardowo ustawiaja zegar na 1MHz.
  • #18 6193101
    Konto nie istnieje
    Poziom 1  
  • #19 6193443
    grzesiug
    Poziom 12  
    ok. Więc mam kolejne pytania, a mianowicie czy uruchomienie zew. kwarcu spowoduje bardziej precyzyjne odliczanie czasu i jak ustawić te fusbity. Wiem że na temat fusbitów jest dużo na forum, ale również jest dużo postów typu " ustawiłem fusbity i nie mogę zaprogramować", więc się trochę boię bo nigdy tego nie robiłem.

    
    Druga rzecz:
    Masz troche nieprawidlowy syntax (zapis) wprowadzania wartosci do Timer0, co byc moze nawet pracuje, ale takze wprowadza w blad.
    Jezeli stosujesz dyrektywe "Load" wtedy:
    Load Timer0 , 125
    albo rownowazne
    Timer0 = 131
    Dyrektywa "Load" wykonuje konversje: (256-wartosc) lub (65536- wartosc) dla Timer1


    Tutaj miałeś całkowitą rację, ciekawe dlaczego tak było w książce.

    Timer obliczyłem tak 1Mhz/64/125 = 125 =8ms
    czyli Timer0=125 ,Prescale = 64 i zliczam 125 przerwań na sekundę, uzyskana dokładność to strata ok 1s na 1 min, jak uzyskać lepszą?
  • #20 6193983
    Konto nie istnieje
    Poziom 1  
REKLAMA