Skocz do zawartości

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


Pomocna odpowiedź

Napisano

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

}

}

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.

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

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

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

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.

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.

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.

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

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

 } 

} 
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<

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