Używanie wielu zewnętrznych przerwań w PIC

9

Korzystałem PIC16F877( arkusz danych ) do kilku projektów. W przypadku pojedynczych przerwań zmiany zewnętrznego pinu można użyć PORTB0przerwania. Ale teraz muszę obsługiwać 8 niezależnych zewnętrznych przerwań zmiany pinów w jednym obwodzie.

W arkuszu danych jest napisanych, że jest 15 przerwań PIC16F877, ale myślę, że są one liczone, w tym przerwania nadmiaru czasu itp., Które w tym przypadku są bezużyteczne.

Tak mówi arkusz danych o INTCONrejestrze.

wprowadź opis zdjęcia tutaj

Czy mogę mieć 4 niezależne przerwań używając bit0, RBIF? Reprezentuje zmianę w PB7:PB4. Jak mogę zidentyfikować, który pin został zmieniony, czy jest to odczytane przez wartość portu w procedurze przerwania?

Nawet jeśli mam pozytywne odpowiedzi na powyższe pytania, potrzebuję 8 przerwań? oczywiście nadal mogę używać INTEdo PORTB0zmian. Potem 4 + 1 = 5, ale co innego 3? (Ponieważ jednak wszystkie 8 zdarzeń przerwania są tego samego typu, 4 + 1 + 3 = 8sprawa wydaje się brzydka, prawda?)

Od mikrokontrolera nie oczekuje się żadnych innych ciężkich zadań poza monitorowaniem 8 styków. (Mówiąc o innych zadaniach, będzie musiał zachować zestaw oddzielnych zmiennych licznika i często przesyłać około 4 bajtów do komputera szeregowo)

Wszelkie sugestie są mile widziane. Nawet jeśli chodzi o zmianę mikrokontrolera na bardziej odpowiedni (ale nie mów mi, żebym odszedł od PICs).

Codenamed SC
źródło
2
Bez użycia przerwań możesz monitorować styki w programie głównym. Ale to nie jest idealne. Alternatywnie możesz wybrać Arduino. Chociaż nie jest to PIC, jest dość prosty, łatwo to zrozumiesz, ponieważ znasz już PIC.
Anubis,
1
Jeśli użyjesz przerwania RBIE, możesz po prostu buforować poprzednią wartość za każdym razem i XOR, aby znaleźć zmiany. Powinno być dość szybkie do wykonania.
PeterJ
@PeterJ Nie do końca to zrozumiałem. Bufor, która wartość?
Codenamed SC
@PeterJ świetnie! czekam ...
Codenamed SC
1
Jednym ze sposobów jest użycie zewnętrznej bramki 8-wejściowej (takiej jak dawniej 74LS30), aby połączyć sygnały zewnętrzne w jeden pin przerwania. Ponieważ 74 (HC) 30 jest bramką NAND, potrzebne byłyby wszystkie wejścia wysoko w stanie spoczynku - musiałyby one również być podłączone do pinów portu, aby można było zidentyfikować, które przerwania były aktywne, czytając port.
Brian Drummond,

Odpowiedzi:

3

To pseudo-kod C wyjaśniający jeden pomysł. Wykorzystuje i wyłączne OR, aby ustalić, które piny się zmieniły i wywoła różne procedury obsługi w ramach jednego przerwania RBIE. W zależności od tego, jak krytyczna jest ta aplikacja, możesz chcieć sprawdzić, jak PIC radzi sobie z sytuacjami takimi jak zmiana portu podczas wykonywania przerwania, aby upewnić się, że nie przegapisz żadnych zdarzeń.

int old_port_b;

void isr_handler()
{
    int new_port_b, changed_pins;
    new_port_b = read_port_b();
    changed_pins = new_port_b ^ old_port_b;
    if (changed_pins | 1)
        rb0_hander();
    if (changed_pins | 2)
        rb1_hander();
        // ... etc
    old_port_b = new_port_b;
}

