MCP 23S08 Interrupts "sammeln" möglich?

OP #2975807
Lesenswert?

Hallo,

ich verwende einen MCP 23S08 als IO Extender. Alle Pins sind als Input 
mit Pull-Up konfiguriert. Lesen und Scheiben klappt auch soweit prima.

Folgendes Problem: Ich möchte gern periodisch die Pins erfragen, die 
seit dem letzten Abfragen eine Änderung erfahren haben. Das Data Sheet 
klingt so als sollte das mit eingeschalteten Interrupts gehen (S. 18):

> INTF will always reflect the pin(s) that have an interrupt
> condition. For example, one pin causes an interrupt to
> occur and is captured in INTCAP and INF. If before clearing
> the interrupt another pin changes, which would normally
> cause an interrupt, it will be reflected in INTF, but not
> INTCAP.

Ich sehe aber in dem Register immer nur den ersten Pin, der sich 
geändert hat. Alle weiteren Änderungen gehen verloren, es sei denn, sie 
passieren exakt gleichzeitig.

Geht das, was ich da vorhabe, oder muss ich tatsächlich die Interrupts 
behandeln, wenn sie ausgelöst werden (was ich aktuell nicht tue)?

Danke & Grüße
Jörg
(Firma: Promaxx.net) #2976389
Lesenswert?

Das ist wirklich ein Problem.
Du wirst mit dem INTCAP-Register keine Freude haben.
Du mußt, wenn ein INT gemeldet wird, einfach das PORT-Register auslesen 
und per XOR mit einer Schattenkopie im uC vergleichen, welche Bits 
geändert wurden, und die dann abarbeiten.

Tipp:
Du solltest das PORT-Register nicht erneut abfragen, um eine 
Schattenkopie zu erzeugen, weil dann schon wieder eine Änderung passiert 
sein kann, sondern durch geschickte Nutzung des XOR-Befehls kannst Du 
eine neue Schattenkopie errechnen, die du dann zum Vergleich speicherst.

Evtl. dann noch von INT-Abfrage auf zyklisches Polling wechseln.

Ich glaube auch nicht, daß eine sofortige INT-Behandlung alle Änderungen 
erfassen würde...
OP #2976956
Lesenswert?

Hallo Bernd,

erstmal vielen Dank für die Antwort! So richtig verstehe ich es aber 
nicht.

Wie es aussieht, bin ich gezwungen, den Interrupt direkt zu behandeln 
(was ich eigentlich aus verschiedenen Gründen vermeiden wollte). 
Anderenfalls sehe ich zusätzliche geänderte Bits nicht. Der Text im 
Datenblatt scheint mir schlicht falsch zu sein. Im Datenblatt des 
nächstgrößeren Bausteins 23S17 taucht er übrigens nicht auf.

Polling würde halbwegs funktionieren, wenn ich es mit sehr hoher 
Frequenz durchführe, aber das kann ich nicht garantieren. Macht auch 
wenig Sinn, da es den µC unnötig beschäftigt hält und dann keine 
Rechenleistung für andere Sachen mehr verbleibt.

In meinem Anwendungsfall hängen an den Eingängen des Extenders übrigens 
mechanische Schalter, d.h. das Timing ist nicht ganz so kritisch. Ich 
interessiere mich nur dafür, welche der Leitungen seit der letzten 
Abfrage (die x Sekunden her sein kann) mindestens einmal auf Masse 
gezogen wurden. Ich hatte nach dem Lesen des Datenblatts gehofft, dass 
mir der Extender diese Pufferung liefert. Schade eigentlich.

Viele Grüße & einen guten Rutsch!
Jörg
OP #2977416
Lesenswert?

Hallo Peter,

Peter Dannegger schrieb:
> Joerg Pleumann schrieb:
>> In meinem Anwendungsfall hängen an den Eingängen des Extenders übrigens
>> mechanische Schalter
>
> Also schnarchlangsame Signale, da ist Pollen im Timerinterrupt die
> übliche Methode.
> Und das Entprellen macht der Timerinterrupt bequemer Weise gleich mit.
> Ich würde 10ms Timerinterrupt einstellen, da langweilt sich der MC immer
> noch sehr.

Leider hat der µC noch ein paar andere (wichtigere) Sachen zu tun, so 
dass ich ihn nicht auf diese Weise beschäftigen wollte. Ich habe aber 
jetzt eine andere Lösung gefunden. Mein eigentliches Problem war, dass 
ich nur noch eine Interrupt-fähige Leitung frei habe, aber potentiell 
mehrere I/O-Extender anschließen wollte - ohne extra Logikbausteine 
dazwischenhängen zu müssen. Ich bin eben eher zufällig im Datenblatt 
darauf gestoßen, dass ich die Interrupt-Leitungen auf Open Drain stellen 
und dann einfach zusammenhängen kann. Hab's mit zwei Extendern probiert. 
Klappt prima. Problem gelöst. Wieder was gelernt.

Danke für Eure Antworten, guten Rutsch!

Grüße,
Jörg
#2977494
Lesenswert?

Joerg Pleumann schrieb:
> Leider hat der µC noch ein paar andere (wichtigere) Sachen zu tun, so
> dass ich ihn nicht auf diese Weise beschäftigen wollte.

Nein!
Du beschäftigst ihn damit nicht, sondern langweilst ihn.

Mal angenommen, Deine super-duper wichtigen Sachen lasten die CPU zu 90% 
aus.
Nun kommt noch ein Timerinterrupt mit 0,1% hinzu, macht zusammen 90,1%.
Ob nun 90% oder 90,1% CPU-Last, das macht keinen Unterschied.


Peter
OP #2977641
Lesenswert?

Peter Dannegger schrieb:
> Joerg Pleumann schrieb:
>> Leider hat der µC noch ein paar andere (wichtigere) Sachen zu tun, so
>> dass ich ihn nicht auf diese Weise beschäftigen wollte.
>
> Nein!
> Du beschäftigst ihn damit nicht, sondern langweilst ihn.
>
> Mal angenommen, Deine super-duper wichtigen Sachen lasten die CPU zu 90%
> aus.
> Nun kommt noch ein Timerinterrupt mit 0,1% hinzu, macht zusammen 90,1%.
> Ob nun 90% oder 90,1% CPU-Last, das macht keinen Unterschied.

Wahrscheinlich hast Du recht. Aber die Lösung mit Interrupt-on-Change 
ist aus meiner Sicht trotzdem eleganter, weil sie die Anzahl der 
Interrupts auf das Notwendige reduziert.

Frohes Neues!
Jörg
(Firma: Promaxx.net) #2979632
Lesenswert?

Hallo,
ich arbeite hier mit dem 23S17 und habe nach dem Studium dieser ganzen 
IOC-Geschichte meine Software etwas umgestellt.
Ein Tastendruck erzeugt einen Interrupt (der in Int-Routine entprellt 
wird) an dem Extender, den die CPU in der Hauptroutine abfragt und die 
Tasten pollt. Dann wird quasi jedes Bit (8 Tasten) einzeln auf Änderung 
getestet...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren