Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
RTC na STM32 za baterijski rad
#1
Da li je moguće da STM32 (recimo serije F7) treba za normalan nastavak rada RTCa kada je bez napajanja (napaja se preko Vbat iz baterije) koristiti poseban kristal (32.768 Hz)? Trenutno koristim samo 25 MHz kristal koji je preskaliran na 1 MHz da bi se koristio kao HSE_RTC i dalje preskalirao na potrebnih 1 Hz. Kada ostane bez napajanja, date/time ostaje sačuvan, ali ispada da RTC prestane brojati vrijeme.

Drugo, a moguće da sam krivo mjerio, ali MCU povlači ispod 2 uA iz baterije kada je spojen na radno napajanje. Međutim kada ga ugasim, potrošnja skoči na nešto preko 20 uA. Kako je to moguće? U nastavku je fragment šeme na kojem se vidi kako su dovedena napajanja na MCU.

[Image: 4ez7g4V.png]
Reply
#2
Mislim (nemoj me držati za reč jer nisam probao) da moraš koristiti LSI ili LSE oscilator da bi ti RTC nastavio sa radom.

LSE koristi eksterni kristal od 32...KHz, a LSI je RC oscilator koji se može kalibrisati nešto od 30-40KHz i naravno nema tačnost koju ima LSE sa kristalom.

LSI sam za sada samo koristio za IWDG (i jako mi se sviđa kako to radi kod kritičnih aplikacija, gde nešto može da zakuca ili obori MCU).
Nisam za RTC, ali mislim da RTC neće nastaviti sa radom ukoliko mu je osnovni izvor HSE ili HSI.

Probaj sa LSE sa kristalom ili da kalibrišeš što bolje LSI ako ti nije posebno važan tačan sat.

Van toga, LSI i HSI su obični RC oscilatori koji nemaju posebnu tačnost jer zavise od temperature i stoga se koriste u aplikacijama gde nisu od posebne važnosti precizna vremena.
Dovedeno je to do stvarno visokog maksimuma kvaliteta i pored toga što su RC oscilatori u pitanju, ali nije ni za približno poređenje sa tačnosti bilo kog oscilatora sa kvarcom.

P.S.

Cube MX ti tu može biti vrlo zahvalan alat jer poseduje kalkulaciju potrošnje maltene za sve moguće opcije rada. Takođe i za sve konfiguracije oba oscilatora.
Ne koristim HAL uopšte, već koliko god mogu bare metal, ali Cube mi odlično posluži za procene resursa.
Reply
#3
Hvala ti, po ovome što smo testirali ispada da je tako. Ono što me muči je ili moja nesposobnost da pronađem tu informaciju u DS ili takva informacija uopće ne postoji u DS-u jer je to stvar koja bi se valjda trebala podrazumijevati.
Reply
#4
Jbg, RM0090, manual za Cortex M4 ima 1750 stranica, a za M7 je moguće i da je veći. Tu stvarno nije lako naći ono što ti treba.
I na kraju se mora proveriti u praksi bilo šta, jer nikad ne znaš da li možda postoji neki problem pa je dodatno opisan i eventualno rešen u Erata dkumentu.
Reply
#5
Tako ispada Confused
Reply
#6
Kad smo već kod IWDG, kog sam malopre pomenuo kao vrlo korisnu stvarčicu, setup je jako jednostavan i važi za sva Cortex STM uz neka obogaćenja kod većih M.

Evo kako izgleda za STM32F1 (Cortex M3, konkretno na Blue Pill):

Code:
void iwdg_setup(void)
{
    //  RCC->CSR |= (1<<0);                 // LSI enable (ukoliko negde vec nije), necessary for IWDG
  //  while ((RCC->CSR & (1<<1)) == 0);   // wait till LSI is ready

  IWDG->KR  = 0x5555;                   // enable write to PR, RLR
  IWDG->PR  = 4;                          // Init prescaler, /64, max 8 sec trenutno
  IWDG->RLR = 0xFFE;                   // Init RLR
  IWDG->KR  = 0xAAAA;                 // Reload the watchdog, takodje ciscenje u nekoj petlji
  IWDG->KR  = 0xCCCC;                 // Start the watchdog
}

