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.

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

FoxTech 22 Lut 2009 15:27 2507 19
  • #1 22 Lut 2009 15:27
    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.

    Code:


    '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 

    0 19
  • #2 22 Lut 2009 15:34
    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

    0
  • #3 22 Lut 2009 15:40
    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.

    0
  • #4 22 Lut 2009 15:56
    dawid512
    Poziom 32  

    Dziwne że to działa bo masz ustawione na zew. generator RC. Zmień to na
    hfuse=99
    lfuse=CF

    0
  • #5 22 Lut 2009 17:43
    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 ??

    0
  • #6 22 Lut 2009 18:27
    ZbeeGin
    Poziom 38  

    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.

    0
  • #7 22 Lut 2009 20:57
    dawid512
    Poziom 32  

    A czy kolega ma podłączony kwarc 8MHz z kondensatorami? Jeżeli nie to nie uzyskasz komunikacji z uc.

    0
  • #8 22 Lut 2009 22:48
    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ć?

    0
  • #9 22 Lut 2009 23:21
    dawid512
    Poziom 32  

    Coś masz nie tak, spróbuj dać kondensatory 33pF.

    0
  • #10 22 Lut 2009 23:55
    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 ?

    0
  • #12 23 Lut 2009 01:25
    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?

    0
  • #13 23 Lut 2009 06:44
    emarcus
    Poziom 35  

    FoxTech napisał:
    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?


    Cos mi tu nie pasuje!
    Jezeli pozostawiles wlaczony JTAG (JTAGEN=0) to jak mozesz miec podlaczony i pracujacy LCD do portu C?
    Aby TAP; cztery piny C2 :C5 funkcjonowaly jako zwykle piny I/O, jest warunek aby JTAG pozostal NIEzaprogramowany czyli 1
    Patrz datasheet str. 223.
    Ponadto jezeli JTAG interface nie jest podlaczony to JTAGEN powinien byc rowniez DISABLED.
    Patrz tabela 105 str 260.
    Poniewaz fusebit odpowiedzialny za JTAGEN jest szostym bitem w Fuse High Byte , zatem ten Byte powinien przyjac wartosc D9 zamiast 99

    Druga rzecz; zwrocmy uwage na Fuse Low Byte w ktorym generalnie ustawiasz zrodlo i warunki taktowania controllera
    Tabela 106 str.261,
    Poniewaz masz zewnetrzny Crystal, zatem CKSEL=1111 (tab2, str25) oraz SUT - tu masz troche wiecej swobody (patrz tab.5 str.27);
    Ostatecznie mozesz przyjac twoj FLB =DF albo EF, przy BOD disabled.
    Jezeli potrzebujesz programowac BOD, zatem musisz odpowiednio poprawic bit 6.
    Wszystko to powyzej mogles skrocic zagladajac do linku jaki wyslalem w poprzednim poscie (Fuse Calculator) warto to przestudiowac, moze byc przydatne czasem.

    emarcus

    0
  • #14 23 Lut 2009 13:50
    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??

    Code:

    $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   
       

    0
  • #15 23 Lut 2009 14:32
    dawid512
    Poziom 32  

    Zmień to

    Code:
    $crystal = 8000000 
    na to
    Code:
    $crystal = 1000000 
    a do licznika ładuj liczbę 131. Przestaw także preskaler na 64.

    0
  • #16 23 Lut 2009 15:48
    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??

    0
  • #17 23 Lut 2009 16:00
    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.

    0
  • #18 23 Lut 2009 17:06
    emarcus
    Poziom 35  

    grzesiug napisał:
    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??


    Jezeli nie zmieniales zadnych fuse bitow wiec pracujesz na fabrycznym ustawieniu, ktore wykorzystuje wewnetrny RC oscylator 8MHz
    podzielony przez 8 co w efekcie daje wynikowe taktowanie 1 MHz
    i do tej czestotliwosci musisz sie stosowac w obliczeniach przebiegow czasowych.

    Fakt podlaczena zewnetrznego oscylatora kwarcowego,czy rezonatora NIC nie zmienia. Po prostu processor go "NIE widzi" .
    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

    0
  • #19 23 Lut 2009 18:05
    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.

    Code:

    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ą?

    0
  • #20 23 Lut 2009 21:52
    emarcus
    Poziom 35  

    grzesiug napisał:
    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.


    Naturalnie!
    Dokladnosc wewnetrznego RC oscylatora jest na poziomie +/- 5%,
    kwarcowy krysztal daje dokladnosc rzedu +/- 20ppm (parts per milion),
    Po wykonaniu rachunku otrzymasz ze kwarc jest 4 miliony razy 'dokladnejszy' niz wew. oscylator. Czesto nie ma potrzeby szukac takiej dokladnosci i z powodzeniem wystarcza wew. oscylator, upraszczajac diagram i oszczedza tez 'pare groszy'.

    Fusebity, a konkretnie:
    Fuse Low Byte i Fuse High Byte okreslisz w zaleznosci od opcji jakie programujesz. Pelne informacje o kazdej opcji sa w datasheet ujete w tabelach i dodatkwych opisach/wyjasnieniach. Nie jest to trudne ustalic: w binary systemie ustawiasz zera i jedynki, a wynik zamieniasz na hex. Tabele podaja numery bitow w bajcie dla kazdej opcji.
    Nalezy pamietac ze liczenie kolejnych bitow zaczyna sie od 0 a nie od 1.
    Jezeli masz z tym trudnosci, to kilka postow wyzej podalem link do "Fuse Calculkator".
    Powstawiaj swoje dane i otrzymasz wynik obydwu bajtow (low i high)gotowy w postaci hex.
    Powodzenie procesu programowania 'fusebitow' bedzie zalezalo od tego jak uwaznie to robisz oraz jakiego programu i programatora uzywasz.
    Casem 'samorobki' niechetnie wspolpracuja z niektorym softem, albo sa niestabilne i niekiedy wprowadzaja bledy, a wtedy mowimy o niepowodzeniach.

    emarcus

    Dodano po 2 [godziny] 14 [minuty]:

    grzesiug napisał:



    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ą?

    Powinno byc:
    Timer0 = 131 '(256-125)=131

    emarcus

    0