Skocz do zawartości

[C] [Attiny13]Niedziałające przerwanie PCINT


alex_o

Pomocna odpowiedź

Witam,
Chce uruchomić przerwanie PCINT0, z tego, co zrozumiałem, z datasheeta to muszę ustawić odpowiedni bit w rejestrze PCMSK, bit PCIE w GIMSK. Nie znalazłem żadnej konfiguracji przerwań PCINT, ale z tego, co wyczytałem to one działają tylko na zmianę stanu na odpowiednim pinie. Do pinu z PCINT0 podłączyłem przycisk zwierany do masy. Jednak, gdy go wciskam nie wchodzi mi do przerwania.

#include <avr/io.h> //dołączenie podstawowej biblioteki
#include <avr/interrupt.h> //dołączenie biblioteki z przerwaniami

ISR(PCINT0_vect)
{
PORTB |= (1<<PB3); 
}

int main(void)
{

GIMSK |= (1<<PCIE); // wlaczenie przerwania INT0 i PCINT 
PCMSK |= (PCINT0); //PCINT
DDRB = 0x1E; // PB0 jako wyjscie
PORTB |= (1<<PB0);
GIFR |=(1<<PCIF);
sei(); // wlaczenie obslugi przerwan


while(1)
{

}

}

Link do komentarza
Share on other sites

Nie robiłem nic na ATtiny13, ale patrząc na Twój post chyba nieco pomieszałeś PCINT4 i PCINT0.

W opisie piszesz o PCINT4, a w programie ustawiasz PCINT0 w rej. PCMSK, PB0 ustawiasz jako wejście w DDRB oraz włączasz pull-up na PB0.

Ale PCINT4 jest na PB4 a nie PB0, przez co opis w poście nie odpowiada programowi.

Link do komentarza
Share on other sites

Przepraszam, w opisie popełniłem błąd chodziło mi o PCINT0. Wcześniej próbowałem robić na PCINT4, ale gdy pisałem

ISR(PCINT4_vect) 

to kompilator pokazywał mi

warning: 'PCINT4_vect' appears to be a misspelled signal handler
Link do komentarza
Share on other sites

Zaglądnij do tabelki z wektorami przerwań w datasheet ATtiny13. Zauważysz, że nie ma osobnych wektorów przerwań dla poszczególnych PCINTx.

Table 9-1. Reset and Interrupt Vectors

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

Czyli jest tylko jeden wektor ten PCINT0 i on się odnosi do wszystkich przerwań wywoływanych przez któryś z pinów PCINT0..5? Więc jeśli używam tego właśnie wektora to przerwanie powinno się wywoływać przy zmianie stanu ale tak się nie dzieje.

Czytałem wcześniej temat w którym komuś też nie działały te przerwania i pomogło mu użycie wektora PCINT_vect, jednak on pracował na ATtiny2313 jak dobrze pamiętam. A gdy użyje zamiast PCINT0_vect, użyje wektora PCINT_vect to kompilator pokazuje mi tego warringa warning: 'PCINT_vect' appears to be a misspelled signal handler

Link do komentarza
Share on other sites

Tutaj masz zbiór wektorów dla poszczególnych mikrokontrolerów:

http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

Dla ATtiny13 jest tylko PCINT0_vect, co jest zgodne z tabelką którą podałem w poście wyżej.

Jak już pisałem wcześniej nie używałem ATtiny13, a w tym momencie nie mam czasu zaglądnąć do datasheet. Spróbuj poczytać dokładnie jeszcze raz. Jeśli nie dasz rady, to wieczorem zerknę do datasheet.

Link do komentarza
Share on other sites

Bo przerwania od pinów czyli PCINT, są przerwaniami o specjalnych właściwościach. TZn, z tego co pamiętam jeszcze z AVRów, to każdy port wyposażony w PCINT, ma własny wektor przerwań. I teraz stwierdzenie od którego pinu na danym porcie nastąpiło przerwanie, jest narzucone na program obsługi przerwania, który musi w odpowiednim rejestrze sprawdzić który pin zgłosił przerwanie, poczym wyzerować programowo, taką maskę/flagę przerwania w tym rejestrze.

Link do komentarza
Share on other sites

