Forum: Mikrocontroller und Digitale Elektronik STM32 RTC haengt nach RTC_SetCounter()


von cepheus (Gast)


Lesenswert?

Hi, ich bin gerade dabei eine RTC auf einem STM32F103C8 in Betrieb zu 
nehmen. Habe den Beispielcode aus der Periph-Lib verwendet, soweit 
funktioniert fast alles, z.B. Auslesen, 1s-IRQ, etc.
Nur, wenn ich jetzt versuche den Wert im laufenden Betrieb zu setzen 
bekomme ich einen Hänger. Verwendet habe ich diese Funktion aus dem 
Example, hier mit Failsafe auf 0x0:
1
void Time_Adjust(uint32_t timestamp)
2
{
3
  /* Wait until last write operation on RTC registers has finished */
4
  RTC_WaitForLastTask();
5
  /* Change the current time */
6
  //RTC_SetCounter(timestamp);
7
  RTC_SetCounter(0x0);
8
  /* Wait until last write operation on RTC registers has finished */
9
  RTC_WaitForLastTask();
10
}

Im Debugger sehe ich das er am letzten Funktionsaufruf hängen bleibt:
1
void RTC_WaitForLastTask(void)
2
{
3
  /* Loop until RTOFF flag is set */
4
  while ((RTC->CRL & RTC_FLAG_RTOFF) == (uint16_t)RESET)
5
  {
6
  }
7
}
Und zwar nur und jedesmal, wenn ich davor einen SetCounter-Aufruf hatte.
Muss ich noch irgendwas beachten?

von hp-freund (Gast)


Lesenswert?

cepheus schrieb:
> wenn ich davor einen SetCounter-Aufruf hatte

Davor?

Die Funktionsbeschreibung sagt aber:

This function must be called before any write to RTC registers.

von cepheus (Gast)


Lesenswert?

Ja, den Teil danach hatte ich aus dem Beispiel so uebernommen.
Spielt aber keine Rolle, wenn ich den Aufruf da rausnehme haengt er
an beliebigen Zeitpunkten beim naechsten Aufruf davon dort fest.

von hp-freund (Gast)


Lesenswert?

Hast Du auch den:

RTC_WriteProtectionCmd(DISABLE); // Disable RTC register write 
protection

mit eingebaut?

von cepheus (Gast)


Lesenswert?

Hmm, nein. In der aktuellen (3.5.0) Library kann ich die aber auch nicht 
finden? Aber das Flag klingt schonmal vielversprechend.

Ich habe gerade einen Workaround zusammengebracht. Und zwar wird im 
Example anhand der RTC BackupRegs geprueft, ob die RTC schon 
konfiguriert ist. Davon abhaengig wird das hier am Anfang ausgefuehrt 
oder nicht:
1
void RTC_Configuration(void)
2
{
3
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
4
  PWR_BackupAccessCmd(ENABLE);
5
  BKP_DeInit();
6
  RCC_LSEConfig(RCC_LSE_ON);
7
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
8
  {}
9
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
10
  RCC_RTCCLKCmd(ENABLE);
11
  RTC_WaitForSynchro();
12
  RTC_WaitForLastTask();
13
  RTC_ITConfig(RTC_IT_SEC, ENABLE);
14
  RTC_WaitForLastTask();
15
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
16
  RTC_WaitForLastTask();
17
}

Wenn ich das in beiden Faellen ausfuehre, kann ich die RTC problemlos 
setzen. Ich versuche das mal einzugrenzen.

von cepheus (Gast)


Lesenswert?

Ich benötige wirklich fast den gesamten Durchlauf dieser Funktion, damit 
ich Schreibzugriff habe.
Immerhin kann ich für den Schon-Konfiguriert-Fall die BKP_DeInit(); 
rausnehmen, damit die RTC mit Batteriepuffer nicht bei jedem Reset 
wieder bei 0 anfängt.
Aber alles in allem ist das Beispiel in der Library IMHO fehlerhaft.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Der Beitrag ist zwar schon älter, hat mir aber viel Googelei gespart :)

Danke!

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.