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


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();
}

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,


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.