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

[Atmega88][C] Uzupełnienie kodu dla generatora 2kHz w trybie CTC na Timer1 16bit

Bluzman 22 Wrz 2020 15:17 813 10
  • #1 18936791
    Bluzman
    Poziom 4  
    Witam wszystkich chętnych do pomocy.
    Potrzebuję zrobić na uC Atmega88 generator sygnału w trybie CTC na Timer1 16bit o częstotliwości 2kHz. Przetaktowałem w mkAVRCalcutaor procesor na 128kHz + CKDIV8 czyli wewnętrzny podział przez 8. Daje to 16000Hz więc preskaler ustawiłem na 8 = 2000Hz. Generator ma wysyłać falę cały czas, bez żadnych regulacji itd. Umieszczam kod programu i właściwie to prosiłbym o uzupełnienie go niż odsyłanie do stron z opisami zasady działania timerów. To niewiele mi dało, wolałbym przeanalizować poprawny kod, łatwiej będzie zrozumieć.

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

    Czy taki kod nie powinien już generować jakiegoś przebiegu, co należy jeszcze umieścić, przerwania?
    Dzięki za pomoc z góry.
  • #2 18937148
    bart-projects
    Poziom 29  
    Nie jest czasem tak, że poprzestawiałeś to na najwolniejsze uC w okolicy a potem kazałeś mu jeszcze liczyć do 1999 zamiast 1? I to może nie dać wyniku :P

    Jeśli wolałbyś jeszcze coś innego na tym uC robic oprócz tego co zrobiłoby NE555 to lepiej ustawić go na wyższe taktowanie a wykorzystać prescalery Timerów i ich pojemność. 2kHz to z palcem spokojnie przy taktowaniu 16MHz masz.
  • #3 18937238
    Bluzman
    Poziom 4  
    Dlaczego 1? Wartość w OCR1A ma być 1 czy preskaler 1? Tak czy inaczej przy wartości 1 w OCR1A też nie daje efektu i No prescaling też.

    Teraz ma być 2kHz, zapewne później będzie zmieniane na inne częstotliwości. Chodzi bardziej o wykorzystanie możliwości jakie daje uC (jak CTC) niż zastosowanie NE555.
  • Pomocny post
    #4 18937524
    trol.six
    Poziom 31  
    Jeżeli nie używasz przerwań to ich nie włączasz. Wprawdzie nie włączasz głównego, ale włączasz od timera (TIMSK1), dlaczego?

    Wzór z dokumentacji dla CTC:
    F = Fclk / (2 * N * (1+OCR1A)) = 16000 / ( 2 * 8 * 2000 ) = 16000 / 32000 = 0.5Hz

    Sterowanie pinem OC1A dla CTC:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    .
  • #5 18937786
    bart-projects
    Poziom 29  
    Zerknij na ten kod, zrobiony na rejestrach,... prosto tłumaczy co i jak a przy okazji ma tez DutyCycle. Jak niepotrzebne to ustaw 50%.
    https://www.elektroda.pl/rtvforum/topic3725206.html#18898698

    Dodano po 8 [godziny] 44 [minuty]:

    Może inaczej...
    uC prosto ze sklepu z podzielnikiem CKDIV8 czyli kręci sie 1MHz
    Ty chcesz 2kHz=2000Hz
    1000_000Hz/2000Hz = 500
    Wystarczy ustawić Timer na CTC i liczyć do 500 po czym odwrócic stan...a tak na prawdę to do 250.. a tak na prawdę do 249...

    Teraz niech to będzie 16MHz
    16MHz*0.2MHz=8000
    Do 16 bit timera wejdzie najwięcej 65536 więc chyba to się zmieści...
    Ustaw ClearTimerOnCompare na tę wartość przy Prescaler =1

    Kalkulator wbudowany w Windows nie gryzie.
  • #6 18955159
    Bluzman
    Poziom 4  
    trol.six napisał:
    Jeżeli nie używasz przerwań to ich nie włączasz. Wprawdzie nie włączasz głównego, ale włączasz od timera (TIMSK1), dlaczego?

    Wzór z dokumentacji dla CTC:
    F = Fclk / (2 * N * (1+OCR1A)) = 16000 / ( 2 * 8 * 2000 ) = 16000 / 32000 = 0.5Hz

    Sterowanie pinem OC1A dla CTC:
    .


    Atmega88 ma zegar max 8MHz, dlaczego liczysz dla 16MHz? Wyłączyłem TIMSK więc sterowanie jest przez wartość OCR1A.
    Znam ten wzór, co wnosi wyliczenie 0,5Hz? Powinno wyglądać raczej tak:
    8 000 000 / (2 * 8 * 2000) = 250
    więc OCR1A ma mieć wartość 249? To nic nie daje, próbowałem

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 18955249
    Bluzman
    Poziom 4  
    Tak czy inaczej mam ustawione i używam z zewnętrznego 8MHz obecnie
    Posiadam niestety stary sprzęt pomiarowy jak analogowy oscyloskop + generator, może nie być jakoś wiarygodny ale prostokąt 2000Hz generuje. Robię tak żeby wiedzieć jak wygląda i porównać z sygnałem od kontrolera. Tu niestety nie generuje się nic lub jakieś "głupoty" nie do odczytania w żaden sposób.
    Nie mam na wzór żeby przeanalizować tak prostego kodu, "liczenia" na przerwaniach jeszcze nie ogarniam zbyt dobrze, nie wychodzą mi takie rzeczy prawidłowo ale to już btw. Obecnie wolałbym wygenerować prawidłowo i wiedzieć na przyszłość jak robić to co przedstawiłem.
  • #9 18959577
    Konto nie istnieje
    Poziom 1  
  • #10 18961756
    Bluzman
    Poziom 4  
    Źle napisałem o tym zewnętrznym taktowaniu, wprowadziłem w błąd. Nie używam zewnętrznego kwarcu. Ale to już nie ważne. Udało mi się zrobić to co chciałem osiągnąć, to było tylko po to żeby zmierzyć czy generuje się prawidłowa częstotliwość.

    Teraz trochę inna kwestia. Chcę zrobić zewnętrzne przerwanie, które reaguje na wciśnięcie przycisku i wtedy dopiero ma się uruchomić w nim generowanie tych 2kHz (działa tylko przy wciśniętym switchu, więc reaguje na stan wysoki a nie zbocza). Dokładnie ten sygnał ma wchodzić do nadajnika radiowego 433Mhz, to idzie do odbiornika i na innej płytce uruchamia silnik. Częstotliwość jest obecnie generowana non-stop, tak jak kolega wspomniał nie potrzebne są przerwania.
    Tylko jak teraz do tego napisać w/w przerwanie zewnętrzne? Umieścić w nim całą konfigurację dla CTC, która jest zawarta pomiędzy 'int main (void)' a 'while(1)':

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #11 18964122
    Konto nie istnieje
    Poziom 1  
REKLAMA