Jak już pisałem wcześniej nie używałem ATtiny13, a w tym momencie nie mam czasu zaglądnąć do datasheet. Spróbuj poczytać dokładnie jeszcze raz. Jeśli nie dasz rady, to wieczorem zerknę do datasheet.

Spróbowałem jeszcze raz poszukać jakiś informacji w datasheet, jednak nie znalazłem nic więcej. Będę wdzięczny jeśli dałbyś radę zerknąć.

Bo przerwania od pinów czyli PCINT, są przerwaniami o specjalnych właściwościach. TZn, z tego co pamiętam jeszcze z AVRów, to każdy port wyposażony w PCINT, ma własny wektor przerwań.

Wiem o tym już to wcześniej wyczytałem

I teraz stwierdzenie od którego pinu na danym porcie nastąpiło przerwanie, jest narzucone na program obsługi przerwania, który musi w odpowiednim rejestrze sprawdzić który pin zgłosił przerwanie, poczym wyzerować programowo, taką maskę/flagę przerwania w tym rejestrze.

Ale ja nie potrzebuje sprawdzać(przynajmniej na razie) na którym pinie zostało zgłoszone przerwanie bo powinno zostać ono zgłoszone na PB0.

Link do komentarza
Share on other sites

Ale ja nie potrzebuje sprawdzać(przynajmniej na razie) na którym pinie zostało zgłoszone przerwanie bo powinno zostać ono zgłoszone na PB0.

Tak ale w procedurze obsługi przerwania, musisz wyzerować na samym końcu i tak odpowiednią flagę.

Link do komentarza
Share on other sites

Sprawdź ten program - pisałem bez sprawdzania poprawności.

program nie uwzględnia drgań styków przycisku, więc może być losowo zapalany LED na PB3.

#include <avr/io.h> //dołączenie podstawowej biblioteki 
#include <avr/interrupt.h> //dołączenie biblioteki z przerwaniami 

ISR(PCINT0_vect) 
{ 
   PORTB ^=  (1<<PB3);  //zmień stan LED na przeciwny - to pewniejsza metoda ocserwacji
} 

int main(void) 
{ 

 DDRB = (1<<PB3); // PB3 jako wyjście (LED), PB0 jako wejście 

 PORTB |= (1<<PB0); //włącz pull-up na PB0 - tutaj przycisk

 //ustawiamy przerwanie
 PCMSK |= (1<<PCINT0); // wlaczenie przerwania PCINT0
 GIMSK |= (1<<PCIE); //włącz przerwania PCINTx

 sei(); // wlaczenie obslugi przerwan 


while(1) 
{ 

 } 

} 
Link do komentarza
Share on other sites

Ale ja nie potrzebuje sprawdzać(przynajmniej na razie) na którym pinie zostało zgłoszone przerwanie bo powinno zostać ono zgłoszone na PB0.

Tak ale w procedurze obsługi przerwania, musisz wyzerować na samym końcu i tak odpowiednią flagę.

No tak, jednak najpierw musi mi wejść do niego. Co niechce się dziać 🙁

Sprawdź ten program - pisałem bez sprawdzania poprawności.

program nie uwzględnia drgań styków przycisku, więc może być losowo zapalany LED na PB3.

#include <avr/io.h> //dołączenie podstawowej biblioteki 
#include <avr/interrupt.h> //dołączenie biblioteki z przerwaniami 

ISR(PCINT0_vect) 
{ 
   PORTB ^=  (1<<PB3);  //zmień stan LED na przeciwny - to pewniejsza metoda ocserwacji
} 

int main(void) 
{ 

 DDRB = (1<<PB3); // PB3 jako wyjście (LED), PB0 jako wejście 

 PORTB |= (1<<PB0); //włącz pull-up na PB0 - tutaj przycisk

 //ustawiamy przerwanie
 PCMSK |= (PCINT0); // wlaczenie przerwania PCINT0
 GIMSK |= (1<<PCIE); //włącz przerwania PCINTx

 sei(); // wlaczenie obslugi przerwan 


while(1) 
{ 

 } 

} 

Niestety, ten kod też nie chce działać.

// Problem rozwiązany w kodzie był drobny błąd

// Napisałem PCMSK |= (PCINT0); a powinno być PCMSK |= (1<

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.