logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[stm32] [STM32][ST Libs] Jak poprawnie skonfigurować RTC w STM32?

herszt 15 Mar 2012 23:30 2891 16
REKLAMA
  • #1 10683186
    herszt
    Poziom 18  
    Posty: 386
    Pomógł: 2
    Ocena: 1
    Witam,

    zaczynam swoją przygodę z STM32, na początku chciałem się pobawić bibliotekami oferowanymi przez producenta i od razu nieprzyjemna niespodzianka. Mam taką funkcję:


    
    void RCC_Conf(void)
    {
    	ErrorStatus HSEStartUpStatus;
    
    	RCC_DeInit();
    
    	RCC_HSEConfig(RCC_HSE_ON);
    
    	HSEStartUpStatus = RCC_WaitForHSEStartUp();
    
    	if(HSEStartUpStatus == SUCCESS)
    	{
    		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    		FLASH_SetLatency(FLASH_Latency_2);
    		RCC_HCLKConfig(RCC_SYSCLK_Div1);
    		RCC_PCLK2Config(RCC_HCLK_Div1);
    		RCC_PCLK1Config(RCC_HCLK_Div2);
    		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    		RCC_PLLCmd(ENABLE);
    
    		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    		
    		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    		
    		while(RCC_GetSYSCLKSource() != 0x08);
    	}
    
    
    	RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
    	RCC_RTCCLKCmd(ENABLE);
    	RTC_WaitForLastTask();
    	RTC_ITConfig(RTC_IT_SEC, ENABLE);
    	RTC_WaitForLastTask();
    	RTC_SetPrescaler(32767);
    	RTC_WaitForLastTask();
    }
    


    I obsługę przerwania:

    
    void RTC_IRQHandler(void)
    {
    	GPIO_ResetBits(GPIOB, GPIO_Pin_8);
    	RTC_ClearITPendingBit(RTC_IT_SEC);
    }
    


    Ale niestety cały program zatrzymuje mi się na ostatniej funkcji RTC_WaitForLastTask(). Będę wdzięczny za wszelkie sugestie takiego stanu rzeczy.

    z góry dzięki
    pozdrawiam
    herszt
  • REKLAMA
  • REKLAMA
  • #3 10683234
    Bruce^666
    Poziom 15  
    Posty: 116
    Pomógł: 11
    Ocena: 3
    Lek na twoje bolączki jak ci sie nie podoba na rejestrach przepisz analogicznie na funkcjach bibliotecznych ja jeszcze nie zdążyłem.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    To jest ważne !!! Reset musi tak wyglądać inaczej nie działa !
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #4 10683566
    herszt
    Poziom 18  
    Posty: 386
    Pomógł: 2
    Ocena: 1
    Witam,

    @freddie Chopin - używam Keila + ST-Linka. Tak, właśnie debugger mi pokazał, że program tak się zatrzymuje, ale z drugiej strony nie zaglądałem dlaczego.

    Spróbuję to od początku "na rejestrach" napisać jak zasugerował @Bruce^666.

    dzięki
    pozdrawiam
    herdzt
  • Pomocny post
    #5 10683644
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    herszt napisał:
    @freddie Chopin - używam Keila + ST-Linka. Tak, właśnie debugger mi pokazał, że program tak się zatrzymuje, ale z drugiej strony nie zaglądałem dlaczego.

    Spróbuj postawić breakpointa na linijce z tą funkcją, a potem "wejdź do niej" - step into - zobaczysz coś więcej może.

    4\/3!!
  • #6 10683708
    Bruce^666
    Poziom 15  
    Posty: 116
    Pomógł: 11
    Ocena: 3
    W tej funkcji jeżeli dobrze pamiętam jest tylko while który czeka na jakąś flagę, nie pamiętam jaką, Ale powtórzę że problem jest że kolega nie resetował poprawnie REJESTRÓW BACK_UP i cześć zapisów do rejestrów które kolega robi lecą w kosmos.
  • #7 10683757
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    Moim zdaniem zdaniem brakuje po
    RCC_RTCCLKCmd(ENABLE);

    RTC_WaitForSynchro();

    nie widzę też włączenia dostępu do BKP o czym pisał Bruce
    
    /* Enable PWR and BKP clocks */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    
      /* Allow access to BKP Domain */
      PWR_BackupAccessCmd(ENABLE);
    
      /* Reset Backup Domain */
      BKP_DeInit();
    

    w trybie debug nawet przy poprawnie działającej inicjalizacji nie chce przechodzić krokowo przez

    while ((RTC->CRL & RTC_FLAG_RTOFF) == (uint16_t)RESET)

    po prostu nigdy nie ustawia się RTOFF , niedawno to samo przechodziłem, jeśli ustawisz break pointa za - przelatuje bezproblemowo. Ciekawe dlaczego tak się dzieje?


    //edyt ...pisałem nie widząc ostatniego wpisu, stąd ta powtórka
  • REKLAMA
  • #8 10694020
    herszt
    Poziom 18  
    Posty: 386
    Pomógł: 2
    Ocena: 1
    Witam ponownie. Troszkę pozmieniałem kod. Już mi się nigdzie nie zawiesza program, jednak za żadne skarby nie chce mi wykonać obsługi przerwania co sekundę. Wydaje mi się, że wszystko napisałem tak jak powinno być po kolei:

    
    void Configuration_RTC(void)
    {
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
      	PWR_BackupAccessCmd(ENABLE);
      	BKP_DeInit();
    	RTC_EnterConfigMode();
    	RCC_LSEConfig(RCC_LSE_ON);
    	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){};
    	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    	RCC_RTCCLKCmd(ENABLE);
    	RTC_WaitForSynchro();
    	RTC_WaitForLastTask();
    	RTC_SetPrescaler(32767);
    	RTC_WaitForLastTask();
    	RTC_ExitConfigMode();
    	RTC_ITConfig(RTC_IT_SEC, ENABLE);
    	RTC_WaitForLastTask();
    }
    


    Funkcje do obsługi przerwań:
    
    void EXTI0_IRQHandler(void)
    {
    	GPIO_SetBits(GPIOB, GPIO_Pin_8);
    	EXTI_ClearITPendingBit(EXTI_Line0);
    
    }
    
    void RTC_IRQHandler(void)
    {
    	GPIO_ResetBits(GPIOB, GPIO_Pin_8);
    	RTC_ClearITPendingBit(RTC_IT_SEC);
    	RTC_WaitForLastTask();
    }
    


    EXTI0 wykonuje się bez problemu, natomiast RTC nie chce pomimo moich najszczerszych chęci (postawiłem tam breakpointa). Wiem, że najlepszą opcją jest napisanie tego na rejestrach. Jednak w przypadku tego programu wyjątkowo uparłem się na te nieszczęsne biblioteki. Nawet próbowałem znaleźć jakieś rozwiązanie w książce pana Paprockiego. Bez rezultatu. Może coś tutaj przeoczam?

    z góry dzięki
    pozdrawiam
    herszt
  • REKLAMA
  • #9 10694074
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    Jeszcze musisz skonfigurować NVIC, ale nie wiem jak to zrobić w tej rewelacyjnej bibliotece.

    Generalnie to masz przykład w przykładach (:)) do tej biblioteki jak skonfigurować RTC z przerwaniami.
  • #11 10694175
    herszt
    Poziom 18  
    Posty: 386
    Pomógł: 2
    Ocena: 1
    gaskoin napisał:
    Jeszcze musisz skonfigurować NVIC, ale nie wiem jak to zrobić w tej rewelacyjnej bibliotece.

    Generalnie to masz przykład w przykładach (:)) do tej biblioteki jak skonfigurować RTC z przerwaniami.


    NVIC skonfigurowałem - EXTI0 jest wykonywane.

    
    void NVIC_Conf()
    {
    	NVIC_InitTypeDef NVIC_InitStruct;
    	GPIO_InitTypeDef GPIO_InitStruct;
    	EXTI_InitTypeDef EXTI_InitStruct;
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    
    	GPIO_ResetBits(GPIOB, GPIO_Pin_8);
    	
    	GPIO_Init(GPIOB, &GPIO_InitStruct);
    
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    
    	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQChannel;
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
    	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_Init(&NVIC_InitStruct);
    
    	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    	GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    
    	EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
    	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    	EXTI_Init(&EXTI_InitStruct);
    }
    


    Właśnie próbowałem ostatecznie zasięgnąć przykładów i _wydaje_ mi się, że niczego nie pominąłem. Ale nadal nie mogę uruchomić tego przerwania.

    z góry dzięki
    pozdrawiam
    herszt
  • #12 10694189
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    Ale musisz skonfigurować jeszcze NVIC dla RTC czego u Ciebi nie widzę.

    Freddie Chopin napisał:
    Konfiguracja NVIC nie jest częścią SPL tylko CMSISa.


    Jednak i tutaj istnieją te cudaśne struktury i jakieś funkcje inicjalizacyjne :) Chyba nie powiesz mi, że są z CMSISa i też tak konfigurujesz przerwania bo chyba walne :P
    A herszt się uparł na te biblioteki, nie wiedzieć czemu. W przeciwnym wypadku bym podał jak to zrobić po ludzku.
  • #13 10694210
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    gaskoin napisał:
    Jednak i tutaj istnieją te cudaśne struktury i jakieś funkcje inicjalizacyjne :) Chyba nie powiesz mi, że są z CMSISa i też tak konfigurujesz przerwania bo chyba walne :P

    Damn, faktycznie też jest coś od tego w SPL. Ja używam tylko NVIC_EnableIRQ, a to akurat z CMSISa [; A że są jakieś inne funkcje to nawet nie wiedziałem, bo po co one komu [;

    4\/3!!
  • Pomocny post
    #14 10694604
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    
    static void NVIC_Configuration(void)
    {
      NVIC_InitTypeDef NVIC_InitStructure;
    
      /* Configure one bit for preemption priority */
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    
      /* Enable the RTC Interrupt */
      NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    }
    



    RTC_WaitForLastTask(); w obsłudze jest niepotrzebne
  • #15 10694869
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    Nie kapuje tego, czemu nie:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Tylko te wszystkie cuda? :)
  • #16 10694901
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    Też nie kapuje dlatego nie używam :) ..funkcje skopiowałem z działającego przykładu bez zbytniego się zagłębiania
  • #17 10697882
    herszt
    Poziom 18  
    Posty: 386
    Pomógł: 2
    Ocena: 1
    Witam,

    udało mi się wszystko w końcu uruchomić. Skorzystałem z dodatkowego kodu kolegi @starob. Jednak nie było to takie proste. Jak się okazało miałem wersję 2.x tych cudownych bibliotek, a tam nie było zdefiniowanego RTC_IRQn.
    Trochę się uparłem na te biblioteki ze względu na książkę, którą posiadam (w przykładach do RTC właśnie nie było fragmentu kolegi @starob), ale zaczynam dostrzegać, że ich uniwersalność jest zarazem dość sporą wadą.

    dzięki jeszcze raz
    pozdrawiam
    herszt

Podsumowanie tematu

✨ W dyskusji poruszono problem konfiguracji RTC w mikrokontrolerach STM32, z wykorzystaniem bibliotek dostarczonych przez producenta. Użytkownik napotkał trudności z inicjalizacją RTC, co prowadziło do zawieszania się programu. Uczestnicy sugerowali różne podejścia, w tym użycie rejestrów zamiast funkcji bibliotecznych oraz konieczność poprawnej konfiguracji rejestrów Backup i NVIC. Wskazano na istotność resetowania rejestrów Backup oraz włączenia dostępu do domeny BKP. Użytkownik ostatecznie zdołał uruchomić RTC, korzystając z dodatkowego kodu, jednak napotkał problemy z wersją bibliotek, która nie definiowała RTC_IRQn.
Wygenerowane przez model językowy.
REKLAMA