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.
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.
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...
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.
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).
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.
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...