Forum: Mikrocontroller und Digitale Elektronik XMega: Laufend RTC-Periode umstellen


von Thomas L. (delfinis)


Angehängte Dateien:

Lesenswert?

Hallo,
ich benutze den RTC um den uc immer eine Minute schlafen zu legen.
Das erste mal soll er jedoch nur 10 sekunden schlafen, und dann immer 
eine Minute. Allerdings soll diese Minute variabel sein, um zeitdrift 
auszugleichen.

Nun hab ich den RTC mittels dem Periodenregister und dem 
Overflow-Interrupt so hingebracht, dass er zuerst 10 Sekunden schläft 
und dann auch wieder aufwacht. (RTC zählt vier mal pro Sekunde d.H. für 
10 Sekunden = 0x28)

Aber wenn ich das Periodenregister RTC.PER auf eine Minute (60 x 4 = 
0xF0) umstelle, weckt er trotzdem immer alle 10 Sekunden auf. Mit dem 
Debugger hab ich dann mal geschaut ob das RTC-Register tatsächlich 
umgeschrieben wird - und es wird auch umgeschrieben (siehe Foto)! Aber 
trotzdem bleibt die Periode auf 10s!

Prozessor: ATXMega32E5
1
main() {
2
.
3
.
4
  RTC.PER = 0x28;
5
  CLK.RTCCTRL = (CLK_RTCSRC_TOSC_gc | CLK_RTCEN_bm); //select 32768/32 ext. crystal
6
  RTC.CTRL = RTC_PRESCALER_DIV256_gc;  // prescaler to 0.25s for time synchroniz.
7
.
8
.
9
  while (1) {
10
    .
11
    .
12
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
13
    sleep_mode();
14
  }
15
}

von Plörensaugikus (Gast)


Lesenswert?

Nun ja. Das  RTC.PER = 0x28; bleibt ja auch immer daselbe

von Thomas L. (delfinis)


Lesenswert?

Plörensaugikus schrieb:
> Nun ja. Das  RTC.PER = 0x28; bleibt ja auch immer daselbe

Nein, wird ja in der Interrupt-Routine auf 0xf0 umgeschrieben, siehe 
Interrupt-Routine und markierte Memory-Stelle. Sorry, hab ich wohl zu 
wenig klar beschrieben.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Thomas L. schrieb:

> Aber wenn ich das Periodenregister RTC.PER auf eine Minute (60 x 4 =
> 0xF0) umstelle, weckt er trotzdem immer alle 10 Sekunden auf. Mit dem

Da Du uns leider nicht mitteilst welchen Xmega Du jetzt wirklich 
verwendest, habe ich in das Datenblatt der AU-Familie geguckt:

Abs. 18.2.2:

Due to the asynchronous clock domain, events will be generated only for 
every third overflow or compare match if the
period register is zero. If the period register is one, events will be 
generated only for every second overflow or compare
match. When the period register is equal to or above two, events will 
trigger at every overflow or compare match, just as
the interrupt request.

Abs. 18.3.2:

Bit 0 – SYNCBUSY: Synchronization Busy Flag
This flag is set when the CNT, CTRL, PER, or COMP register is busy 
synchronizing between the RTC clock and
system clock domains after writing any of these registers or when waking 
up from a sleep mode where the peripheral
clock is stopped. This flag is automatically cleared when the
synchronisation is complete.


Beachstest Du diese Hinweise? Leider ist Dein Code-Beispiel nicht 
vollständig...

Grüßle
Volker.

Nachtrag: Warum hast Du den Interrupt-Code nicht als Text eingefügt? 
Lustiges Suchspiel!

Also ich würde das Busy-Waiting im Hauptprogramm machen und erst nachdem 
sich die RTC synchronisiert hat den Interrupt freigeben. Bei der 
Änderung im Irpt-Handler ggf. ein Flag setzen, Irq. sperren und in 
main() auf die Synchronisierung warten.

: Bearbeitet durch User
von Thomas L. (delfinis)


Lesenswert?

Volker B. schrieb:
> Da Du uns leider nicht mitteilst welchen Xmega Du jetzt wirklich
> verwendest

Hab ich doch:
"Prozessor: ATXMega32E5"


Hab die Lösung gefunden:
******************************

Hab eine Annotation note gefunden:
ww1.microchip.com/downloads/en/AppNotes/doc8047.pdf

Dort steht unter anderem:
"Note that the PER register  does  not  have  a  separate  synchronizer; 
the  synchronization  of  PER  is triggered by synchronization of the 
CNT, CTRL or COMP registers.

Hab in der Interrupt-Routine noch nachträglich das CTRL Register neu 
überschrieben, nun funktionierts! Nur leider steht davon nichts im 
Datenblatt....
1
ISR(RTC_OVF_vect) {
2
  while (RTC.STATUS & RTC_SYNCBUSY_bm);
3
  RTC.PERL = 0x28;
4
  RTC.PERH = 0x00;
5
6
  // ==> wichtig, für's Update des PER-Registers:
7
  RTC.CTRL = RTC_PRESCALER_DIV256_gc; 
8
9
  PORTA_OUTSET = 0x01; // 3.3V on
10
  PORTD_OUTSET = 0X80; //DEBUG
11
}

von Wolfgang (Gast)


Lesenswert?

Thomas L. schrieb:
> Hab eine Annotation note gefunden:
> ww1.microchip.com/downloads/en/AppNotes/doc8047.pdf
> ...
> Nur leider steht davon nichts im Datenblatt....

Das Datenblatt beschreibt, was der Prozessor kann. Die Application Note 
beschreibt, wie man die Baugruppe anwendet - darum die Bezeichnung 
"Application Note".

Wenn man das natürlich als "Annotation Note" abtut, darf man sich nicht 
wundern ...

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.