Ich möchte Impulse (je ca. 20-50ms) zählen. Impulsgeber sind mehrere Geräte (8), die unabhängig voneinander ihre Impulse abgeben, also auch mal parallel oder sehr kurz voneinander versetzt. Meine Idee war es, z.B. an den Ports 1.1 bis 1.7 die Impulse zu empfangen und über Interrupt zu erfassen. Der Interrupt für den Port 1 wird aber für den gesamten Port, also alle 8 Leitungen abgerufen. Wenn also an Port 1 ein Impuls eintrifft, wird er aufgerufen. Die einzelnen Pins müßte ich dann in der Interruptroutine abfragen. Dann zähle ich aber mitunter Signale doppelt, da ich nicht weiß welcher Port den Interrupt ausgelöst hat. Hat jemand eine Lösung?
Rene schrieb: > Meine Idee war es, z.B. an den Ports 1.1 bis 1.7 die Impulse zu > empfangen und über Interrupt zu erfassen. > Der Interrupt für den Port 1 wird aber für den gesamten Port, also alle > 8 Leitungen abgerufen. Wenn also an Port 1 ein Impuls eintrifft, wird er > aufgerufen. Die einzelnen Pins müßte ich dann in der Interruptroutine > abfragen. Dann zähle ich aber mitunter Signale doppelt, da ich nicht > weiß welcher Port den Interrupt ausgelöst hat. > Hat jemand eine Lösung? Zum einen erhebt sich die Frage, warum das unbedingt Interrupts sein müssen. 20-50ms sind für einen µC eine lange Zeit. Das würde auch mit Polling (also regelmässigem Nachsehen) genauso gut gehen. Zum anderen: Na du kannst ja vergleichen, wie der Zustand des Portes beim letzten Interrupt war. Du merkst dir einfach den kompletten Portzustand und beim nächsten Interrupt vergleichst du mit dem dann vorliegenden Portzustand. Alle Bits die verändert sind, zeigen an, dass sich da was getan hat. Und dann merkst du dir genau diesen Portzustand für den wiedrrum nächsten Aufruf der ISR. Du musst natürlich ALLE Flanken am Port mitkriegen, nicht nur die steigenden Flanken. (Hinweis: die XOR Operation kann man in so einem Fall tadellos einsetzen) -> d.h. dein Interrupt bringt dir im Grunde jetzt gar nichts mehr, sofern dein Restprogramm nicht trödelt. Denn um das vergleichen mit dem vorhergehenden Portzustand kommst du eh nicht rum. Und das kannst du genausogut in der Hauptschleife auch machen.
Ich möchte die Anzahl der gezählten Impulse pro PIN extern kommunizieren. Ob ich den MSP430 dazu abfrage, oder dieser in definierten Zeitabständen die Anzahl übermittelt ist noch offen. Die Idee des merken des Zustands ist fraglich, da die Impulse auch mal 5 Minuten nicht auftreten. Kommt also nur an P1.1 ein Signal hintereinander, dann sehe ich das im Interrupt nicht durch eine Zustandsänderung - beim Polling ja. Insofern gebe ich dir recht.
Rene schrieb: > Die Idee des merken des Zustands ist fraglich Nö. Die ist nicht fraglich. Das ist die Art und Weise, wie man das macht. > da die Impulse auch mal 5 > Minuten nicht auftreten. Und? > Kommt also nur an P1.1 ein Signal > hintereinander, dann sehe ich das im Interrupt nicht durch eine > Zustandsänderung Natürlich siehst du es. Du musst auf ALLE Flanken den Interrupt reagieren lassen, nicht nur die steigenden! Bei JEDER Änderung an dein Eingangspins (von 0 auf 1, von 1 auf 0) muss dein Interrupt ausgelöst werden. Und der Rest ist einfach nur ein Bytevergleich auf Bitebene
1 | uint8_t oldState; |
2 | |
3 | |
4 | ISR( .... ) |
5 | {
|
6 | uint8_t newState = kompletter Port einlesen; |
7 | |
8 | uint8_t changed = newState ^ oldState; |
9 | |
10 | // in changed ist an allen Bitpositionen eine 1, an der sich
|
11 | // der jetzige Zustand vom Port (newState) vom vorhergehenden
|
12 | // Zustand (oldState) unterscheidet
|
13 | |
14 | // durch Untersuchung der Bits in changed, zusammen mit der
|
15 | // Information in newState kann man feststellen, ob und welcher
|
16 | // Pin gerade seinen Wechsel von 0 auf 1 gemacht hat
|
17 | |
18 | if( (changed & 0x01) && (newState & 0x01) ) |
19 | // Pin 0 hat von 0 auf 1 gewechselt
|
20 | |
21 | if( (changed & 0x02) && (newState & 0x02) ) |
22 | // Pin 1 hat von 0 auf 1 gewechselt
|
23 | |
24 | if( (changed & 0x04) && (newState & 0x04) ) |
25 | // Pin 2 hat von 0 auf 1 gewechsel
|
26 | |
27 | ....
|
28 | |
29 | |
30 | oldState = newState; |
31 | }
|
@KHB Was ist los, du gibst die Lösung vor? Wie sol er jetzt was lernen? ;-)
Es gibt auch das P1IFG Register. Darin wird ein Bit fuer den Pin gesetzt, der den Interrupt ausgeloest hat. Das Bit sollte per SW in der ISR zurueckgesetzt werden. Gruss Josef
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.