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

Timer0 przerwanie zamiast 1us jest ~3

nasiono 01 Lut 2012 22:47 1804 9
  • #1 10482242
    nasiono
    Poziom 17  
    Witam.
    Chciałem otrzymać przerwanie od przepełnienia generowane przez timer0 procesor pracuje na 16mhz jednak mam dziwny problem.
    Mianowicie zamiast planowego 1us mam 2-4 x większe wartości.
    Napisałem taki program testowy który ma zobrazować efekt czyli co sekundę instrumentować zmienną.

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


    Zarówno debugger jak i fizyczny układ pokazują ewidentne opóźnienie.
  • #2 10482317
    JarekC
    Poziom 32  
    Witam,

    Przyczyna jest bardzo prosta.
    Sama obsługa przerwania zajmuje więcej niż 1us.
    Zauważ, że 1us to tylko 16 taktów zegar, już same rozkazy skoku do przerwania (JMP) i powrotu (RETI) zajmują 7 taktów. A gdzie czas na odłożenie rejestrów na stosie i samą obsługę przerwania.

    Poza tym jaki jest sens przerwania co 1us aby w nim tylko zliczać do 1 sek.?

    Pozdrawiam
    JarekC
  • #3 10482338
    nasiono
    Poziom 17  
    Program jest przykładowy docelowo ma liczyć opóźnienie miedzy impulsami na poziomie pojedynczych "us".
    Gdy w ciele przerwania nie ma nic poza inicjalizowaniem rejestru nadal trwa to za długo a to już jest dziwne.

    ISR(TIMER0_OVF_vect)
    {
    TCNT0 = 240;
    };
  • #4 10482540
    janbernat
    Poziom 38  
    Policz instrukcje prologu i epilogu wejścia w przerwanie.
    Zwróć uwagę ktore z nich są wykonywane w jednym cyklu zegarowym a które w kilku cyklach.
    Nawet jak w przerwaniu nic nie będziesz robił to wejście i wyjście z przerwania zajmie jakiś czas.
  • #5 10483013
    JarekC
    Poziom 32  
    Na szybko wykonana kompilacja i wynikowy kod obsługi przerwania gdzie tylko jest ustawiany licznik.
    Obsługa przerwania zajmuje 24 takty+ 4 na wywołanie czyli razem 28 taktów.
    Więc się nie dziw.

    Opisz co potrzebujesz uzyskać, bo to co wymyśliłeś raczej się nie sprawdzi.

    Pozdrawiam
    JarekC

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #6 10483100
    nasiono
    Poziom 17  
    Macie racje. Od dłuższego czasu siedzę na nieco szybszych procesorach tam to wszystko inaczej sie załatwia.
    A co do tego co potrzebuje uzyskać to moim celem jest zrobienie licznika który mierzy odstęp czasu pomiędzy 2 impulsami wahający się od 1us do 1s.
    Myślałem że zrobię licznik który przy każdym przepełnieniu będzie inkrementował jakies zmienne wtedy mógł bym je wykorzystac w pętli do odmierzania i innych rzeczy.
  • #7 10483901
    Konto nie istnieje
    Konto nie istnieje  
  • #8 10483930
    nasiono
    Poziom 17  
    Tylko jest tego rodzaju problem iż atmega taktowana zegarem 16mhz przy preskalerze 8 i 8 bitowym liczniku minimalny czas jest w porządku (0,5us) maksymalny natomiast 128us więc dalej musze inkrementowac w przepełnieniu zmienną . Dodatkowo z tego co widze input capture przypisany jest tylko do timera1 ja go używam do innych celów (2 kanałowy pwm).
    Poradziłem sobie w taki sposób ze w funkcji przerwania od przepełnienia timera 0
    programowo odejmuje naddatek czasu.
    Pozdrawiam
  • #9 10484077
    Konto nie istnieje
    Konto nie istnieje  
  • #10 10484104
    nasiono
    Poziom 17  
    Zdaje sobie sprawę że powinno się dobierać procesor do zastosowania ale czasem trzeba się dostosować.
    Co do inkrementowania to nie wyraziłem się jasno chodzi oto ze zegar tyka co 0,5 s i gdy stan licznika startuje od 11 to gdy się przepełni 79999 razy mam prawie idealną sekunde dzięki temu w obsłudze przerwania zewnętrznego wystarczy odczytać stan licznika TCNT0 i zmiennej od przepełnień i mam dokładny czas.
REKLAMA