MSP430 parallele Impulszählung mehrere Ports

Gast #3179812
Lesenswert?

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?
#3179842
Lesenswert?

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.
Gast #3179964
Lesenswert?

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.
#3179984
Lesenswert?

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
}

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