mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 1 second time-base peter dannegger


Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe mir nun einmal den Code von peter Dannegger angeschaut,
welcher eine präzise 1-Sekunden Zeitbasis darstellt.

Nur habe ich dazu einige Fragen:

1.)Der Codeabschnitt:


#define XTAL    11059008L  // after measuring deviation: 1.5s/d

#define DEBOUNCE  256L

#if XTAL % DEBOUNCE
                // compare (DEBOUNCE - 1) times
      OCR1A = XTAL / DEBOUNCE - 1;
#endif

Da verstehe ich folgendes nicht ganz. "%" an sich ist ja eine Modulo
Operator.

Das beudeutet der Ausdruck "XTAL % DEBOUNCE" ist ungleich Null,
sofern bei der Division von XTAL durch DEBOUNCE ein Rest bleibt,
richtig? (und das wird immer der Fall sein, es sei denn XTAL und
DEBOUNCE sind gleich groß)

SO...nun zu den Fragen:
1.)Wieso überhaupt diese Division, oder anders gefragt, wozu ist dieser
Prescaler gut?

2.)Was genau macht die Zeile:

OCR1A = XTAL / DEBOUNCE - 1;    // compare (DEBOUNCE - 1) times

Also warum wird (DEBOUNCE - 1)  mal verglichen? Und was wird
verglichen?

Falls jemand so freundlich sein könnte , mir auf die Sprünge zu
helfen,ich seh da absolut nicht durch ;-)

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.:

Ich nehme an, der prescaler von 256 hat etwas damit zu tun, dass das
Timerregister ein 8 Bit Register( von 0- 255) ist?!

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Hast du mal für ein paar Werte die Division ausgerechnet?
Der Prescaler ist auf die Genauigkeit bezogen. Darauf geht Peter in
mehrern Threads ein.
Übrigens ändert sich die 256 eher selten. Die Quarzfrequnez ändert
sich.
(Der Rest einer Divison ist immer dann gleich Null, wenn der Dividend
ein ganzes Vielfaches des Divisors ist: 10 % 5 = 0, 20 % 5 = 0, 21 % 5
= 1...

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2. die -1 kommt vom CTC-Modus des Timers: Der Timer braucht einen
Taktzyklus, um modifiziert zu werden.

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ok, aber die ganze ISR sieht ja so aus:

SIGNAL (TIMER1_COMPA_vect)
{

  #if XTAL % DEBOUNCE
      OCR1A = XTAL / DEBOUNCE - 1;
  #endif

    if( --prescaler == 0 )
    {
        prescaler = (uchar)DEBOUNCE;
        second++;    // exact one second over

  #if XTAL % DEBOUNCE
       OCR1A = XTAL / DEBOUNCE + XTAL % DEBOUNCE - 1;
  #endif
    }
}

Machdem der Rest ja Präprozessor Anweisungen sind, besteht das
eigentlich "Programm" aus dem Code

if( --prescaler == 0 )
    {
        prescaler = (uchar)DEBOUNCE;
        second++;    // exact one second over
        }

Das Hauptprogramm startet bei einem Timerwert von 0, zählt dann rauf
bis zu
OCR1A = XTAL / DEBOUNCE - 1;

Dann wird in die ISR gesprungen, der prescaler um 1 dekrementiert und
geprüft, ob dieser bereits 0 ist. Dann ist eine Sekunde vergangen, weil
ja schon 256 mal der COMPARE MATCH ausgelöst wurde...

Nur, das XTAL / DEBOUNCE -1 beschäftigt mich trotzdem...
Dass der Timer einen Takt zum modifizieren braucht leuchtete ein, nur
durch das "-1" bewirkt doch lediglich, dass dieser Takt "nicht
mitgezählt" wird.... Aber die Zeit ist ja trotzdem verstrichen....?!!

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du durch 3 teilen willst, zählt der Timer 0, 1, 2, 0 usw., d.h. Du
mußt mit 2 vergleichen, damit danach wieder die 0 kommt, und 2=3-1.


Peter

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhm, ok.

Stimmt es dann also, dass ich den Prescaler "DEBOUNCE" frei wählen
kann?

Ich stelle mir das nun so vor:

Je kleiner der DEBOUNCE Wert --> desto größer ist der Wert, der ins
Register OCR1A geladen wird --> es passiert weniger of ein Compare
Match --> Weniger ISR Aufrufe.
Dafür wird aber auch schon nach einer geringeren Anzahl von Interrupts
die Sekunde weitergezählt.

Im Endeffekt sollte aufgrund der zusätzlichen Korrektur mit

OCR1A = XTAL / DEBOUNCE + XTAL % DEBOUNCE - 1;

also DEBOUNCE jeden beliebigen Wert annehmen können.

Ein DEBOUNCE Wert von 256 wurde also lediglich gewählt, um mit den 4ms
nebenbei eine praktische Zeitbasis für eine Tastenentprellroutine zu
haben?

Ist das so richtig?

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit anderen Worten:

Das "-1" im Ausdruck

 OCR1A = XTAL / DEBOUNCE - 1;

ist vorhanden, weil der Timer bei jedem Überlauf bei "0" zu zählen
beginnt und dabei bereits ein Takt vergeht.

Soll der Timer also z.B.: bis 10 zählen und man würde den Wert "10"
ins OCR1A Register schreiben, dann würde der Timer bei jedem Durchlauf
eigentlich bis "11" zählen, weil

0,1,2,3,4,5,6,7,8,9,10,0,1,2,3,4,5,6,7,8,9,10

Daher müsste ich in diesem Falle wohl "9" ins Register schreiben.

Damit wäre das "-1" erklärt, aber was hat es dann mit dem angeblich
zusätzlich benötigten Timertakt zum Nachladen des Wertes des Timers im
CTC Mode auf sich? Davon hab ich im Datenblatt nichts gelesen...

Danke!

Gruß..Mark

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.