Velika prednost je što je IWDG sasvim nezavisna naprava, kojoj treba čistiti brojač sa IWDG->KR = 0xAAAA; pre nego što istekne, inače resetuje MCU pa otpočetka.

Super je zato što može zaštititi od jedne jako nezgodne stvari, a to je prestanak rada HSI oscilatora. Tada MCU ostaje zaglavljen tu gde jeste, sa svim outs koji su trenutno bili aktivni.
Pošto to može u nekim situacijama biti jako opasna stvar, posebno kod kontrole nekih izvršnih organa koji raspolažu velikim silama, brzinama, itd, onda nezavisna IWDG naprava može sve to počisti resetom MCU i pri tom isključiti opasne izlaze.

Ranije sam kod MCU, koji nisu imali nezavisni hardver za IWDG, koristio eksterni NE555 kog čistim u pravilnim intervalima i koji obara MCU u slučaju nekog problema. Sada je to fino jer postoji unutra u STM32xxx.

P.S.

Da "dokusurim" info o IWDG:
kod Cortex M3 je podesiv od 100uS do 26 sekundi timeout, što je i više nego dovoljno za bilo koju opciju opasnog rada.
Čak može zaštititi i SMPS vođen tim MCU, koji radi do nekih 50KHz, sa timeout od 100uS.
Reply
#7
Da dodam par stvari oko RTC.

Prvo RTC moze da radi sa jednim od dva izvora clock-a, prvi je interni LSI RC oscilator (vrlo neprecizan, stabilnost u par %) ili LSE sa malim kristalom od sata 32.768kHz za koji se obicno daje 10ppm stabilnost.

Malo je nezgodno za experimentisanje sa tim RTC jer se glavna logika desava kada kontroler ostane bez glavnog napajanja a ostane Vbat, morate voditi racuna da ne mogu da se neke stvari resetuju i pociste dok se kontroler skroz ne iskljuci i ukljuci ponovo.

Takodje kod STM-ova ima CSS (Clock Security System) koji sluzi za nadgledanje ispravnosti master oscilatora i u slucaju da prestane da radi (problem sa kristalom na HSE) moze da prebaci na interni oscilator i tako nastavi da radi.
Reply
#8
Ima i mogućnost taktovanja sa HSE i preskalerom, koju je prasimix i upotrebio, ali to vreme staje onog trenutka kad stane HSE.
Reply
#9
Da moze i preko HSE ali kao sto si rekao tajmer staje kada stane taj oscilator tj kad MCU ostane bez Vcc power.

LSE ili LSI rade nezavisno preko VBat ako se tako konfigurise, to je predvidjeno bas za low-power satove.

Neki modeli MCU imaju i Alarm time, tu ima jos i nesto sitne NVRAM memorije (10-15 bytova) koja se napaja preko VBat.
Reply
#10
Kada smo već kod WDG
Da li netko ima ideju zašto cubeMX kod generiranja kod stavljja obično na zadnje mjesto
Recimo ovaj primjer koji sam sada izgenerirao.

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MX_USART1_UART_Init();
MX_SPI1_Init();
MX_FATFS_Init();
MX_RTC_Init();
MX_IWDG_Init();

Koliko sam čitao ako se napravi soft reset IWDG će se pauzirati i ako fail-a bilo koji dio inicijalizacije sve će se zaglaviti.
Na žalost čini mi se upravo to desi ponekada Sad
Da li postoji neki dobar razlog da IWDG ne bude inicijaliziran prije HAL_Init ?
Reply
#11
Gorane,

Brojač od IWDG startuje onog momenta kad se u registar KR upiše 0xCCCC.
Ukoliko do tog momenta nemaš spremnu i formiranu ISR rutinu koja će refrešovati taj brojač, IWDT će oboriti sistem.

Dosta često razne inicijalizacije zahtevaju neke blokirajuće delays i nisu vremenski precizno kontrolisane.
Ukoliko se ranije inicijalizuje IWDG i ako je u pitanju neki kratak interval njegovog mogućeg overflow, onda će isteći u toku neke inicijalizacije.

