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

Timer0 AVR 16MHz: Przerwanie zamiast 1us trwa 2-4x dłużej, jak to naprawić?

nasiono 01 Lut 2012 22:47 1927 9
  • #1 10482242
    nasiono
    Poziom 17  
    Posty: 355
    Pomógł: 1
    Ocena: 4
    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  
    Posty: 1510
    Pomógł: 231
    Ocena: 398
    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  
    Posty: 355
    Pomógł: 1
    Ocena: 4
    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  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    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  
    Posty: 1510
    Pomógł: 231
    Ocena: 398
    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  
    Posty: 355
    Pomógł: 1
    Ocena: 4
    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  
    Posty: 355
    Pomógł: 1
    Ocena: 4
    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  
    Posty: 355
    Pomógł: 1
    Ocena: 4
    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.

Podsumowanie tematu

✨ Użytkownik zgłosił problem z timerem 0 w procesorze AVR pracującym na 16 MHz, gdzie przerwanie od przepełnienia trwało 2-4 razy dłużej niż oczekiwane 1 µs. Odpowiedzi wskazują, że przyczyną jest czas obsługi przerwania, który przekracza 1 µs z powodu instrukcji skoku i powrotu, a także konieczności zapisu rejestrów na stosie. Użytkownik planował używać przerwania do pomiaru czasu między impulsami, jednak zauważył, że przy preskalerze 8 minimalny czas wynosi 0,5 µs, a maksymalny 128 µs. Zasugerowano użycie funkcji "input capture" do dokładniejszego pomiaru, ale użytkownik musiał dostosować swoje podejście, aby programowo odejmować nadmiarowy czas w obsłudze przerwania.
Wygenerowane przez model językowy.
REKLAMA