mikrocontroller.net

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


Autor: Sebastian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: sechsnullfuenf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.