Forum: Mikrocontroller und Digitale Elektronik Problem mit RTC beim ATxmega64D3 mit internen 32kHz Oscillator


von David R. (dave234)


Lesenswert?

Hallo zusammen,

ich habe hier einen ATxmega64D3 und möchte mit dem RTC möglichst genau 
einmal pro sekunde einen Interrupt auslösen.
Ich möchtre den internen 32,768kHz Oscillator verwenden.

Laut Datenblatt kann man entweder 1kHz Clk von der internen ULP,
oder 1024Hz vom internen 32,768kHz Oscillator mit prescaler,
oder direkt 32,768kHz benutzen.

Ich möchte gerne die 32,768kHz benutzen, damit ich mit dem richtigen 
Zählerwert für die Counter Periode auf möglichst genau 1s komme.

Ich konnte bei mir aber folgendes Verhalten beobachten:

benutze ich die 1kHz von der ULP muss ich die Zähler periode auf 
irgendwas um 1000 stellen damit der Interrupt ca. 1x pro sekunde kommt 
(viel zu ungenau).

Benutze ich die die 1,024kHz von dem 32,768kHz OSC muss ich die 
Zählerperiode auf 1022 stellen und bekomme einen intterupt alle 1,0001 
Sekunden. Das weicht auf dauer zu weit ab.

Benutze ich die 32,768kHz direkt müsste ja eigentlich theoretisch eine 
Zählerperiode von 32767 zu den gewünschten Ergebnis führen (und würde 
genügend spielraum bieten zur feinjustierung). Praktisch muss ich eine 
Zählerperiode von 944 einstellen und bekomme dann ca. 1s, ungenauer als 
mit 1,024kHz.

Ich habe stundenlang herumprobiert und Datenblätter gelesen. Vielleicht 
übersehe ich ja etwas.

Anbei meine Initialisierungsroutine.

Wäre Super wenn jemand eine Idee hat.

Grüße
David


1
void RCT_init(void)
2
{
3
 //OSC_CTRL |= 0b00000100;  // aktiviere 32,768kHz Oscillator
4
  OSC.CTRL |= OSC_RC32KEN_bm; 
5
6
while ((OSC.STATUS & (OSC_RC32KRDY_bm))==0)    //Warte bis Oscillator bereit
7
{
8
}
9
    
10
//CLK_RTCCTRL=0b00001100;
11
// CLK_RTCCTRL=0b00001100;
12
 CLK_RTCCTRL=0b00001101;
13
 //         110   RTC Clock Source 32,768kHz internal
14
//            1  Enable RTC Source
15
16
17
RTC_COMP = 1;    //Compareregister setzen (kein compare intterupt vorgesehen)
18
while(RTC.STATUS & RTC_SYNCBUSY_bm) //warten auf sync
19
{
20
}  
21
    
22
//RTC_PER = 32768;
23
RTC_PER =944;    //Setze Periodenregister
24
//RTC_PER =1022;    
25
26
while(RTC.STATUS & RTC_SYNCBUSY_bm) //warten auf sync
27
{
28
}  
29
      
30
RTC_INTCTRL =  0b00000011; // Compare interrupt aus, Overflowinterrupt an, prio heigh
31
while(RTC.STATUS & RTC_SYNCBUSY_bm) //warten auf sync
32
{
33
}  
34
      
35
RTC_CNT=0;      //Count Register resetten
36
while(RTC.STATUS & RTC_SYNCBUSY_bm)  //warten auf sync
37
{
38
}  
39
      
40
RTC_CTRL =    0b00000001; // Clocksorce Prescaler: 1
41
while(RTC.STATUS & RTC_SYNCBUSY_bm)   //warten auf sync
42
{
43
}
44
  
45
}

von Bastian W. (jackfrost)


Lesenswert?

Wenn du eine sehr stabile Temperatur hast kannst du ja alle x Interrupte 
den Wert kurz ändern um nicht zu weit abzudriften.

Wenn deine Temperatur schwankt wirst du mit den internen Taktquellen 
nicht glücklich , da du weniger als 0,1% Fehler haben willst.

Die ULP ist sehr ungenau. Bei meinem 128A1 war das ein Problem nach 
bereits ein paar Tagen. Da ging die Uhr gut nach.

Gruß JackFrost

von Jacko (Gast)


Lesenswert?

Also von 32,768 kHz kommen 1024 Hz. Nach Adam Riese braucht man
die nur durch 1024 (2^10) zu teilen, um 1 Hz = 1 Takt pro
Sekunde zu erhalten.

Das wäre hochgenau, WENN die internen 32,768 kHz genau wären...

von David R. (dave234)


Lesenswert?

Jacko schrieb:
> Also von 32,768 kHz kommen 1024 Hz. Nach Adam Riese braucht man die nur
> durch 1024 (2^10) zu teilen, um 1 Hz = 1 Takt pro Sekunde zu erhalten.
> Das wäre hochgenau, WENN die internen 32,768 kHz genau wären...

Deshlab hatte ich ja gedacht dass ich die 32,768kHz nehme und dann bis 
32765± zähle um es genau hinzubekommen, die Schritte sind ja feiner. 
Doch statt mit 32,768kHz zählt der mit 945Hz.

Bastian W. schrieb:
> Wenn du eine sehr stabile Temperatur hast kannst du ja alle x Interrupte
> den Wert kurz ändern um nicht zu weit abzudriften.

Habe ich auch schon dran gedacht. Meine aber gelesen zu haben man müsse 
den Zähler dafür anhalten.das macht es auch nicht genauer.