Ne koristim HAL, ali mogu da pretpostavim da je to o čemu sam malopre pisao razlog smestanja na poslednje mesto u inicijalizacijama.

Naravno, imaš pravo miksovati i bare metal sa HAL. To ti omogućava da ne zahtevaš od Cube MX da aktivira IWDG a ti ga onda možeš pokrenuti bilo gde.

Na primer, inicijalizuješ ga sa najdužim vremenom od 26 sekundi ili slično kako tebi odgovara, pokriješ tim inicijalizacije ostalih stvari, potom kad ti bude spremna ritmična rutina za čišćenje IWDG, reinicijalizuješ ga na neko kratko vreme koje je tebi optimalno i potom preuzmeš periodično čišćenje njegovog brojača.

Evo napisaću ponovo inicijalizaciju sa dopunskim komentarima oko potrebnih stvari:

Code:
void iwdg_setup(void)
{
  //  RCC->CSR |= (1<<0);                 // LSI enable (aktiviranje LSI ukoliko negde vec prethodno nije aktiviran)
  //  while ((RCC->CSR & (1<<1)) == 0);   // wait till LSI is ready (ne ides dalje dok oscilator stvarno ne proradi)

  IWDG->KR  = 0x5555;    /* enable write to PR, RLR, kljuc koji omogucava pristup promeni preskalera i RLR,
                                        moze se i kasnije u hodu promeniti stanje PR i RLR po potrebi */

  IWDG->PR  = 64;            // Init prescaler, /64,  (moguce od 4 do 256, 40KHz/PR)
  IWDG->RLR = 0xFFF;     /* Init RLR, trajanje intervala, realno od 5 TC do 0xFFF, trenutno 4095 x 40KHz/64 tj.
                                          6552 mS ako je LSI kalibrisan na 40KHz, max. oko 8720 mS ako je 30KHz LSI */  

  IWDG->KR  = 0xAAAA;  /* upis restartuje down count od vrednosti RLR ka nuli, ovim se inace kasnije restartuje counter pre nego sto istekne, inace se dogodi reset MCU */

IWDG->KR  = 0xCCCC;                 // Start the watchdog, start naprave prvi put
}

Reference su ti u dokumentu RM0008
Reply
#12
(05-02-2019, 10:10 AM)Macola Wrote: Gorane,

Brojač od IWDG startuje onog momenta kad se u registar KR upiše 0xCCCC.
Ukoliko do tog momenta nemaš spremnu i formiranu ISR rutinu koja će refrešovati taj brojač, IWDT će oboriti sistem.

Dosta često razne inicijalizacije zahtevaju neke blokirajuće delays i nisu vremenski precizno kontrolisane.
Ukoliko se ranije inicijalizuje IWDG i ako je u pitanju neki kratak interval njegovog mogućeg overflow, onda će isteći u toku neke inicijalizacije.

Ne koristim HAL, ali mogu da pretpostavim da je to o čemu sam malopre pisao razlog smestanja na poslednje mesto u inicijalizacijama.

Naravno, imaš pravo miksovati i bare metal sa HAL. To ti omogućava da ne zahtevaš od Cube MX da aktivira IWDG a ti ga onda možeš pokrenuti bilo gde.

Na primer, inicijalizuješ ga sa najdužim vremenom od 26 sekundi ili slično kako tebi odgovara, pokriješ tim inicijalizacije ostalih stvari, potom kad ti bude spremna ritmična rutina za čišćenje IWDG, reinicijalizuješ ga na neko kratko vreme koje je tebi optimalno i potom preuzmeš periodično čišćenje njegovog brojača.

Evo napisaću ponovo inicijalizaciju sa dopunskim komentarima oko potrebnih stvari:

Code:
void iwdg_setup(void)
{
 //  RCC->CSR |= (1<<0);                 // LSI enable (aktiviranje LSI ukoliko negde vec prethodno nije aktiviran)
 //  while ((RCC->CSR & (1<<1)) == 0);   // wait till LSI is ready (ne ides dalje dok oscilator stvarno ne proradi)

 IWDG->KR  = 0x5555;    /* enable write to PR, RLR, kljuc koji omogucava pristup promeni preskalera i RLR,
                                       moze se i kasnije u hodu promeniti stanje PR i RLR po potrebi */

 IWDG->PR  = 64;            // Init prescaler, /64,  (moguce od 4 do 256, 40KHz/PR)
 IWDG->RLR = 0xFFF;     /* Init RLR, trajanje intervala, realno od 5 TC do 0xFFF, trenutno 4095 x 40KHz/64 tj.
                                         6552 mS ako je LSI kalibrisan na 40KHz, max. oko 8720 mS ako je 30KHz LSI */  

 IWDG->KR  = 0xAAAA;  /* upis restartuje down count od vrednosti RLR ka nuli, ovim se inace kasnije restartuje counter pre nego sto istekne, inace se dogodi reset MCU */

IWDG->KR  = 0xCCCC;                 // Start the watchdog, start naprave prvi put
}

Reference su ti u dokumentu RM0008

super, puno hvala

tako sam i složio sada
postavljen mi je od početka na maksimalni interval pa nemam problema, a ako se sada zaglavi nešto morao bi resetirati.
Budem probao simulirati zaglavljivanje pa vidjeti da li se trigerira.

Zaglavit nije tako teško, ako se ne pokrene clock koji vozi neku periferiju onda će kod zaglaviti kod njene inicijalizacije...

Inače u novom cubeMX-u se za svaku periferiju može odabrati da li se želi LL ili HAL - ne znam da li je toga bilo u starim verzijama, pa se to lako može kombinirati ...
Reply
#13
Uz to nemam ISR za resetiranje countera

Moj kod radi ovako nekako (sve radi low power-a)

Odem u STOP mode
Ako se alarm ne desi 26 sec IWDG bi trebao resetirati
budim se na alarm (RTC alarm je podešn na 1 sekundu)
provjerim da li je vrijeme za slanje poruke ako je izlazim iz tog prvog loopa i ulazim u state mašinu
ako nije idem nazad na spavanje.

U state mašini samo iz prelaska iz stanje u stanje resetiram counter.
Kada bi jedno stanje potrajalo više od 26 sekundi IWDG bi resetirao sistem.
Reply
#14
Ne znam.
HAL je suprotan mom načinu razmišljanja i zato ga ne koristim.
Jednostavno mi se ne sviđa put od Bg ka Zg, preko Amsterdama, makar bio i najluksuznijom klasom...

Takođe sam poznat po tome što nikad, baš nikad ne koristim debuger već ispravljam kod na druge načine.
Hardver je moja osnovna zona te onda tako i razmišljam.
U principu, kad se sretnem sa nekim MCU, prvo mu istražim module i savladam rukovanje njima, potom radim dalje.

Kad malo pretražiš ono što je napravio HAL, vidiš da je na kraju uradio ovaj bare metal koji sam iznad napisao, samo je to uradio kroz deset nekih (bar meni) groznih libs.

Oko IWDG, koliko se sećam, postoje flags o tome da li je baš IWDG napravio reset (mislim da je u RCC_CSR) i mislim da oni ostaju sve dok je napajanje prisutno i da se mogu naknadno pročitati po restartu naprave.
Takođe, koliko se sećam, može se IWDG isključiti u jednom od registara debugera.

Kod vremenski kritičnih stvari, gde često menjaš PR i RLR, imaš izveštaj sa dva flaga u status registru IWDG_SR.
Reply
#15
(05-02-2019, 10:33 AM)Goran.Mahovlic Wrote: Uz to nemam ISR za resetiranje countera

Moj kod radi ovako nekako (sve radi low power-a)

Odem u STOP mode
Ako se alarm ne desi 26 sec IWDG bi trebao resetirati
budim se na alarm (RTC alarm je podešn na 1 sekundu)
provjerim da li je vrijeme za slanje poruke ako je izlazim iz tog prvog loopa i ulazim u state mašinu
ako nije idem nazad na spavanje.

U state mašini samo iz prelaska iz stanje u stanje resetiram counter.
Kada bi jedno stanje potrajalo više od 26 sekundi IWDG bi resetirao sistem.

Verovatno smo istovremeno pisali pa ovo nisam video.

Tako nekako bih i ja uradio.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)