int main()
{
    old_port_b = read_port_b();
    enable_interrupt();
}
PeterJ
źródło
Rozumiem, dzięki! ale nie takiej odpowiedzi szukam. W ten sposób możesz monitorować RB7:RB4tylko 4 piny. Ale proszę o sposób monitorowania 8 pinów. jakieś sugestie?
Codenamed SC
Myślę, że istnieje powód, dla którego nie możesz użyć RB0 - RB7, dla którego powyższe powinno działać? W przeciwnym razie nie mogę wymyślić żadnego sposobu, jeśli szybkie uruchomienie kodu nie jest konieczne, możesz użyć powyższego stylu kodu w przerwaniu timera (lub tylko w głównej pętli).
PeterJ
W przypadku tego PIC, jeśli potrzebujesz do tego celu przerwań, można zastosować sztuczkę XOR na RB4: RB7 i cztery przerwań dla RB0: RB3. Jeśli nie potrzebujesz przerwania, po prostu odpytaj cały port w swoim kodzie lub skorzystaj z przerwania timera, aby obsłużyć odpytywanie, jeśli potrzebujesz dużej częstotliwości próbkowania
Scott Seidman
and four interrupts for the RB0:RB3? PIC16F877 nie obsługuje żadnych przerwań RB1:RB3, co?
Codenamed SC
Brakowało mi tego w arkuszu danych, zakładałem, że obejmuje on cały port. Ale widziałem twój drugi komentarz raz na sekundę, więc myślę, że lepiej byłoby po prostu uruchomić to w głównej pętli. W przypadku przerwań musisz zadbać o aktualizację zmiennych w dowolnym momencie podczas wykonywania i jak obsługiwać zmiany pinów podczas działania przerwania. To naprawdę brzmi, jakby to skomplikowało, bez żadnego prawdziwego zysku. Jedynym wyjątkiem, o którym mogłem pomyśleć, jest to, czy chcesz używać funkcji budzenia ze snu podczas przerwania, w którym to przypadku musisz je sprzętowo wyposażyć w MUX.
PeterJ
1

Ta część ma tylko 4 przerwań zmiany pinów i kilka innych, które możesz ustawić na wybranych krawędziach. Jedną strategią byłoby wykrycie zmiany wartości 8 bitów zewnętrznie, a następnie przerwanie niedopasowania. Robi się bałagan w sprzęcie, ale robi dokładnie to, czego chcesz.

Ważnymi parametrami, których nie podałeś, jest to, jak szybko musisz zareagować na zmianę PIN, i jaki minimalny czas będzie trwał, aby zmiana PIN była ważna. W zależności od odpowiedzi możesz sondować na podstawie regularnych przerw w oprogramowaniu układowym. 16F877 może działać z częstotliwością instrukcji 5 MHz, a sprawdzenie zmiany zajmie tylko kilka instrukcji. Załóżmy, że ustawiasz przerwanie co 50 instrukcji. To pozostawia dużą część czasu procesora kodowi pierwszego planu. Szybkość przerwań wynosiłaby 100 kHz, a okres 10 µs. Oczywiście kod na pierwszym planie nadal musi widzieć flagę zmiany i coś z tym zrobić, więc czas odpowiedzi będzie dłuższy niż 10 µs, ale nie powiedziałeś nic o tym, co musisz zrobić, gdy wykryta zostanie zmiana. Jeśli to musi zareagować w czasie ludzkim,

Olin Lathrop
źródło
Przepraszamy za brakujące dane. Ponieważ oczekiwany wskaźnik odpowiedzi once per secondbędzie wystarczający. Gdy zostanie wykryta zmiana szpilki (tylko jedna krawędź, powiedzmy rosnące), należy zwiększyć licznik (zmienny). W głównej pętli musi monitorować wartości liczników, a gdy ktoś przekroczy pewną wartość, należy przesłać cztery bajty USARTdo komputera. Następnie zresetuj odpowiednią wartość licznika do zera. Proste. Myślę, że opcja odpytywania pójdzie dobrze, prawda?
Codenamed SC
2
Raz na sekundę ! Więc po co to wszystko boli z powodu przerwań? Można to łatwo zrobić okresowo z odpytywaniem. W czym zatem problem?
Olin Lathrop
hmm ... i myślę, że będzie najlepiej, ponieważ jest ich 8, a także nie można przewidzieć odpowiedzi (ale można przyjąć, że ta wartość jest minimalna). Hej! ludzie mogą popełniać błędy, prawda .. :(
Codenamed SC
1

Możesz użyć 8-wejściowej bramki NAND, o której wspomniał @Brian Drummond, aby podnieść przerwanie na pinie INT, a także podłączyć źródła przerwań do 8-bitowego rejestru przesunięcia równoległego / szeregowego, np. „74HC165N”, więc wtedy będziesz potrzebować aby po prostu odczytać dane z tego Rejestru Przesunięcia po podniesieniu przerwania, a to dostarczy informacji o twoim faktycznym źródle przerwań ... to może nie być najszybszy sposób, ale łatwy do rozszerzenia i użyje nie więcej niż 5 pinów, i jeśli dodasz system kontroli adresu (MUX, LATCH, ...), wtedy będziesz potrzebować tylko jednej sosny do powiadomienia o przerwaniu, a inne piny mogą być ponownie użyte w różnym czasie dla różnych zasobów;)

Eli Oulman
źródło