www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega16 ICP


Autor: Bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sers Leute,
ich programmiere in C mit Codevision. Der ATMega läuft mit 16MHz.
Nun möchte ich den ICP nutzen, indem ich bei fallender Flanke den
Zähler rücksetze und auf steigende Flanke umstelle (TCCR1B=0xC1). Kommt
die steigende Flanke, wird der ICR-Register ausgelesen und gespeichert
(ICRH zuerstm, dann low), dann wieder auf fallende Flanke umgestellt
(TCCR1B=0x81).
Wenn ich nun zum Test einen Low-Pegel von 90µs anlege, so müsste ich im
ICR-Register so nen ungefähren Wert von 1440 haben. Mein tatsächlicher
(gemessener) Wert ist jedoch viel niedriger (so ca.190).
Die Ausgabe (ans Termianl) findet in einem anderen Timer statt.
Lediglich habe ich noch eine Kontrollfunktion in dieser ICP-ISR
eingebaut, indem ich einen PIN für die Dauer der ISR auf 1 setze. Somit
kann ich am OSZI beobachten, ob die ISR überhaupt durchlaufen wird. ->
Ja sie wird.
Meine Frage:
Wieso habe ich so eine große Differenz zwischen theoretischem und
gemessenen ICR Wert?

Autor: Olaf K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wird der ICR-Register ausgelesen und gespeichert (ICRH zuerstm, dann
low)

Datenblatt S.90: "... For a 16-bit read, the Low byte must be read
before the High byte."

Den ICP-Interrupt würde ich übrigens nicht dazu nutzen, den Timer
rückzustellen, denn dadurch geht der Vorteil der Clockgenauigkeit
verloren. Wann genau der ICP-Interrupt abgearbeitet (und damit der
Timer rückgestellt) wird, hängt von vielen Faktoren ab, z.B. ob gerade
ein anderer Int bearbeitet wird oder zeitweilig ein cli gesetzt wurde,
oder ob der ICP-Int gerade während eines Multi-Cycle-Befehls auftrat
(z.B. JMPs oder Branches), oder vielleicht auch vom Sleep-Modus.

Der ICP-Wert wird dagegen zusammen mit dem ICP-Flag genau bei der
betreffenden Flanke (bzw. mit Noise Canceler ein paar Takte später)
gespeichert, und wann man ihn dann per Interrupt abholt und
weiterbearbeitet, ist nebensächlich.

Normalerweise speichert man den ersten ICP-Wert (z.B. den bei fallender
Flanke) ab, läßt den Timer weiterlaufen bis zur steigenden Flanke (= 2.
ICP-Wert) und subtrahiert den 1. vom 2. Wert, das geht auch über die
$FFFF-Grenze hinaus (in asm sind das nur 2 Befehle, in C dürfte es mit
unsigned int gehen).
Überläufe erkennt man mittels Compare-Match-Interrupt, d.h. beim ersten
ICP-Int wird der Counter ausgelesen und direkt als Compare-Wert
gespeichert (bei Nutzung des Prescalers vorher was abziehen, sonst wird
der Comp-Int sofort ausgelöst).

MfG Olaf

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.