Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

atmega32 przerwania dwóch timerów

qudi 04 Lut 2011 01:48 1232 21
  • #1 04 Lut 2011 01:48
    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ź...

    0 21
  • #2 04 Lut 2011 03:14
    shg
    Specjalista techniki cyfrowej

    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ń.

    0
  • #3 04 Lut 2011 10:24
    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 ?

    0
  • #4 04 Lut 2011 10:28
    asembler
    Poziom 32  

    Oczywiście. Wystarczy na początku obsługi przerwania wstawić SEI();

    0
  • #5 04 Lut 2011 10:42
    qudi
    Poziom 15  

    na początku którego przerwania w opisanym przeze mnie problemie ? w przerwaniu A ?

    0
  • #6 04 Lut 2011 10:44
    asembler
    Poziom 32  

    Jezeli chcesz aby przerwanie B przerywało przerwanie A to na początku przerwania A.

    0
  • #7 04 Lut 2011 10:47
    qudi
    Poziom 15  

    dziwne to trochę, nigdy tego nie stosowałem - jak to najlepiej sprawdzić czy działa ?

    0
  • #8 04 Lut 2011 10:51
    asembler
    Poziom 32  

    qudi napisał:
    dziwne to trochę, nigdy tego nie stosowałem - jak to najlepiej sprawdzić czy działa ?

    Nie rozumiem w ogole.

    0
  • #9 04 Lut 2011 10:53
    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 ???

    0
  • Pomocny post
    #10 04 Lut 2011 11:02
    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 .

    0
  • #11 04 Lut 2011 11:05
    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(); ?

    0
  • #13 04 Lut 2011 12:28
    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 ?

    0
  • #14 04 Lut 2011 13:05
    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
    }

    0
  • #15 04 Lut 2011 15:40
    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?

    0
  • #16 04 Lut 2011 16:44
    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)

    0
  • Pomocny post
    #17 04 Lut 2011 18:04
    shg
    Specjalista techniki cyfrowej

    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):

    Code:
    ISR(INT0_vect, ISR_NOBLOCK)
    
    {
      jakiś kod
    }

    Dzięki temu sei() zostanie wywołane prędzej, niż zrobiłbyś to wewnątrz procedury sam.

    0
  • #18 04 Lut 2011 20:47
    janbernat
    Poziom 38  

    Radził bym pamiętać o stosie.
    kol. asembler programuje w asemblerze i wszystko ma pod kontrolą.

    0
  • #20 04 Lut 2011 21:49
    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.

    0
  • #21 04 Lut 2011 23:30
    qudi
    Poziom 15  

    a to jest w stanie nas od tego uchronić ?

    Code:
    ISR(TIMER0_COMP_vect, ISR_NOBLOCK) {
    

    }


    chyba też niebardzo...

    0
  • #22 05 Lut 2011 01:34
    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.

    0