Forum: Mikrocontroller und Digitale Elektronik Fragen zum tutorial: AVR - Die genaue Sekunde / RTC


von Dirk (Gast)


Lesenswert?

Hallo,

hab mir heute nochmal, den Code von peter Dannegger und den 
Verbesserungsvorschlag zu Gemüte genommen.

link: AVR - Die genaue Sekunde / RTC

Bei dem Erstgenannten, sehe ich soweit durch, bis auf folgendes.
1
define DEBOUNCE  256L    // debounce clock (256Hz = 4msec)

Wofür steht das L ? Ich hab immer gedacht, dass  aus DEBOUNCE long 
signed int wird und somit 4byte groß ist. Passt aber irgendwie zu der 
Erklärung im Tutorial nicht:

"Der Softwareteiler wird mit 256 gewählt, d.h. 256 Timerinterrupts pro 
Sekunde, und kann somit nur mit einem einzigen Byte realisiert werden."

1. 256 -> ist doch 2byte groß (9 bit), also kann ich es doch nicht mit 
einem einzigen byte realisieren
1
prescaler = (uchar)DEBOUNCE;

2. Wird bei dem cast, nur die unteren 8 bits verwendet und der rest 
abgeschnitten?

3.
Dann zudem Verbesserungsvorschlag:
1
 if( --prescaler == 0 ){ 
2
    prescaler = (uchar) DEBOUNCE;
3
    second++;      // exact one second over  
4
  }  
5
#if XTAL % DEBOUNCE
6
  if (prescaler <= XTAL % DEBOUNCE) {
7
    OCR1A += XTAL / DEBOUNCE +1;   /* um 1 Takt längere Periode um 
8
              den Rest abzutragen */
9
  } else {
10
#endif
11
    OCR1A += XTAL / DEBOUNCE;   /* kurze Periode */
12
#if XTAL % DEBOUNCE    
13
  }
14
#endif
15
}

Die Zeilen kann ich nicht nachvollziehen, wie der rest bei der 
Geschichte gleichmäßig abgetragen werden soll.
1
if (prescaler <= XTAL % DEBOUNCE) {
2
    OCR1A += XTAL / DEBOUNCE +1;   /* um 1 Takt längere Periode um 
3
              den Rest abzutragen */

xtal = 11059008 debounce = 256

11059008 / 256 = 43199,25 -> Bedingung wird immer ausgeführt, wenn der 
prescaler <= 25 ist -> d.h. dass das Vergleichsregister OCR1A für die 
nächsten Timer Interrupts( 25 noch) mit OCR1A = 43199  + 43199  + 1 
geladen. Der Wert ist doch viel zu hoch? Wie soll ich den auf den rest 
von 64 / s kommen? Ich weiß einfach nicht, wo hier der Denkfehler ist.

Gruß und Dank

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dirk wrote:
> Hallo,
>
> hab mir heute nochmal, den Code von peter Dannegger und den
> Verbesserungsvorschlag zu Gemüte genommen.
>
> link: AVR - Die genaue Sekunde / RTC
>
> Bei dem Erstgenannten, sehe ich soweit durch, bis auf folgendes.
>
>
1
define DEBOUNCE  256L    // debounce clock (256Hz = 4msec)
>
> Wofür steht das L ? Ich hab immer gedacht, dass  aus DEBOUNCE long
> signed int wird und somit 4byte groß ist.

An der Stelle soll dem C-Präprozessor mitgeteilt werden, dass an allen 
Stellen bei denen er mit DEBOUNCE rechnet, mit der Präzission LONG 
gerechnet werden soll. Das soll Ungenauigkeiten aufgrund von 
Überlaufffehlern verhindern.

> Passt aber irgendwie zu der
> Erklärung im Tutorial nicht:
>
> "Der Softwareteiler wird mit 256 gewählt, d.h. 256 Timerinterrupts pro
> Sekunde, und kann somit nur mit einem einzigen Byte realisiert werden."
>
> 1. 256 -> ist doch 2byte groß (9 bit), also kann ich es doch nicht mit
> einem einzigen byte realisieren
>
>
1
prescaler = (uchar)DEBOUNCE;
>

Es fehlt der Datentyp von prescaler, aber an der Stelle wird vermutlich 
eine Variable prescaler angelegt. Hier reicht für 256 Stufen tatsächlich 
ein Byte. ein Byte kann die Werte 0 bis 255 aufnehmen, d.h. 256 Stufen. 
Wenn man hier 256 speichert, wird durch den Überlauf eine 0 gespeichert, 
also die erste Stufe.

> 2. Wird bei dem cast, nur die unteren 8 bits verwendet und der rest
> abgeschnitten?
>

Ja.

von Dirk (Gast)


Lesenswert?

Danke für die Antwort.

prescaler wird vorher vom Typ uchar angelegt und somit deckt sich das 
mit deiner Aussage.

Hast du vielleicht noch eine Idee für den Verbesserungsvorschlag?

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
Noch kein Account? Hier anmelden.