: Bearbeitet durch User
von Jacko (Gast)


Lesenswert?

Es ist wurscht, ob man für eine Sekunde die 1024, oder die
32768 Hz nimmt. Beide haben den gleichen relativen Fehler.

Atmel garantiert nur, dass man mit Kalibrieren auf
typisch (!) 0,5% Genauigkeit kommt.
0,5 % von 1024 sind ca. 5,x Hz, also 1019...1029 Hz.

Ohne 32,768 kHz Quarz wird das nichts.

von David R. (dave234)


Lesenswert?

Jacko schrieb:
> Es ist wurscht, ob man für eine Sekunde die 1024, oder die
> 32768 Hz nimmt. Beide haben den gleichen relativen Fehler.
>
> Atmel garantiert nur, dass man mit Kalibrieren auf
> typisch (!) 0,5% Genauigkeit kommt.
> 0,5 % von 1024 sind ca. 5,x Hz, also 1019...1029 Hz.
>
> Ohne 32,768 kHz Quarz wird das nichts.

im Prinzip richtig. Mein gedanke war nur, dass wenn ich statt den 1022 
Zählschritten (bei denen er nen tacken zu langsam zählt) ich 1021 
verwende der Zähler zu schnell läuft.

Wenn ich aber statt 32768 z.B. 32767 einstellen könnte kann ich mich da 
irgendwie rantasten.

Und hier liegt ja das Problem: die 32,768kHz lassen sich nicht korrekt 
aktivieren.

von Jacko (Gast)


Lesenswert?

Ich weiß ja nicht, was du von Datenblättern hältst -
aber dort ist der Verlauf der 32K-Frequenz gegenüber dem
Kalibrierwert RC32KCAL[7..0] zu sehen:
Ca. 60 Steps für 6 kHz, also auf 100 Hz einstellbar.
Dazu Temperaturdrift... ergibt >= 0,5% Fehler

Wenn es genauer sein soll: 32,768 kHz Quarz!

von David R. (dave234)


Angehängte Dateien:

Lesenswert?

Jacko schrieb:
> Ich weiß ja nicht, was du von Datenblättern hältst -
> aber dort ist der Verlauf der 32K-Frequenz gegenüber dem
> Kalibrierwert RC32KCAL[7..0] zu sehen:
> Ca. 60 Steps für 6 kHz, also auf 100 Hz einstellbar.
> Dazu Temperaturdrift... ergibt >= 0,5% Fehler
>
> Wenn es genauer sein soll: 32,768 kHz Quarz!

Ich glaube wir reden aneinander vorbei.

ich versuche lediglich wie in der Tabelle beschrieben den Zähler mit 
32,768kHz zählen zu lassen. Er zählt aber mit 945Hz.

Dass der interne OSC ungenau ist weiss ich.

von Jacko (Gast)


Lesenswert?

Achso, ich dachte, du wolltest eine genaue Sekunde...

Wenn ein 32 KHz Takt für 1 s nur 945 Takte braucht, (oder
umgekehrt?) wird da wohl was falsch programmiert sein.

Erst mal meint man, du benutzt den 1024 Hz Takt, der gerade
10% Fehler hat.

Da du in deinen Programmschnipseln lauter Konstanten und
Variablen benutzt, die weder im Datenblatt zu finden sind,
noch im Text definiert sind, wirst du dort suchen müssen.
Wer soll das sonst können?

von David R. (dave234)


Lesenswert?

Jacko schrieb:
> Achso, ich dachte, du wolltest eine genaue Sekunde...
>
> Wenn ein 32 KHz Takt für 1 s nur 945 Takte braucht, (oder
> umgekehrt?) wird da wohl was falsch programmiert sein.
>
> Erst mal meint man, du benutzt den 1024 Hz Takt, der gerade
> 10% Fehler hat.
>
> Da du in deinen Programmschnipseln lauter Konstanten und
> Variablen benutzt, die weder im Datenblatt zu finden sind,
> noch im Text definiert sind, wirst du dort suchen müssen.
> Wer soll das sonst können?

Ja, ich habe die 1024 Hz erwähnt weil ich alle Varianten durchprobiert 
habe.

Der Programmierschnipsel ist der einzige Teil der sich mit dem Timer und 
der Clock beschäftigt.

Ich sehe 0 Variablen.

Alle Registernamen und Bitbezeichnungen stehen im Datenblatt.

http://www.atmel.com/Images/Atmel-8210-8-and-16-bit-AVR-Microcontrollers-XMEGA-D_Manual.pdf

Ob das falsch programmiert ist versuche ich ja gerade herrauszufinden.

Ich weiss also nicht was dein Problem ist?

: Bearbeitet durch User
von Sebastian S. (amateur)


Lesenswert?

Irgendwie scheint mir das alles vergebene Liebesmüh zu sein.

Wenn es stimmt, was die Atmels behaupten, so sind 0,5% ein 
phantastischer Wert.

Normalerweise ist das für alle Messzwecke ausreichend genau.

Aber halt nicht für eine Uhr.
Da hilft nur ein Quarz - und zwar kein PC-kompatibler (wird ständig über 
das Internet korrigiert) sondern ein echter Uhrenquarz.

Da hilft auch kein Taschenrechner!
Eine definierte Zeitspanne messen um dann z.B. alle 5 Minuten 
Korrekturschritte einzufügen ist auch Unsinn.
Hierbei wird ja implizit unterstellt das der interne Zeitgeber super 
genau z.B. 0,4571% vor- oder nachgeht.
Also ein Witz, noch nicht mal wenn die Temperatur konstant gehalten 
wird.

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.