Skocz do zawartości

Obsługa przerwań ATmega8/16/32


ciscoc

Pomocna odpowiedź

Witam, Panowie

potrzebuję pomocy w wytłumaczeniu roli przerwań ponieważ czytam już któryś raz i nie mogę tego zrozumieć.

Może ktoś z was posiada jakieś przykłady?

Przerwanie kojarzy mi się z zakończeniem działania programu i koniec nic więcej, a jaka jest rola tych rejestrów GICR itp. poprostu nie rozumie.

Niżej zamieszczam program który staram się zrozumieć ale nie wychodzi mi:

#include

#include

ISR(INT0_vect)

{

PORTA |= _BV(PA0); // zapal diodę LED

}

ISR(INT1_vect)

{

PORTA &= ~_BV(PA0); // zgaś diodę LED

}

int main() // program główny

{

DDRA |= _BV(DDRA0); // pina 0 portu A jako wyjście

GIMSK |= _BV(INT0)|_BV(INT1); // włączenie obsługi przerwań INT0 i INT1

MCUCR |= _BV(ISC11)|_BV(ISC10) | _BV(ISC01)|_BV(ISC00);

// włącz generowanie przerwań przez narastające zbocze na INT0 i INT1

sei(); // włącz globalną obsługę przerwań

while(1); // pętla nieskończona

return 0;

}

Link do komentarza
Share on other sites

Moje propozycje:

1. czytaj datasheet,
2. szukaj w google,
3. albo kup książkę i rusz do przodu nie tracąc czasu.

To nie jest forum gdzie uczymy od całkowitych podstaw (takie przynajmniej są założenia).

PS.

A w przyszłości wklejaj kod w znacznikach CODE.

Link do komentarza
Share on other sites

Witam.

Przerwania służą do asynchronicznego obsłużenia konkretnego zadania.

Asynchroniczne rozumię, że może zdarzyć się w dowolnym miejscu programu i zawsze będzie od razu obsłużone. (To "od razu" to dla czepialskich skrót myślowy).

Generalnie chodzi o to, żeby program który realizuje swoje zadanie przerwał je w momencie informacji o wystąpieniu przerwania, wykonał zadanie które przerwało pracę programu, a następnie wrócił do swojego wcześniejszego zadania.

Jeżeli w pętli głównej programu mamy np 10 zadań to niezależnie przy którym wystąpi przerwanie program po obsłużeniu przerwania wróci dalej do tego samego zadania, które musiał przerwać.

A co do programu:

Program w pierwszej części konfiguruje i inicjuje przerwanie

a w dalszej nie robi nic - siedzi w pustej pętli while.

Jeżeli zostanie zgłoszone przerwanie INT0 lub INT1 to zostaną wykonane odpowiednie funkcje ISR czyli zapalenie lub zgaszenie diody.

Żądanie przerwania generowane jest przez pojawienie się zbocza narastającego na pinie INT0 lub INT1 - patrz nota katalogowa.

Jeżeli podłączysz do tych pinów switche to jednym będziesz załączał LEDa a drugim będziesz wyłączał go.

Jaśniej chyba się już nie da 😉

Pozdrawiam

Zuk

Link do komentarza
Share on other sites

Oprócz tego co napisał Zuk, przerwania mogą być wywoływane przez różne czynniki. Wewnętrznie (np. przez timery) bądź zewnętrznie (przez stan lub jakieś zbocze na odpowiednim wyjściu). W przypadku Twojego kodu są to przerwania zewnętrzne za pomocą pinów INT0 i INT2.

Rejestr GIMSK służy do ustawienia, które wejścia (mogą być również wyjścia, wtedy przerwania te można inicjować programowo) będą obsługiwane przez przerwania. W przypadku AtMegi8 masz to w DataSheet na stronie 49.

Rejestr MCUCR ustawiasz czy przerwanie to ma być wywołane zboczem narastającym, opadającym, stanem niskim czy wysokim na pinie INT0-1. (str.66 dokumentacji)

Funkcja sei(); ustawia 7 bit w rejestrze SREG (str. 11 dokumentacji), zezwala globalnie na wszystkie przerwania, bez tego przerwania są wyłączone.

W przypadku wystąpienia przerwania od np. INT0 zostanie wykonane to co znajduje się wewnątrz funkcji ISR(INT0_vect). A po wykonaniu wszystkich instrukcji powróci do wykonywania programu tam gdzie go przerwał - tak jak Zuk już napisał🙂

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dziękuję Panowie za odpowiedź,

wieczorem postaram się zamieścić kod programu którego nie rozumiem.

A chciałbym abyście konkretnie na jego przykładzie się wypowiedzieli.

[ Dodano: 10-04-2012, 20:23 ]

Oto kod programu zaczerpnięty z książki jak w załączniku ( );

A tu link do schematu ( )

#include

#include

int8_t licznik=0;

ISR (INTO_vect)

{

licznik=10;

}

ISR (TIMER1_OVF_vect)

{

if (licznik>0)

{

PORTC^=0x01;

licznik--;

}

else

PORTC&= ~(_BV(PC0));

}

ISR (BADISR_vect) {}

int main (void)

{

DDRC|=_BV(PC0);

PORTC&=~(_BV(PC0));

GICR|=_BV(INT0);

MCUCR|=_BV(ISC01);

DDRD&=~(_BV(PD2));

PORTD|=_BV(PD2);

TCCR1B|=_BV(CS11);

TIMSK|=_BV(TOIE1);

sei();

for (;😉

return 0;

}

Byłbym wdzięczny za omówienie tego programu linika po linice.

Link do komentarza
Share on other sites

1. Umieszczej kod w znacznikach

2. Jeżeli używasz w funkcji obsługi przerwania zmiennej, musi być ona zadeklarowana jako volatile,
czyli w twoim przypadku: volatile int8_t licznik=0;

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.