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

Atmega328P - Jak zatrzymać właściwie Timer 2 w trybie CTC

windu83 24 Lut 2015 10:02 1935 7
REKLAMA
  • #1 14471686
    windu83
    Poziom 10  
    Witam panowie.

    Zagadka jest taka. Jest sobie arduino uno, ale programuję je bez bootloadera, bezpośrednio w c w avr studio wersja 4. W pewnym momencie w programie startuję timer 2 w trybie CTC i używam go jako wyjście zegarowe dla bufora. Timer 2 ma ustwienia prescalera na 1 i rejestru porównawczego na 7, co daje ze wzoru przy częstotliwości uC 16Mhz, na wyjściu 1 Mhz i do tej pory wszystko działa pięknie, ale gdy w pewnym momencie chcę zatrzymać timer zerując zwyczajowo prescaler to owszem timer zostaje zatrzymany i sygnał zegarowy przestaje być generowany, ale co gorsze to procesor się zawiesza! i program zostaje zatrzymany. Czy ktoś pomoże mi zatrzymać ten pędzący pociąg, bo sprawdziłem, że przy ustawieniu mniejszej częstotliwości(zwiększeniu prescalera) udaje się zatrzymać timer, ale przy 1 Mhz nie działa ta sztuczka.

    Kod do kompilacji

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 14471775
    Andrzej__S
    Poziom 28  
    windu83 napisał:
    Timer 2 ma ustwienia prescalera na 1 i rejestru porównawczego na 7

    Zacznijmy od tego: timer w trybie CTC, preskaler 1, OCR2A=7, czyli przerwanie co 8 taktów zegara, a ile taktów trwa procedura obsługi tego przerwania?
    Samo wejście i wyjście z procedury zajmuje więcej czasu.
  • REKLAMA
  • #3 14471798
    windu83
    Poziom 10  
    Ok, zgoda. Pomijając przerwanie, pomińmy je. po wystartowaniu timera dajmy sobie opóźnienie 100 ms żeby się rozbujał i po tym spróbujmy go zatrzymać, nie używając w ogóle przerwania, przerwanie jest nie istotne
  • REKLAMA
  • #4 14471833
    Andrzej__S
    Poziom 28  
    Próbowałeś testowo wyłączyć przerwania komentując TIMSK2 = (1 << OCIE2A); oraz while(data_ok == 0);?
    Wtedy też nie działa?

    EDIT:
    Ewentualnie spróbuj zwiększać wartość OCR2A (od 50 do 100), bez zmiany preskalera.
  • #5 14472417
    windu83
    Poziom 10  
    tak oraz tak
  • #6 14472627
    dondu
    Moderator na urlopie...
    Zatrzymywanie timera poprzez wyzerowanie preskalera to normalny sposób jego wyłączenia określony w dokumentacji :)

    windu83 napisał:
    Ok, zgoda. Pomijając przerwanie, pomińmy je.

    To je pomiń w programie, a nie teoretycznych rozważaniach.
    Innymi słowy kol. Andrzej__S pokazał Ci gdzie masz podstawowy problem.

    Zmień więc koncepcję i dopiero gdy ona nie będzie dziać poprawnie możemy zobaczyć dlaczego.
  • REKLAMA
  • #7 14473231
    Andrzej__S
    Poziom 28  
    Pierwsze co mi się rzuciło w oczy, to fakt, że gubisz większość przerwań timera, więc chyba nie można powiedzieć:
    windu83 napisał:
    do tej pory wszystko działa pięknie

    Być może nie jest to przyczyna tego, że program przestaje działać, ale na pewno nie "działa pięknie".

    windu83 napisał:
    owszem timer zostaje zatrzymany i sygnał zegarowy przestaje być generowany

    windu83 napisał:
    przy ustawieniu mniejszej częstotliwości(zwiększeniu prescalera) udaje się zatrzymać timer, ale przy 1 Mhz nie działa ta sztuczka

    No więc jak to właściwie jest. Skoro "sygnał zegarowy przestaje być generowany", to znaczy, że timer jest zatrzymany, czyli instrukcja TCCR2B = 0x00; została wykonana. Po czym wnioskujesz, że "przy 1 Mhz nie działa ta sztuczka"?

    Nie sądzę, żeby fakt nieodebrania znaku poprzez USART był jakoś związany z zatrzymaniem lub niezatrzymaniem timera. Zapewne nie posiadasz debugera sprzętowego, ale sprawdzenie, dokąd dochodzi program można zrealizować prościej, np. poprzez ustawienie stanu wysokiego na jakimś wolnym pinie. To pewniejsze rozwiązanie. No a po wysłaniu znaku masz pustą pętlę nieskończoną i wyłączone taktowanie timera, więc nie zostanie wywołane żadne przerwanie, a co za tym idzie program przestanie się wykonywać, a raczej jego wykonywanie się przestanie być zauważalne.

    Proponuję zmienić sposób sprawdzenia miejsca, do którego dochodzi wykonywanie programu i wstawić coś do pętli głównej, choćby miganie diodą, żeby dokładniej sprawdzić, czy i kiedy mikrokontroler się "zawiesił".
  • #8 14474340
    windu83
    Poziom 10  
    Dziękuję serdecznie za podpowiedzi koledzy. Debugowanie własnie u mnie odbywa się przez uarta, ale portem też sprawdzę dla pewności. Generalnie to po ten operacji zatrzymania timera zostaje wykonana masa innych zadań, jednak kod przyciąłem dla czytelności. Dodam że program działał dopóki nie oddałem tej obsługi przerwania, więc do reszty kodu nie mogę się czepić. Nie pamiętam czy sprawdzałem to jeszcze z wyłączonym przerwaniem, więc muszę to jeszcze raz sprawdzić. Pamięć mam dobrą, ale krótką.
REKLAMA