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

ATMEGA8A-PU - Timer2 / CTC / organizacja pracy programu

stachu03 07 Lip 2015 09:36 756 2
REKLAMA
  • #1 14829654
    stachu03
    Poziom 13  
    Cześć.

    Mój problem dotyczy Atmegi8 i obsługi Timera2 w trybie CTC.
    Poniżej przedstawie napisany kod i problem który próbuję rozwiązać od pewnego czasu.

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


    A teraz obliczenia:
    Taktowanie procesowa 1MHz, preskaler 8 daje 125kHZ co przekłada się na czas impulsu równy 0,000008s .
    Ustawiając OCR2 na 200 nasze przerwanie będzie wykonywać się co 0,0016s co daje 625 przerwań na sekundę

    Problem w tym, że najprawdopodobniej bardzo rzadko spełniają się warunki porównujące wartości liczników w ifach czyli odswiez_wyswietlacz==312 itd. Twierdzę tak, ponieważ gdy warunek zmienię na odswiez_wyswietlacz>312 to wyświetlacz się odświeża.

    Co robię nie tak, że nie mogę uchwycić momentu w którym licznik ma konkretną wartość?

    Pytanie drugie.
    Czy możecie mi poradzić, jak zaprogramować mikrokontroler, aby z wykorzystaniem timera2 tak zorganizować program aby np. wyświetlacz odświeżał się co 0,5s, pomiar robił się co 2s, stan wejść binarnych był sprawdzany co 1s.

    Czy należy to robić właśnie w taki sposób, że w przerwaniu inkrementuje/dekrementuje kilka liczników od wartości których uzależniam wykonanie poszczgólnych części programu?

    Czy powinienem zastosować inne podejście ?
  • REKLAMA
  • #3 14829994
    tmf
    VIP Zasłużony dla elektroda
    stachu03 napisał:

    A teraz obliczenia:
    Taktowanie procesowa 1MHz, preskaler 8 daje 125kHZ co przekłada się na czas impulsu równy 0,000008s .
    Ustawiając OCR2 na 200 nasze przerwanie będzie wykonywać się co 0,0016s co daje 625 przerwań na sekundę

    Problem w tym, że najprawdopodobniej bardzo rzadko spełniają się warunki porównujące wartości liczników w ifach czyli odswiez_wyswietlacz==312 itd. Twierdzę tak, ponieważ gdy warunek zmienię na odswiez_wyswietlacz>312 to wyświetlacz się odświeża.

    Co robię nie tak, że nie mogę uchwycić momentu w którym licznik ma konkretną wartość?

    Pytanie drugie.
    Czy możecie mi poradzić, jak zaprogramować mikrokontroler, aby z wykorzystaniem timera2 tak zorganizować program aby np. wyświetlacz odświeżał się co 0,5s, pomiar robił się co 2s, stan wejść binarnych był sprawdzany co 1s.

    Czy należy to robić właśnie w taki sposób, że w przerwaniu inkrementuje/dekrementuje kilka liczników od wartości których uzależniam wykonanie poszczgólnych części programu?

    Czy powinienem zastosować inne podejście ?


    Robisz kilka rzeczy nie tak. Po pierwsze jeśli zmienna jest typu volatile int, to na 8 bitowym MCU dostęp do niej nie będzie atomowy - trzeba więc tą atomowość zapewnić. Dlaczego? Zastanów się co się stanie jeśli przerwanie wypadnie pomiędzy instrukcjami sprawdzającymi stan zmiennej...
    Druga sprawa - operator == dla jakiegokolwiek licznika jest ryzykowny. Jeśli pętla trwa dłużej niż okres pomiędzy zmianami stanu porównywanej zmiennej, to będziesz gubił pewne stany. I kicha. Trzeba to rozwiązać np. stosując operator >= i <= lub samo >= plus dodatkowa flaga inforumująca, że sekwencja już się wykonała. Jeszcze lepiej - ustawić timer żeby generował przerwanie co określony czas i z tego przerwania wywoływać odpowiednią funkcję. To przy okazji może być też odpowiedź na twoje kolejne pytanie.
    Inna możliwość (stwarzająca mniej potencjalnych problemów) to osobna flaga, ustawiana w przerwaniu po upływie określonego czasu - sprawdzasz ją w main i wywołujesz funkcję, po czym zerujesz flagę, która się znowu ustawi po upływie określonego czasu. Kilka flag - kilka różnych czasów. To tylko niektóre pomysły jak rozwiązać twój problem.
REKLAMA