Forum: Mikrocontroller und Digitale Elektronik externer Interrupt, 16Bit Counter


von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

Moin,
ich hab folgendes Programm. Ich benutze den externen Interrupt um ein 
Pulsweitenmoduliertes-Signal auszuwerten, das Signal hat einen Frequenz 
von 1KHz und im Normal Zustand ein duty cycle von 50%, der Takt meines 
Controllers beträgt 3MHz. Ich benutze den 16Bit Counter zur Auswertung 
der Pulsbreite. Ich setze den Counter am Anfang des Pulses auf Null und 
lese ihn mit der nächsten Flanke aus und mit der darauf folgenden Flake 
lese ich ihn auch noch mal aus. Dann hab ich einmal die Zeit des 
Impulses und der Periode, mit den ich dann die Abweichung berechne. Der 
berechnete Wert wird dann über die Serielleschnittstelle an den Pc 
übertragen, der Wert besteht aus 2 Byte, anschließend übertrage ich ein 
Zeichen das Signalisiert das ein neues Delta übermittelt wird.(Programm 
im Anhang)
Ich hab nun folgendes Problem: Wenn ich die Timerauswertung mach wird 
nur noch Datenmüll übermittelt, das heißt, obwohl das Tastverhältnis 
gleichbleibt ändert sich der Wert, unzwar beträchtlich von 250 - 0 alles 
mal dabei. Die Serielleschnittstelle hab ich überprüft, übermittelte 
Zeichen werden auch empfangen. Das Signal am Interrupt ist störungsfrei. 
Falls einer einen Tip hat, bitte schreiben. Ich weiß nicht mehr weiter.

von sechsnullfuenf (Gast)


Lesenswert?

Unterbreche den Prozess. Bestimme einen freien Pin, und schiebe dort den 
gemessenen Wert seriell raus. Gleichzeitig senden eine Konstante (0x5A 
oder so) ueber die Schnittstelle.

von Johannes M. (johnny-m)


Lesenswert?

Warum machst Du das nicht mit Input Capture? Ist eigentlich die 
klassische Anwendung dafür...

Abgesehen davon solltest Du, wenn Du schon die Ausgabe mit gesperrten 
Interrupts machst, auch dafür sorgen, dass bei der Wiederfreigabe der 
Interrupts die dazugehörigen Flags gelöscht werden. Da Du das bisher 
nicht machst, wird vermutlich sofort nach dem sei() der Interrupt 
Handler ausgeführt. Und dass dann im TCNT1 unsinnige Werte stehen, ist 
hoffentlich klar...

von Sebastian (Gast)


Lesenswert?

Wenn ich in die Interruptroutine springe wird das Flag doch automatisch 
gelöscht, und wenn ich dann die Interrouptroutine verlasse und den 
Interrupt sperre, wird das Flag doch garnicht mehr gesetzt.

von Johannes M. (johnny-m)


Lesenswert?

Sebastian wrote:
> Wenn ich in die Interruptroutine springe wird das Flag doch automatisch
> gelöscht, und wenn ich dann die Interrouptroutine verlasse und den
> Interrupt sperre, wird das Flag doch garnicht mehr gesetzt.
Dann schau bitte mal ins Datenblatt! Mit cli() sperrst Du nur die 
Bearbeitung aller Interrupt-Ereignisse. Die Flags werden immer 
gesetzt, wenn das dazugehörige Ereignis auftritt, völlig unabhängig 
davon, ob der Interrupt lokal oder global gesperrt ist! Ansonsten wäre 
Polling nicht möglich. Und wenn Du mit sei() die Interrupt-Bearbeitung 
wieder freigibst, wird alles, was in der Zwischenzeit aufgelaufen ist, 
abgearbeitet (sofern nicht lokal gesperrt durch gelöschtes 
Interrupt-Enable).

von Sebastian (Gast)


Lesenswert?

Ach so, ja cool dann wird das sicherlich daran liegen, werde ich gleich 
mal ausprobieren. Danke schon mal dafür. Kannst du mir vielleicht noch 
mal grob erklären was Input Capture ist.

von Johannes M. (johnny-m)


Lesenswert?

Sebastian wrote:
> Ach so, ja cool dann wird das sicherlich daran liegen, werde ich gleich
> mal ausprobieren. Danke schon mal dafür. Kannst du mir vielleicht noch
> mal grob erklären was Input Capture ist.
Grob: Input Capture speichert bei einer Flanke (bei entsprechender 
Konfiguration wahlweise positiv, negativ oder beide) am Input 
Capture-Pin verzögerungsfrei den Inhalt des Timer-Zählregisters im 
Capture-Register. Ist vom Prinzip her ähnlich wie die Vorgehensweise mit 
externem Interrupt, hat aber gravierende Vorteile: Das Timer-Register 
wird automatisch gesichert, und zwar direkt beim Auftritt des 
Capture-Ereignisses und nicht erst im Interrupt Handler. Dadurch wird 
die Verzögerung vom Auftritt des Ereignisses bis zur Ausführung des 
Codes im Handler eliminiert, und man hat bis zum nächsten Capture Zeit, 
den Wert aus dem Capture-Register abzuholen und zu verarbeiten. I.d.R. 
setzt man bei der Verwendung von Capture auch nicht den Timer zurück 
(was die Genauigkeit wieder zunichte machen würde), sondern lässt ihn 
durchlaufen und subtrahiert einfach den ersten Wert vom zweiten...

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
Noch kein Account? Hier anmelden.