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][C] Problem z uruchomieniem oscylatora LSE dla wewnętrznego RTC

csdominik 09 Lis 2010 00:46 4153 14
REKLAMA
  • #1 8720500
    csdominik
    Poziom 11  
    Posty: 43
    Pomógł: 3
    Witam, jakiś czas temu założyłem temat dotyczący komunikacji uC z DS1307 za pomocą I2C (https://www.elektroda.pl/rtvforum/topic1812072.html) jako że nie udało mi się tego zrobić aż do teraz - a potrzebuję RTC na gwałt, postanowiłem uruchomić wewnętrzny RTC.

    Przeglądałem kilka przykładów (w tym te od ST, oraz przykłady z książki o STM32 od Pana Paprockiego). I niestety nie mogę włączyć oscylatora LSE. Szczerze mówiąc nie wiem dlaczego. Postępowałem zgodnie z instrukcjami - dodałem odpowiednie komendy dotyczące RCC, NVIC (docelowo, przerwanie od RTC co sekundę) ustawiłem preskaler itd. Niestety kontroler zatrzymuję się w niżej zaznaczony miejscu.
    Próbowałem zmieniać podłączone oscylatory - i przy LSI oraz HSE/128 debuger zatrzymuje się na "RTC_WaitForSynchro();"
    Jeśli ktoś spotkał się z tym problemem - i wie jak temu zaradzić, proszę o porady.
    Pozdrawiam Dominik
    Ustawienia RTC oraz kolejność inicjalizacji:
    Cytat:

    void RTC_Configuration(void)
    {
    // Wlaczenie oscylatora LSE
    /* oraz inne próby
    RCC_LSEConfig(RCC_LSE_ON);
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);



    // LSE bedzie zrodlem sygnalu zegarowego dla RTC
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    */
    //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // PRÓBA Z LSI
    RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128); // ORAZ Z HSE/128
    // Wlaczenie taktowania RTC
    RCC_RTCCLKCmd(ENABLE);

    // Czekaj na synchronizacje
    RTC_WaitForSynchro();

    // Czekaj na zakonczenie operacji
    RTC_WaitForLastTask();

    // Wlacz przerwanie od RTC (co 1s)
    RTC_ITConfig(RTC_IT_SEC, ENABLE);

    RTC_WaitForLastTask();

    // Okres RTC bedzie wynosil 1s
    RTC_SetPrescaler(32767); // RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)

    RTC_WaitForLastTask();

    }
    void SystemInit2(void) // tutaj pokazana kolejnosc
    {
    RCC_Configuration();
    NVIC_Configuration();
    EXTI_Configuration();
    GPIO_Configuration();
    RTC_Configuration();
    }

    Pozostałe:
    Cytat:

    void RCC_Configuration(void)
    {
    ErrorStatus HSEStartUpStatus;

    RCC_DeInit(); // reset ustawień RCC
    RCC_HSEConfig(RCC_HSE_ON); // Wlacz HSE
    HSEStartUpStatus = RCC_WaitForHSEStartUp(); //czekaj az HSE bedzie gotowy
    if(HSEStartUpStatus == SUCCESS)
    {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    FLASH_SetLatency(FLASH_Latency_2); // tu 0 na 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);
    } /* else { } */

    // WŁĄCZAM PORTY GPIO:
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
    //WŁĄCZAM RCC DLA DRUGICH OPCJI PORTÓW.
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    RCC_ClearFlag();
    }

    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;

    #ifdef VECT_TAB_RAM
    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
    #else
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    #endif

    // TODO Wlacz przerwanie od IRQ4 (PA4)
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // TODO WLACZ PRZERWANIE OD RTC
    // Ustalenie grupy przerwan
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    // Wlacz przerwanie od RTC
    NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    }

    void EXTI_Configuration(void)
    {
    EXTI_InitTypeDef EXTI_InitStructure;

    EXTI_InitStructure.EXTI_Line = EXTI_Line4;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
    }



    Dodatkowe info:
    Atollic TrueSTUDIO + (ST-Link) + płyta z stm32f103VB
  • REKLAMA
  • #2 8875163
    dan00
    Poziom 2  
    Posty: 2
    Aby skonfigurować niektóre rejestry RTC należy najpierw odblokować dostęp do rejestrów chronionych
    
    RCC_APB1PeriphClockCmd (RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, ENABLE);
    PWR_BackupAccessCmd(ENABLE);// włączenie dostępu do rejestrów chronionych
    RCC_LSICmd(ENABLE);					// Włącz LSI
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);	//LSI źródłem zegara RTC
    RCC_RTCCLKCmd(ENABLE);				//włączenie taktowania dla RTC
    PWR_BackupAccessCmd(DISABLE);
    RCC_APB1PeriphClockCmd (RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, DISABLE);


    Aby móc skonfigurować preskaler należy najpierw włączyć tryb konfiguracji rtc
    RTC_EnterConfigMode();	
    RTC_SetPrescaler(32767);
    RTC_ExitConfigMode();


    Oczywiście po niektórych operacjach należy użyć
    RTC_WaitForSynchro();
    RTC_WaitForLastTask();

    ale aby te funkcje działały prawidłowo najpierw RTC musi działać tzn mieć określone źródło sygnału zegarowego oraz włączony określony zegarek np LSI, LSE

    Proszę używać znaczników code.
    Robak
  • REKLAMA
  • #3 8879767
    hardtmuth
    Poziom 20  
    Posty: 464
    Pomógł: 5
    Ocena: 30
    Mialem kiedys tez problem z zatrzymywaniem sie programu w tym samym miejscu co u Ciebie.

    Sprawdzialem i okazalo sie, ze kwarc zegarkowy nie ruszal, procek nie byl dobrze przylutowany, byl brak polaczenia pomiedzy kwarcem, a nozkami procesora.

    Przyklady STM`a od RTC na pewno chodza dobrze, dodatkowo zobacz inny przyklad z RTC + kalendarz.
  • #4 8880096
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #6 8881745
    hardtmuth
    Poziom 20  
    Posty: 464
    Pomógł: 5
    Ocena: 30
    Co do kwarca, sam chyba mam nawet 22pF i rusza rowniez. Bez kwarca tez potrafi nawet ruszyc. Dokladnosc, nie wiem jaka, bo nie mialem jeszcze okazji ;)
  • #7 9016905
    maciek11
    Poziom 17  
    Posty: 299
    Pomógł: 3
    Ocena: 7
    Dołączę się do tematu, bo mam podobny problem z tą różnicą że kwarc przez długi czas działał. Od pewnego czasu układ ma jednak problem z wystartowaniem. Zapętla się na synchronizacji. Czasem jak dotknę PCB w okolicach kwarca to układ ruszy. Luty na płytce były ok, ale na wszelki wypadek poprawiłem jeszcze raz. Jutro/dzisiaj :D zmienię te kondensatory na 6p i zobaczę czy pomogło. W razie czego na jeszcze jakąś podpowiedź mogę liczyć?
  • #8 9017240
    hardtmuth
    Poziom 20  
    Posty: 464
    Pomógł: 5
    Ocena: 30
    Sprobuj ktoregos z przykladow od STM`a. Tzn. wez z niego proces inicjalizacji.
  • #9 9017299
    maciek11
    Poziom 17  
    Posty: 299
    Pomógł: 3
    Ocena: 7
    Ok spróbuję. Najgorsze że to wcześniej działało, więc to nie powinna być wina kodu ale i tak to sprawdzę.
  • REKLAMA
  • #10 9017308
    hardtmuth
    Poziom 20  
    Posty: 464
    Pomógł: 5
    Ocena: 30
    Tez tak mialem, potem okazywalo sie, ze jednak cos zmienilem.

    Rob kopie wersji co jakis czas, przynajmniej codziennie nowa (chyba, ze nad tym siedzisz z doskoku, a nie codziennie).
    Dzieki temu zawsze mozesz wrocic do tego co bylo wczesniej. Wgrac stary kod i sprawdzic czy dzialalo dawniej.

    ExamDiff jest dobrym programem do porownywania plikow jesli nie widac na pierwszy rzut oka zmian.

    Tutaj przyklad mojej inicjalizacji (po usunieciu inita bkp i jego rejestrow bo to nie jest Ci potrzebne):
    
    NVIC_InitTypeDef NVIC_InitStructure;
    uint16_t WaitForOscSource;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    BKP_TamperPinCmd(DISABLE);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
    
    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);
    
    RCC_LSEConfig(RCC_LSE_ON);
    for(WaitForOscSource = 0; WaitForOscSource < 5000; WaitForOscSource++) { }
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}
    
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    RCC_RTCCLKCmd(ENABLE);
    RTC_WaitForSynchro();
    RTC_WaitForLastTask(); 
    RTC_ITConfig(RTC_IT_SEC, ENABLE);
    RTC_WaitForLastTask(); 
    RTC_SetPrescaler(32771); // wartosc po kalibracji wstepnej
    RTC_WaitForLastTask(); 
    RCC_ClearFlag();	
    


    To na pewno dziala, plytka STM3210B-EVAL.
  • #11 9027815
    maciek11
    Poziom 17  
    Posty: 299
    Pomógł: 3
    Ocena: 7
    Dzięki za kod, jeszcze dzisiaj go sprawdzę. Próbowałem na razie ze zmianą kondensatorów, ale nie pomogło. Dam znać jak zadziała ta Twoja procedurka.
  • #12 9032049
    maciek11
    Poziom 17  
    Posty: 299
    Pomógł: 3
    Ocena: 7
    Sprawdziłem działanie na Twoim kodzie. Niestety zapętla się na tym:

    
    while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}
    


    W funkcji RCC_GetFlagStatus jak RCC_FLAG jest sprawdzane i zawsze zwróci 1.

    ---

    Skompilowałem i wgrałem z powrotem ten sam kod, z którego jeszcze wczoraj układ nie chciał ruszyć. Tym razem układ wystartował bez problemu, a w tym projekcie żadnych zmian nie robiłem. Kurcze może jednak ze sprzętem jest jakiś problem :(
  • #13 9066639
    maciek11
    Poziom 17  
    Posty: 299
    Pomógł: 3
    Ocena: 7
    Normalnie ręce opadają. Jednego dnia zaprogramowałem układ i działał. Nic z nim nie robiłem przez kilka dni, a teraz znowu się podnieść nie chce. Na RTC się wiesza...
  • #14 9066869
    Konto nie istnieje
    Poziom 1  
  • #15 9066953
    maciek11
    Poziom 17  
    Posty: 299
    Pomógł: 3
    Ocena: 7
    Tak kondensatory zmienione na 6.8pF

Podsumowanie tematu

✨ Użytkownik ma problem z uruchomieniem oscylatora LSE dla wewnętrznego RTC w mikrokontrolerze STM32. Pomimo stosowania przykładów z dokumentacji ST oraz książek, kontroler zatrzymuje się na funkcji "RTC_WaitForSynchro()". Użytkownicy sugerują kilka rozwiązań, w tym odblokowanie rejestrów RTC, sprawdzenie połączeń kwarcu, a także użycie kondensatorów o pojemności 6pF. Wskazano również na możliwość problemów ze sprzętem, gdyż układ działał wcześniej bez problemów. Użytkownik rozważa również porównanie kodu z wcześniejszymi wersjami, aby zidentyfikować potencjalne zmiany, które mogły wpłynąć na działanie.
Wygenerowane przez model językowy.
REKLAMA