Ta strona używa ciasteczek (plików cookies), dzięki którym może działać lepiej. Dowiedz się więcejRozumiem i akceptuję
Odbierz rabat na filament!

Wartość zmiennej SystemCoreClock - STM32 Nucleo-F411RE, Standard Peripheral Library

Autor Wiadomość
draghan 




Posty: 26
Otrzymał 4 piw(a)
Programuję w:
C++, C
Należę do:
SKIP PG
Wysłany: 11-10-2017, 22:49   Wartość zmiennej SystemCoreClock - STM32 Nucleo-F411RE, Standard Peripheral Library

Cześć,
chciałbym się dowiedzieć, jaką wartość powinna mieć zmienna SystemCoreClock dla płytki STM32 Nucleo-F411RE wyjętej prosto z pudełka - czyli bez zainstalowanego zewnętrznego oscylatora.
Domyślnie (przez SWforSTM32) została wygenerowana wartość 100'000'000, co odpowiada 100 MHz:
Kod programu: Zaznacz cały
#if defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F412xG) || defined(STM32F413_423xx)
    uint32_t SystemCoreClock = 100000000;
#endif /* STM32F410xx || STM32F401xE || STM32F412xG || STM32F413_423xx */

Zdaje mi się, że jest to bzdura - owszem, na opakowaniu widnieje ładny napis "ARM Cortex-M4 100 MHz", jednak reference manual podaje że to jest maksymalna wartość taktowania.
Wrzuciłem tam program (najprostszy przykład z kursu Elvisa dla STM32 F1 z SysTick) mający migać LEDką z założonym interwałem 10 s i zmierzyłem czas świecenia diody. Wyszło mi że dioda świeci przez ok. 9 sekund. Niestety nie posiadam oscyloskopu żeby to dokładnie zmierzyć, ale 10 s to nie jest wyraźnie.
W data sheet znalazłem informację, że domyślnie jako HSI używany jest oscylator o f = 16 MHz, co nawet się zgadza z definicją makra:
Kod programu: Zaznacz cały
#if !defined  (HSI_VALUE)   
  #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */

Ustawiwszy SystemCore na HSI_VALUE dioda świeci przez ok. 15 sekund, co również wyraźnie nie jest równe 10 s :mrgreen: .

Moglibyście mnie naprowadzić, gdzie szukać informacji na ten temat?

EDIT:
Z tego co udało mi się prześledzić w kodzie, początkowa wartość tej zmiennej nie gra większej roli. Myślałem że jest to jedna z kluczowych zmiennych do działania systemu.
Funkcja RCC_GetClocksFreq() twierdzi, że źródłem taktów dla rdzenia jest PLL z tak dobranymi współczynnikami, że wychodzi w rozrachunku 100 MHz. I teraz pytanie: czy domyślny rezonator może być tak niedokładny? W dłuższym horyzoncie czasowym to bym zrozumiał, ale żeby w przeciągu 10 sekund stracić 10% dokładności... Trochę nie chce mi się w to wierzyć. :)

Warto przeczytać » Kurs elektroniki - #0 - Spis treści kursu!


Ostatnio zmieniony przez draghan 12-10-2017, 19:58, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
Elvis 



Posty: 1236
Pomógł: 90 razy
Otrzymał 229 piw(a)
Skąd: wawa
Programuję w:
C, asm
Wysłany: 12-10-2017, 20:55   

Możesz po prostu wywołać funkcję 
Kod programu: Zaznacz cały
SystemCoreClockUpdate()

Dzięki niej wartość SystemCoreClock zostanie ustawiona poprawnie.

Postaw piwo autorowi tego posta
 
 
draghan 




Posty: 26
Otrzymał 4 piw(a)
Programuję w:
C++, C
Należę do:
SKIP PG
Wysłany: 12-10-2017, 22:39   

Już wcześniej znalazłem tę funkcję. Tylko nie mogłem dokopać się do informacji, jak jest skonfigurowane taktowanie przy starcie kontrolera, stąd powstał temat. Przelatując debuggerem w trybie krokowym właśnie przez wspomnianą przez Ciebie funkcję do ustawiania wartości tej zmiennej nadrobiłem tę lukę w wiedzy.

Ponadto byłem przekonany, że wartość zmiennej SystemCoreClock wpływa na konfigurację taktowania mikrokontrolera, a okazuje się być odwrotnie - ona z ustawień zegara wynika.

Tak czy inaczej dziękuję za wskazówkę. :)

Postaw piwo autorowi tego posta
 
 
Elvis 



