mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frequenzmessung mit ATMega16


Autor: Karlheinz Druschel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leuts,

folgendes:
Ich habe hier einen ATMega16 auf dem STK500 und zwei externe Signale, A
und B. Diese Signale können 3 Zustände haben: 0V, 5V oder
Rechteckimpulse mit ca. 4 Hz. Ich muss alle drei Zustände auswerten.
Nun dachte ich, ich könnte mir mit externen Interrupts helfen, deshalb
habe ich die Signale auf INT0 und INT1 verdrahtet.
Variante 1: Für eine bestimmte Zeit (beispielsweise 600 ms) zähle ich
die Flankenwechsel
Variante 2: Ich zähle die Zeit zwischen den Flankenwechseln.
Nun gehts aber schon generell beim Timing los: Ich habe mir also eine
Timer-Overflow-Routine geschrieben, die alle 5 ms aufgerufen wird. Zur
Kontrolle toggel ich bei jedem Aufruf PORTA.0. Lt. Oszi klappt das,
auch wenn die Werte für TCNT0 nicht nachberechnen kann.
Nun möchte ich für rund 600 ms messen, bei einem Aufruf alle 5 ms muss
ich also nur bis 120 zaehlen, dann sind 600 ms um. Stimmt aber nicht,
das Signal verschleift irgendwie total. D.h. wenn ich bei einem
Zählerstand von 120 ein Pin toggle, dann sind die 1 und 0 Zeiten
unterschiedlich lang, und einen Zusammenhang mit 120 kann ich nirgendwo
entdecken. Also habe ich wohl ein grundlegendes Problem mit den Timern.
Oder ?

Greets
Karlheinz

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das Signal mit 4Hz frequenzstabil oder variiert die auch noch?
Ohne einen Blick auf deinen Quellcode würde ich folgendes
vorschlagen:
Bei jedem externen Interrupt einen Timer so zurücksetzen, dass er nach
125-150ms (eine Periodenhälfte) überläuft.
Bei konstantem Pegel auf der Leitung kommt es zum Überlauf.
In der INT0-ISR würde ich eine LED setzen, die den Flankenwechsel
anzeigt.
In der Timer-Überlauf-ISR würde ich diese LED dann löschen, und dafür
pegel-abhängig eine andere setzen. Insgesamt also 3 LEDs...

Bei mehr als einem Interrupt könnte man einen Timer verwenden, der
regelmässig (100µs oder so) ein Interrupt auslöst. In dessen ISR werden
dann für jeden Interrupt Variablen heruntergezählt, und bei 0 ein
Überlauf detektiert...

Auf dein Problem mit den Timer bin ich jetzt nicht eingegangen...
Hab die Fragestellung / das Problem wohl auch nicht ganz verstanden.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Das cli() und sei() in der ISR kannste Dir sparen, das passiert
automatisch!

Abgesehen davon hast Du den INT0 als Low-Level-sensitiv initialisiert.
Du  inkrementierst Dein nCounterA (wie ist das überhaupt
initialisiert??) ständig mit hoher Rate, so lange das TFlagA gesetzt
ist. Da kann dann kein sinnvoller Wert drinstehen!

Gruß

Johnny

Autor: Karlheinz Druschel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt,
jetzt klapperts.
1000 Dank

Greets
Karlheinz

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.