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

Atmega328 - timer1 i timer0 - sterowanie diodami w zegarze widmowym

apollo1412 16 Sty 2015 21:15 2118 30
REKLAMA
  • #1 14337724
    apollo1412
    Poziom 11  
    Witam.
    Próbuję napisać program który będzie sterował włączanieM diod nad kręcącą się nad nimi tarczą z wyciętymi cyframi, taki zegar widmowy. Chcę do tego użyć timera1 i timera0 w atmedze328p.
    Timer1 ma liczyć czas jednego obrotu, dostaje sygnał z transoptora, korzystam z przerwania ICP. W przerwaniu, liczbę jaką do jakiej doliczył timer1 zapisuje gdzie indziej, zeruje timer1 i kręci się następne okrążenie. W tym czasie chcę użyć timer0 w przerwaniu od przepełnienia. Chcę aby w ciągu jednego obrotu tarczy dał 96 sygnałów przerwań. Do tego używam liczby do jakiej doliczył timer1 i dziele ją na 96.

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Ale nie działa za dobrze. Macie jakieś pomysły co do tych timerów?
  • REKLAMA
  • #2 14337823
    BlueDraco
    Specjalista - Mikrokontrolery
    Przenieś kod z pętli głównej do przerwania timera T0.
  • REKLAMA
  • #4 14337870
    apollo1412
    Poziom 11  
    Dalej nie o to chodzi. Mam wrażenie że timer0 jest za wolny, widzę kilka cyfr na raz.
  • #6 14337903
    apollo1412
    Poziom 11  
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Efekt jest taki że widzę podświetlone kontury wszystkich cyfr powoli przekręcających się w lewo (tarcza też w lewo się kręci)
  • #8 14338002
    apollo1412
    Poziom 11  
    Zakładam że obrót będzie trwał najdłużej 20ms, czyli od 50 obrotów na sekundę. Czyli timer1 może doliczyć do 1250 (bo preskaler 256).
    W wtedy dzielę te 1250 na 48 częsci i wychodzi 26. To ma być 26 do przerwań przepełnienia dla timera0 dla preskalera 256 ale jest preskaler 64 więc powinno być 104. I wtedy zapasam diodę na czas 4 lub 3 przerwań.
  • REKLAMA
  • #10 14338029
    apollo1412
    Poziom 11  
    Przepraszam, cały czas wprowadzam zmiany. Czy 48 czy 96 -od tego będzie zależeć tylko czas jaki będzie wyświetlać się jedna cyfra. Cyfr, a właściwie znaków jest 12, stąd takie liczy 24,48,96.
  • #11 14338058
    dondu
    Moderator na urlopie...
    Starajmy się rozmawiać o jednym kodzie :)

    Drobne poprawki w obu przerwaniach:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    by nie liczyć za każdym przerwaniem T0.

    Liczysz dobrze, ale nie uwzględniasz tego w kodzie programu. Innymi słowy nie przeliczasz 26 na 104.
  • #12 14338075
    apollo1412
    Poziom 11  
    Zmienna impuls tyczy się timera1 to ona mówi nam o tym ile czasu upłynęło w czasie jednego obrotu.
    Wysyłam ją sobie na terminal i przyjmuje bardzo dziwne wartości, powinna ciągle oscylować wokół jakieś liczby, bo tarcza się kręci ze stałą prędkością, a zmienia się w dość szerokim przedziale. Może źle ją odczytuje z ICR?
  • REKLAMA
  • #14 14338106
    apollo1412
    Poziom 11  
    Cytat:
    Jeszcze raz - w którym miejscu to wykonujesz?:
    dondu napisał:
    Liczysz dobrze, ale nie uwzględniasz tego w kodzie programu. Innymi słowy nie przeliczasz 26 na 104.

    Jeżeli ustawie te same preskalery to tu:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    timer0 jest w trybie normalnym, więc jeżeli chcę żeby przepełnił się po tylu impulsach ile wyniosi 1/96 całego obrotu to muszę odjąć tę wartość od 255.
  • #15 14338115
    dondu
    Moderator na urlopie...
    OK, ale odejmujesz złą wartość ponieważ:

    dondu napisał:
    Innymi słowy nie przeliczasz 26 na 104.


    dla przypadku 48:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Piszmy tylko o 48, OK? Cofnij się więc do tego:

    apollo1412 napisał:
    Zakładam że obrót będzie trwał najdłużej 20ms, czyli od 50 obrotów na sekundę. Czyli timer1 może doliczyć do 1250 (bo preskaler 256).
    W wtedy dzielę te 1250 na 48 częsci i wychodzi 26. To ma być 26 do przerwań przepełnienia dla timera0 dla preskalera 256 ale jest preskaler 64 więc powinno być 104. I wtedy zapasam diodę na czas 4 lub 3 przerwań.

    i sprawdź ten fragment programu, ponieważ:

    dondu napisał:
    Liczysz dobrze, ale nie uwzględniasz tego w kodzie programu.
  • #16 14338156
    apollo1412
    Poziom 11  
    Niestety nie mogę zrozumieć o co Ci chodzi
  • #18 14338181
    apollo1412
    Poziom 11  
    Powinno być 151
  • #20 14338207
    apollo1412
    Poziom 11  
    Powinno być
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #22 14338256
    apollo1412
    Poziom 11  
    Kod: text
    Zaloguj się, aby zobaczyć kod



    Teraz używam tych samych preskalerów.

    Efekt jest taki że widać kilka konturów znaków, zamiast jednego wyraźnego.
  • #23 14338302
    dondu
    Moderator na urlopie...
    Moim zdaniem teraz program powinien działać poprawnie. Skoro nie działa należy dodać pewne elementy porządkowe.

    Jednym z nich jest włączanie i wyłączanie Timera0, a drugim resetowanie licznika preskalera Timera0.

    Ten pierwszy powinien polegać na tym, że Timer 0 powinien startować w momencie przerwania Timer1, a zatrzymywać się, w momencie odliczenia 95 przerwania.

    Resetowanie preskalera natomiast jest nieco bardziej skomplikowane, ponieważ bit PSRSYNC zeruje preskaler obu tych timerów. W związku z tym resetowanie także powinno być w przerwaniu Timera1.

    Możesz pokazać jakieś zdjęcie tego efektu?

    EDIT:

    Dla porządku zmienną kawalek zrób statyczną w przerwaniu T0.
  • #24 14341427
    apollo1412
    Poziom 11  
    Kod: text
    Zaloguj się, aby zobaczyć kod


    W ten sposób oba liczniki liczą dobrze. Niestety za złe liczenie odpowiadała część mechaniczna, czyli czujnik "krzywo" zamontowany.

    Kiedy wysyłam zmienna impuls UARTem, to pokazuje mi dobre cyfry, można obliczyć z tego prędkość itd. Ale kiedy dodaje do tego włączanie diod
    Kod: text
    Zaloguj się, aby zobaczyć kod

    czy to w przerwaniu od timera0 czy to w pętli głównej nagle gubi się wynik, pokazują się złe liczby tak jakby procesor nie wyrabiał się z włączaniem diod. Czy to możliwe?
  • #25 14342759
    dondu
    Moderator na urlopie...
    apollo1412 napisał:
    czy to w przerwaniu od timera0 czy to w pętli głównej nagle gubi się wynik, pokazują się złe liczby tak jakby procesor nie wyrabiał się z włączaniem diod. Czy to możliwe?

    Nie analizowałem programu powyżej, ale uC pracuje z maksymalną częstotliwością i bez problemu musi się wyrobić.
    Natomiast dodanie wysyłania UART może wprowadzić jakieś problemy, ale tylko Ty wiesz jak ta biblioteka jest napisana.
  • #26 14344267
    apollo1412
    Poziom 11  
    Jest to biblioteka z blga mirekk36. Specjalnie sprawdziłem jakie będą wysyłane wartości bez włączania diod i włączaniem. Te z włączanie dawały już złe wyniki. Może schemat podłączenia jest zły dlatego diody za wolno reagują?
  • #27 14344403
    BlueDraco
    Specjalista - Mikrokontrolery
    Czy mógłbyś jakoś precyzyjnie wyjaśnić, na czym polega błędne działanie programu i załączyć wersję, której zachowanie opisujesz?
  • #28 14344509
    apollo1412
    Poziom 11  
    Jasne. Korzystam z tego programu żeby wysyłać wartość impuls oraz rmp na terminal.
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Po rozpędzeniu silnika dostaje stabilny pomiar np. 1400 +-10 impuslsów co daje ok ~9ms na obrót przy preskalerze 1024 (kwarc 16mHz)
    Dwie linijki odpowiadające za włącznie diod zą zakonentowane. Kiedy jednak usuną zakomentowanie
    Kod: text
    Zaloguj się, aby zobaczyć kod

    żeby zapalić diody na krótką chwile, która w tym przypadku trwa od kawalek 18 do kawalek 20, to terminal nie pokazuje mi już stabilnej liczby tylko szaleje. Może włączać te diody inaczej niż przez funkcję if?
  • #30 14346192
    apollo1412
    Poziom 11  
    Dodaje dodatkowo ilość impulsów które mogły się pojawić zanim wykonała się ta linijka a po zerowaniu licznika.
REKLAMA