Posty: 1236
Pomógł: 90 razy
Otrzymał 229 piw(a)
Skąd: wawa
Programuję w:
C, asm
Wysłany: 12-10-2017, 23:00   

Skoro już dociekasz co z czego wynika, mogę Ci udzielić kolejnej wskazówki.
Poszukaj funkcji SystemInit jest w jednym z plików automatycznie dodanych do projektu.
Ta funkcja jest wywoływana przed main i właśnie w niej konfigurowany jest zegar mikroprocesora.
Po resecie, czyli niejako domyślnie wykorzystywany jest wbudowany rezonator - 16MHz HSI. Dopiero funkcja SystemInit uruchamia pętlę PLL oraz ustala docelowe taktowanie. Ta funkcja powinna też ustawiać wartość zmiennej SystemCoreClock, ale niestety tego nie robi, a wtedy łatwo o niespójność w kodzie.
Natomiast co do niedokładności generatora RC to 3% jest jak najbardziej możliwe, 10% to faktycznie trochę dużo, coś w programie jest pomieszane? Sprawdź też czy 100MHz jest dopuszczalne przy pętli PLL zasilanej z HSI. W przypadku stm32f103 było takie ograniczenie napisane małym drukiem - że PLL z HSE, czyli zewnętrznego generatora lub kwarcu może osiągać 72MHz, ale z HSI już tylko 64MHz.
Przy okazji warto zwrócić uwagę, że maksymalna prędkość to nie jedyna możliwa i słuszna. To trochę jak z samochodem, prędkość maksymalna to ważny parametr, ale czasem warto/trzeba jeździć wolniej.

Ostatnio popularny » Wytrzymałość materiałów - #1 - Wstęp teoretyczny


Postaw piwo autorowi tego posta
 
 
draghan 




Posty: 26
Otrzymał 4 piw(a)
Programuję w:
C++, C
Należę do:
SKIP PG
Wysłany: 13-10-2017, 18:42   

Elvis napisał/a:
Poszukaj funkcji SystemInit jest w jednym z plików automatycznie dodanych do projektu.
Ta funkcja jest wywoływana przed main i właśnie w niej konfigurowany jest zegar mikroprocesora.
Po resecie, czyli niejako domyślnie wykorzystywany jest wbudowany rezonator - 16MHz HSI. Dopiero funkcja SystemInit uruchamia pętlę PLL oraz ustala docelowe taktowanie. Ta funkcja powinna też ustawiać wartość zmiennej SystemCoreClock, ale niestety tego nie robi, a wtedy łatwo o niespójność w kodzie.

Dzięki. Przejrzałem sobie tę funkcję. Z niej wywoływana jest SetSysClock, gdzie siedzą wszystkie ustawienia o które mi chodziło.

Elvis napisał/a:
Natomiast co do niedokładności generatora RC to 3% jest jak najbardziej możliwe, 10% to faktycznie trochę dużo, coś w programie jest pomieszane?

Kazałem w SysTick_Handler wysyłać znak po UART do PC, gdzie uruchomiłem analizator pakietów. I ten wskazał mi, że interwał między otrzymywanymi znakami wynosi ok. 1 sekundę. Może jakoś koślawo to mierzyłem wcześniej, cholerka wie.

Elvis napisał/a:
Sprawdź też czy 100MHz jest dopuszczalne przy pętli PLL zasilanej z HSI. W przypadku stm32f103 było takie ograniczenie napisane małym drukiem - że PLL z HSE, czyli zewnętrznego generatora lub kwarcu może osiągać 72MHz, ale z HSI już tylko 64MHz.

Na szczęście (albo i nieszczęście) nie zauważyłem nigdzie takich niecnych dopisków.

Elvis napisał/a:
Przy okazji warto zwrócić uwagę, że maksymalna prędkość to nie jedyna możliwa i słuszna. To trochę jak z samochodem, prędkość maksymalna to ważny parametr, ale czasem warto/trzeba jeździć wolniej.

Czytałem, że przy używaniu ADC dobrze jest przemyśleć konfigurację PLL, żeby znaleźć złoty środek między optymalnym czasem pomiaru i optymalnie działającą resztą. Czy gdzieś jeszcze się to przydaje?

Postaw piwo autorowi tego posta
 
 
Elvis 



Posty: 1236
Pomógł: 90 razy
Otrzymał 229 piw(a)
Skąd: wawa
Programuję w:
C, asm
Wysłany: 14-10-2017, 09:01   

