Hallo, das Thema ist im Netz leider nur recht verwirrend dargestellt und teils sogar falsch, daher frage ich mal. Ich möchte bei meinem F103 in den Stop oder StandbyMode und er soll per RTC Sekunden Interrupt wieder rauskommen. Nur wie? Die Modes sind nicht debugbar. Einmal drin kann ich den Chip erstmal löschen und vorher Reset drücken, damit er wieder durch den st-link beschreibar wird. Und dann finden sich noch so Dinge wie void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) void PWR_EnterSTANDBYMode(void) aber auch void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) die damit etwas zu tun haben zu scheinen. In einer App Note wird zudem gesagt, dass ein EXTI auf die NVIC Line 17 gelegt werden soll. Aber den RTC Alarm nutze ich nicht. Wie sieht das denn nun ganz einfach aus? Mehr ein paar Codezeilen dürften da ja nicht sein, den durch den RTC Int aufwachen zu lassen. Bei meinen Versuchen weckte der Systick die CPU auf, schalte ich den ab wacht sie nicht mehr auf. EXTI->PR = 0xFFFFFFFF; PWR_ClearFlag(PWR_FLAG_WU); PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFE); SystemInit(); Gruss, Christian
mts schrieb: > nutze den RTC Alarm.. Funktioniert aber nicht, kein Einsprung in die ISR :-(
1 | /* ----- Alarm Interrupt setzen ------- */
|
2 | |
3 | /* Alarm Interrupt an NVIC koppeln, Kanal 17 */
|
4 | EXTI_ClearITPendingBit(EXTI_Line17); |
5 | NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn; |
6 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13; |
7 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
8 | NVIC_Init(&NVIC_InitStructure); |
9 | |
10 | /* Int zulassen */
|
11 | RTC_WaitForLastTask(); |
12 | RTC_ClearITPendingBit(RTC_FLAG_ALR); |
13 | NVIC_EnableIRQ(RTCAlarm_IRQn); |
14 | |
15 | RTC_WaitForLastTask(); |
16 | RTC_SetAlarm(RTC_GetCounter() + 5); |
17 | RTC_WaitForLastTask(); |
18 | RTC_ITConfig(RTC_IT_ALR, ENABLE); |
19 | |
20 | |
21 | |
22 | void RTC_IRQHandler(void) |
23 | {
|
24 | #define MEZ +1
|
25 | static _Bool merker = false; |
26 | static _Bool led_switch = false; |
27 | struct tm *ptr; // Zeiger auf Zeit Strktur |
28 | time_t value; // 32 Bit Unixzeit |
29 | |
30 | |
31 | if (RTC_GetITStatus(RTC_IT_ALR) != RESET) |
32 | {
|
33 | RTC_WaitForLastTask(); |
34 | RTC_SetAlarm(RTC_GetCounter() + 3); |
35 | /* Wait until last write operation on RTC registers has finished */
|
36 | RTC_ClearITPendingBit(RTC_IT_ALR); |
37 | EXTI_ClearITPendingBit(EXTI_Line17); // Remove LINE interrupt flag bit |
38 | }
|
39 | |
40 | if (RTC_GetITStatus(RTC_IT_SEC) != RESET) |
41 | { .... |
Chris J. schrieb: > das Thema ist im Netz leider nur recht verwirrend dargestellt und teils > sogar falsch, daher frage ich mal. Im "Netz" vagabundiert halt vieles herum. Und??? Es soll (rein gerüchtehalber ...) ein Reference Manual geben, das man sich angeblich bei ST kostenlos herunter laden kann. > Ich möchte bei meinem F103 in den Stop oder StandbyMode und er soll per > RTC Sekunden Interrupt wieder rauskommen. Hm, in besagten Manual (Figure 179. RTC simplified block diagram) ist klar beschrieben, dass RTC_Second nur nach RTC_CR geht, und da steht ausdrücklich "not powered in Standby" drunter. Im Standby ist's also nix. Steht auch in "Table 15. Standby mode". Also jede Sekunde den Alarm für die nächste Sekunde setzen ... Zum Stop-Mode siehe "Table 14. Stop mode". > Wie sieht das denn nun ganz einfach aus? Mehr ein paar Codezeilen > dürften da ja nicht sein, den durch den RTC Int aufwachen zu lassen. Und wenn man gründlich im Reference Manual liest, findet man auch heraus, wie die ggf. aussehen müssen. Aber eine fertige Copy-And-Paste Lösung gibt's halt nicht. Selber machen macht Spass - und gibt hinterher ein echtes Erfolgserlebnis. ;-)
A. B. schrieb: > ein Reference Manual geben, das man sich angeblich > bei ST kostenlos herunter laden kann. Sorry, aber ich stelle hier nur was ein, wenn ich absolut nicht mehr weiter weiss und alle Quellen zur Rate gezogen habe. Der INT springt nicht an, auch im Stop Mode nicht und auch so wird kein Alarm Int erzeugt. Der benutzt ja wohl die gleiche Routine wie die anderen RTC Ints und wird nur über sein Bit unterschieden... einen EXTI_17 Handler gibt es nicht. Die Schose spielt einwandfrei
1 | /* ------------------------------------------------ */
|
2 | /* ----- Normalen Sekunden Interrupt setzen ------- */
|
3 | /* ------------------------------------------------ */
|
4 | |
5 | /* ----- 1s RTC Interrupt an NVIC koppeln --------*/
|
6 | NVIC_InitTypeDef NVIC_InitStructure; |
7 | NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; |
8 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 14; |
9 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
10 | NVIC_Init(&NVIC_InitStructure); |
11 | /* Int zulassen */
|
12 | NVIC_EnableIRQ(RTC_IRQn); |
13 | |
14 | /* RTC Second Interrupt einschalten*/
|
15 | RTC_WaitForLastTask(); |
16 | RTC_ITConfig(RTC_IT_SEC, ENABLE); |
Die aber nicht, null Reaktion.
1 | /* ------------------------------------ */
|
2 | /* ----- Alarm Interrupt setzen ------- */
|
3 | /* ------------------------------------ */
|
4 | |
5 | /* Alarm Interrupt an NVIC koppeln, Kanal 17 */
|
6 | EXTI_ClearITPendingBit(EXTI_Line17); |
7 | NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn; |
8 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13; |
9 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
10 | NVIC_Init(&NVIC_InitStructure); |
11 | NVIC_EnableIRQ(RTCAlarm_IRQn); /* Int zulassen */ |
12 | |
13 | RTC_WaitForLastTask(); |
14 | RTC_SetAlarm(RTC_GetCounter() + 5); |
15 | RTC_WaitForLastTask(); |
16 | RTC_ITConfig(RTC_IT_ALR, ENABLE); |
Habs schon... Das Zauberwort hiess: PWR_BackupAccessCmd(ENABLE); Ohne das geht nix mit der RTC. Und dieser aus dem Netz abgeschrieben Code läuft auch nicht, da da unbedingt ein RTC_WaitForLastTask() zwischen die beiden Operationen muss, sonst wird die AL Time nicht gesetzt. FALSCH: RTC_SetAlarm(RTC_GetCounter() + 3); RICHTIG: PWR_BackupAccessCmd(ENABLE); RTC_WaitForSynchro(); RTC_WaitForLastTask(); uint32_t val = RTC_GetCounter(); RTC_WaitForLastTask(); RTC_SetAlarm(val + 3); RTC_WaitForLastTask(); PWR_BackupAccessCmd(DISABLE); Ob das nötig ist weiss ich nicht, es spielt mit und ohne in der ISR EXTI_ClearITPendingBit(EXTI_Line17); // Remove LINE interrupt flag bit Das Aufwachen aus dem Stoop läuft leider immer noch nicht, weder mit WFI noch mit WFE und im Release rennt er sogar in den Hardfault Handler :-(
Funzt nicht :-( Das Ding geht und geht nicht in den Sleep Mode, die anderen Modes brauche ich nicht. Und das ewige manuelle Um-Jumpern und Löschen, weil die swd Schnittstelle sich aufhängt nervt auch. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Enable deepsleep */ SetRedLED(ENABLE); __WFI(); /* Enter sleep mode */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; SetRedLED(DISABLE); SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; __WFI(); /* Enter sleep mode */
Deshalb liebe ich HAL. :) Dafür gibt es ein Beispiel Namens: RTC_LowPower_STANDBY Kannst ja mal suchen ob es das auch ohne HAL gibt.
pegel schrieb: > Deshalb liebe ich HAL. :) Damit fange ich nicht mehr an, diese Klicki-Bunti CubeMX Welt ist mir suspekt, das Alte tut es ja auch ;-) Ging aber auch so, habs mal zusammen geschrieben im Code Bereich.
Ich hab zwar keine Ahnung, aber bei SLEEPDEEP würde ich auf Stop oder Standby-Mode tippen. Und dann wäre noch zu klären, wo nach Beendigung eines Ereignisses die Ausführung weiter geht.
Da du die SPL nutzt, würde ich dir raten mal in die zahlreichen Examples zu schauen. Damit habe ich den Stop- und Standby-Mode in kurzer Zeit lauffähig bekommen, allerdings mit EXTI zum aufwecken. Das ist vielleicht eine bessere Quelle zum abtippen, als irgendwas aus dem "Netz"
Auch wenn Du den RTC jetzt am laufen hast, kleiner Tip am Rande: Du kannst den RTC Interrupt auch ohne Sleep/Standby debuggen. Mach erstmal das RTC Krams mit dem Debugger rund und dann, wenn der Alarm funktioniert, gehst Du in den Sleep. Vor dem Sleep deaktiviere ich Systick, danach aktiviere ich ihn wieder und setze ich die Clock neu. (Bei mir passte der HAL_Delay sonst nicht). Du solltest auch I2C usw. deaktivieren, sonst bleibt der Verbrauch relativ hoch. Noch ein Tip: Nach einem Reset lasse ich den Controller mindestens 5 Sekunden wach (lasse LED blinken, dann seh' ich es). Währenddessen kann man mit dem Debugger neu aufspielen. Dann reicht es Reset zu drücken, dann Debug in der IDE. ...Alex
:
Bearbeitet durch User
noreply@noreply.com schrieb: > Ich hab zwar keine Ahnung, aber bei SLEEPDEEP würde ich auf Stop oder > Standby-Mode tippen. Nee.... das ist wirklch SLEEP Mode, der hat nur diverse Modi. Ich schrieb: > Da du die SPL nutzt, würde ich dir raten mal in die zahlreichen Examples > zu schauen. Ja, nach 7 Stunden fiel mir ein, dass ich die irgendwo mal kopiert hatte und das Vergessene, nämlich der EXTI17 fiel vom Himmel. Nicht aber, dass dann plötzlich ein anderer Handler angesprungen wird als vorher. Es laufe nur SLEEP und STOP, aus Standby kommt er nur mit einem echten Pin Int wieder raus und startet dann komplett neu per Reset, zumindest bei mir. Alexander B. schrieb: > Mach erstmal > das RTC Krams mit dem Debugger rund und dann, wenn der Alarm > funktioniert, gehst Du in den Sleep. Genauso habe ich es gemacht, dass der Sleep und Stop funktionieren sah ich auch nur an den Blinki-LEDs. Nur sagt einem keiner, dass bei allen Modi SysClock und SysTick neu konfiguriert werden müssen, ebenso die Clock fürs ADC und SPI etc. Alle gelöscht, watt ein Mist :-( Und dass Systick auch den Sleep sofort beendet und daher abgeschaltet werden muss. Eigentlich kann man den Systick sogar dafür nehmen, wenn man mit 24 Bit zufrieden ist. Und der Watchdog funkt einem auch noch dazwischen, den juckt das nämlich nicht, wenn der abläuft wird resettet. Mühsam, mühsam.... dabei will ich nur von den 50mA, die das Board normal braucht auf ca 5-6, damit der 18650 Akku etwas länger hält. Echte Low Power Anwendungen habe ich lieber mit dem Attiny 84 gemacht an der Arduino IDE, direkt an eine Mignon mit DC/DC Step up (200uA) da hält ne Mignon fast 1/2 Jahr für den Sensor und Funkmodul. > Nach einem Reset lasse ich den Controller mindestens 5 > Sekunden wach (lasse LED blinken, dann seh' ich es). Währenddessen kann > man mit dem Debugger neu aufspielen. Dann reicht es Reset zu drücken, > dann Debug in der IDE Auf die Idee kam ich auch später, vorher artig immer umgestöpselt und mit ST Utility gelöscht, bis das so nervig wurde, dass ich auch auf diese Idee kam.
Ist zwar HAL, aber ich teile mal meinen Code: https://gist.github.com/alexbrickwedde/21bd84693f0749a6ac8121bb72026dd1 Ich lasse den Controller max 10 Sekunden schlafen und bediene dann den IWDG. Über den Tageswechsel erkenne ich dann recht einfach, dass der Sleep beendet sein soll. Egal, ob und wie oft er vorher durch irgendwas anderes aufwacht. I2C, SPI usw. (de)aktivieren fehlt hier noch (ist in der DoSomeAction).
:
Bearbeitet durch User
Quelle: en.CD00171190.pdf Table 11 on site 71
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.