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

atmega32 przerwania dwóch timerów

qudi 04 Lut 2011 01:48 1472 21
REKLAMA
  • #1 9100440
    qudi
    Poziom 15  
    Witam !!!
    Mam pytanie, dawno nie programowałem avr-ów i chciałbym sobie przypomnieć czy przerwanie timera1 może kolidować z przerwaniem timera0 ? Chyba mogą bo przerwanie "stopuje" cały program ale chciałbym się upewnić... proszę o odpowiedź...
  • REKLAMA
  • #2 9100493
    shg
    Poziom 35  
    Dwóch rdzeni to tam raczej nie masz, więc oczywiście że może.
    Są dwa warianty, albo drugie przerwanie zostanie przyblokowane na czas wykonywania pierwszego, albo pierwsze przerwanie zostanie przerwane przez drugie.
    Jeżeli wystąpią jednocześnie, to jako pierwsze zostanie wywołane to, które ma niższy adres w tablicy wektorów przerwań.
  • #3 9101047
    qudi
    Poziom 15  
    A - przerwanie A
    B - przerwanie B
    Czy można zrobić tak by kiedy wykonywane jest A a podczas jego wykonywania (np. w połowie) B domaga się wykonania to A zostaje przerwane natomiast B wykonuje się w pełni ?
  • REKLAMA
  • #4 9101064
    asembler
    Poziom 32  
    Oczywiście. Wystarczy na początku obsługi przerwania wstawić SEI();
  • #5 9101108
    qudi
    Poziom 15  
    na początku którego przerwania w opisanym przeze mnie problemie ? w przerwaniu A ?
  • #6 9101111
    asembler
    Poziom 32  
    Jezeli chcesz aby przerwanie B przerywało przerwanie A to na początku przerwania A.
  • #7 9101124
    qudi
    Poziom 15  
    dziwne to trochę, nigdy tego nie stosowałem - jak to najlepiej sprawdzić czy działa ?
  • REKLAMA
  • #8 9101133
    asembler
    Poziom 32  
    qudi napisał:
    dziwne to trochę, nigdy tego nie stosowałem - jak to najlepiej sprawdzić czy działa ?

    Nie rozumiem w ogole.
  • #9 9101143
    qudi
    Poziom 15  
    no chodzi mi o to czy to na pewno będzie działać... Interesuje mnie również czy po zakończonym wykonaniu przerwania B, program wróci do wykonania przerwania A ? Czy po prostu wyjdzie do głównej pętli programu ???
  • Pomocny post
    #10 9101174
    asembler
    Poziom 32  
    To bedzie działac tak jak piszesz. Program wróci do miejsca przerwania czyli po wykonaniu B do przerwania A a potem do programu głównego.
    Ja to stosuje w większosci programów bo to nawet konieczność np przy stosowaniu UART .
  • #11 9101185
    qudi
    Poziom 15  
    rzeczywiście to bardzo łatwy i przydatny sposób... bardzo dziękuje za pomoc... jeszcze tylko jedno z serii moich łopatologicznych pytań. Jeśli nie chce aby przerwanie B było przerwane przez inne to po prostu nie daje na początku SEI(); ?
  • REKLAMA
  • #13 9101526
    qudi
    Poziom 15  
    mam jeszcze jedno pytanie - co się stanie gdy będą trzy przerwania...
    A, B, C. Jak zrobić tak by A mogło być przerwane przez B,C natomiast B tylko przez C ? Czy to jest w ogóle możliwe na ATmega32 ?
  • #14 9101664
    asembler
    Poziom 32  
    Wszystko jest możliwe. Generalnie polega to odblokowywani i zablokowywaniu przerwań. A że akurat robisz to w innych przerwaniach to dla procesora nie ma znaczenia. Innymi słowy w przerwaniu B zanim odblokujesz ogólne przerwania SEI musisz zablokowac przerwanie od C, no i nie zapomniec na koncu przerwania b odblokować to przerwanie.Czyli:

    PrzerwanieB
    {
    zablokujC
    SEI
    ...
    ...
    ...
    ...
    ...
    CLI
    odblokujC
    }
  • #15 9102315
    qudi
    Poziom 15  
    no dobra ale jak zrealizować to "zablokuj C " oraz "odblokuj C" ? SEI zezwala na przerwania natomiast CLI nie zezwala(odwołuje SEI?) ? Po co właściwie użyłeś tego CLI na końcu?
  • #16 9102605
    asembler
    Poziom 32  
    CLI musiałem zastosować zeby do konca przerwania utrzymac warunek aby przerwanie C nie przerwało przerwaniaB a zdarzyłoby sie to w momencie wykonania "odblokujC"

    zablokujC,odblokujC realizuje sie za pomocą rejestrów specjalnych
    np dla timer0

    TIMSK&=~(1<<TOIE0)
    TIMSK|=(1<<TOIE0)
  • Pomocny post
    #17 9102974
    shg
    Poziom 35  
    Jeżeli piszesz w C i używasz avr-libc, to przerwania "nieblokujące" (takie które mogą być przerwane przez inne przerwanie (lub nawet same przez siebie, trzeba uważać)) deklaruje się tak (przykład dla INT0):
    ISR(INT0_vect, ISR_NOBLOCK)
    {
      jakiś kod
    }

    Dzięki temu sei() zostanie wywołane prędzej, niż zrobiłbyś to wewnątrz procedury sam.
  • #18 9103940
    janbernat
    Poziom 38  
    Radził bym pamiętać o stosie.
    kol. asembler programuje w asemblerze i wszystko ma pod kontrolą.
  • #19 9104159
    qudi
    Poziom 15  
    co masz na myśli ?
  • #20 9104333
    janbernat
    Poziom 38  
    To co napisał shg- trzeba uważać.
    Jeżeli pierwsze przerwanie odłoży na stos to co trzeba i drugie przerwanie wewnątrz pierwszego też odłoży na stos to co trzeba i z tego przerwania zostanie wywołane jeszcze raz pierwsze albo drugie- bo znów zostało wywołane- i znowu odłozy na stos to co trzeba- to stos może się przepełnić.
    To znaczy wejść w obszar pamięci wykorzystywanej przez program.
    A może to zrobić zaraz albo po kilku minutach, godzinach, miesiącach.
    Dlatego można- jak to robi asembler- ale trzeba dobrze znać zależności czasowe i asembler.
    Tzn. nie znać osobiście kol. asembler ale programowanie w asemblerze.
  • #22 9105287
    asembler
    Poziom 32  
    Czym ty sie martwisz M32 ma 2 kb ram to dasz na stos 1kB i w zyciu sie nie przepełni chyba że specjalnie napiszesz złe obsługi przerwania, ale to też trzeba umieć zrobic.
REKLAMA