Jak chodzi o taktowanie mikrokontrolera to równie dobrze można odwrócić pytanie - a dlaczego chcemy używać maksymalnej prędkości? Dlatego że można? A może dlatego że tak było w przykładach?
Otóż z procesorami jest jak z samochodami - maksymalna prędkość nie jest jedyną i czasem warto pojeździć wolniej.
Dlaczego jeździmy wolniej samochodem? Bo przykładowo mniej wtedy zużywa paliwa - a procesor mniej prądu. Wbrew pozorom pędzący 100MHz stm32 to prawdziwe monstrum, ale i apetyt na paliwo (prąd) ma on znaczny. Jeśli zwolnimy do powiedzmy 50MHz zaoszczędzimy prawie połowę prądu (zależność jest z grubsza liniowa).
Kolejna sprawa w przypadku samochodów to bezpieczeństwo. Jazda 100km/h w terenie zabudowanym jest nie tylko nielegalna, ale i niebezpieczna. Mikrokonotrolery mają podobny problem - 100MHz to maksimum, przy wyższym taktowaniu układ może działać niepoprawnie. Ale nawet jeśli nie przekroczymy tej granicy, musimy mu dostarczyć idealne zasilanie 3.3V. Jeśli spadniemy np. do 3V może źle działać. Z drugiej strony przy niższej częstotliwości taktowania układ jest stabiliniejszy - może być zasilany słabiej odfiltrowanym lub niższym napięciem (np. bezpośrednio z baterii).
Musimy też pamiętać, że 100MHz to częstotliwość pracy rdzenia i niektórych peryferiów. Pozostałe pracują z połową tej częstotliwości, czyli 50MHz - albo i wolniej. Jeśli to one są krytyczne w naszym zastosowaniu, być może nie ma sensu taktować rdzenia szybciej, marnować prądu skoro i tak będziemy czekać na wolniejsze moduły (np. dane z UART-a).
Co ciekawe sama pamięć Flash, w której jest program nie pracuje z częstotliwością 100MHz. Jej maksymalne taktowanie to o ile pamiętam 25MHz. STM32 stosuje mikro-cache, pobiera na raz 4 instrukcje i dzięki temu rdzeń może czasem działać z pełną prędkością. Napisałem czasem, bo to prawda tylko jeśli program nie ma skoków/rozgałęzień. Co więcej takie buforowanie wprowadza pewien niedeterminizm - jeśli bardzo zależy nam na kontroli czasu wykonywania instrukcji, najlepiej zwolnić.
Jeszcze wracając do porównań samochodowych - wysoka prędkość to i hałas. Procesory nie hałasują, ale emitują zakłócenia - i znowu im szybciej pracują tym więcej emitują.
Wspomniałeś o ADC, to też dobry powód do wybrania innej niż maksymalna prędkość taktowania. Czasem taktując rdzeń wolniej możemy uzyskać wyższą prędkość pracy przetwornika A/C. Bywa też tak, że zależy nam na określonej częstotliwości próbkowania. Wtedy musimy tak dobrać częstotwliość pracy całego układu, żeby ADC mógł pobierać próbki z oczekiwaną częstotliwością.
Pewnie jest jeszcze więcej powodów używania innych niż maksymalna prędkość pracy - ale tych kilka przyszło mi do głowy.

Postaw piwo autorowi tego posta
 
 
Więcej szczegółów
Wystawiono 1 piw(a):
draghan
draghan 




Posty: 26
Otrzymał 4 piw(a)
Programuję w:
C++, C
Należę do:
SKIP PG
Wysłany: 14-10-2017, 21:21   

Elvis napisał/a:

Jak chodzi o taktowanie mikrokontrolera to równie dobrze można odwrócić pytanie - a dlaczego chcemy używać maksymalnej prędkości? Dlatego że można? A może dlatego że tak było w przykładach?

Mając szybkie auto, dobrze jest w pełni wykorzystywać jego możliwości. Poza samą frajdą mamy zysk w postaci szybciej pokonanej trasy lub przejechania większego dystansu w ograniczonym czasie.

Wiadomo, że wszystko zależy od docelowego zastosowania. Nad względami stabilności myślałem, ale nie wziąłem pod uwagę oszczędności energii ani ewentualnych zakłóceń. Fajnie że o tym wspomniałeś - łatwo o tym zapomnieć.

Postaw piwo autorowi tego posta
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Wersja do druku

Skocz do:  

Nie rozwiązałeś swojego problemu? Zobacz podobne tematy: [C] Sterowanie serwo... PWM na atmega32 w C... JTAG dla procesora A... Problem z programem...
lub przeszukaj forum po wybranych tagach: nucleof411re, spl, stm32, systemcoreclock


Powered by phpBB modified by Przemo © 2003 phpBB Group
Popularne kursy: Arduinopodstawy elektroniki