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 ;-)
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?!
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...
2. die -1 kommt vom CTC-Modus des Timers: Der Timer braucht einen Taktzyklus, um modifiziert zu werden.
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....?!!
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
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?
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.