externer Interrupt, 16Bit Counter

Gast #699515
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.
Angehängte Dateien:
#699531
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...
Gast #699537
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.
#699546
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).
#699573
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...

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