Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[STM32][C] TIM1 taktowany dwa razy niższą częstotliwością

y0yster 05 Lip 2011 23:12 3083 23
  • #1 05 Lip 2011 23:12
    y0yster
    Poziom 19  

    Witam,

    Napotkałem pewien problem. Otóż, w obsłudze przerwania od timer'a mam zmianę stanu lini. Generuję prostokąt.

    Konfiguracja układu to:
    Zewnętrzny kwarc: 8Mhz
    oraz RCC skonfigurowane w następujący sposób:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Procek powinien być więc taktowany prędkością 24MHz.

    Timer mam skonfigurowany w następujący sposób:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Z wyliczeń częstotliwość przerwań od TIM1 powinna wynosić:
    24MHz/(23999 + 1) = 1kHz

    Niestety na oscyloskopie podpiętym do wyjścia stan wysoki "trwa" 500Hz, częstotliwość jest 2 razy mniejsza. W czym może leżeć problem?

    0 23
  • #2 06 Lip 2011 07:27
    felekfala
    Poziom 19  

    Odpowiedź jest umieszczona w RM str n84, 85 (wersja z 1072str):

    The timer clock frequencies are automatically fixed by hardware. There are two cases:
    1. if the APB prescaler is 1, the timer clock frequencies are set to the same frequency as
    that of the APB domain to which the timers are connected.
    2. otherwise, they are set to twice (×2) the frequency of the APB domain to which the timers are connected.

    Czyli jeśli taktujesz magistralę APB z częstotliwością podzielną przez 3 czyli 24MHz to częstotliwość taktowania TIMera będzie dwa razy mniejsza czyli 12MHz.

    0
  • #3 06 Lip 2011 07:34
    y0yster
    Poziom 19  

    felekfala napisał:
    Odpowiedź jest umieszczona w RM str n84, 85 (wersja z 1072str):

    The timer clock frequencies are automatically fixed by hardware. There are two cases:
    1. if the APB prescaler is 1, the timer clock frequencies are set to the same frequency as
    that of the APB domain to which the timers are connected.
    2. otherwise, they are set to twice (×2) the frequency of the APB domain to which the timers are connected.

    Czyli jeśli taktujesz magistralę APB z częstotliwością podzielną przez 3 czyli 24MHz to częstotliwość taktowania TIMera będzie dwa razy mniejsza czyli 12MHz.


    Tylko ja nie dzielę częstotliwości APB przez 3. Mój procek to STM32F100RB, który może być maksymalnie taktowany z częstotliwością równą 24MHz. Jeśli źle coś rozumiem, proszę popraw.

    Zgodnie z:

    felekfala napisał:

    The timer clock frequencies are automatically fixed by hardware. There are two cases:
    1. if the APB prescaler is 1, the timer clock frequencies are set to the same frequency as
    that of the APB domain to which the timers are connected.


    Powinienem mieć zegar timera taktowany z częstotliwością 24MHz.

    Zauważyłem też, że jeśli ustawię

    Kod: c
    Zaloguj się, aby zobaczyć kod


    , a później

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nie widzę, żadnej różnicy w działaniu timera. Co się zgadza z powyższym opisem. Natomiast dlaczego częstotliwość jest równa 12MHz, a nie 24MHz?

    0
  • #4 06 Lip 2011 07:47
    felekfala
    Poziom 19  

    W RM napisano że jeśli częstotliwość APB1 jest mniejsza niż 72 MHZ, APB2 36MHz. RM nie wyróżnia tutaj jakich rodzin to uC dotyczy stąd w wnioskuje, że jeśli Twój procek ma mniejszą częstotliwość taktowania, to traktujesz to jak byś miał już podzieloną częstotliwość i tak jak napisali taktowanie timera będzie dwa razy mniejsze niż magistrali.

    0
  • #5 06 Lip 2011 07:51
    y0yster
    Poziom 19  

    felekfala napisał:
    W RM napisano że jeśli częstotliwość APB1 jest mniejsza niż 72 MHZ, APB2 36MHz. RM nie wyróżnia tutaj jakich rodzin to uC dotyczy stąd w wnioskuje, że jeśli Twój procek ma mniejszą częstotliwość taktowania, to traktujesz to jak byś miał już podzieloną częstotliwość i tak jak napisali taktowanie timera będzie dwa razy mniejsze niż magistrali.


    Mógłbyś przytoczyć fragment z miejsca w RM gdzie to znalazłeś? Bo do końca nie rozumiem co miałeś na myśli pisząc:

    felekfala napisał:
    W RM napisano że jeśli częstotliwość APB1 jest mniejsza niż 72 MHZ, APB2 36MHz.

    0
  • #7 06 Lip 2011 07:57
    y0yster
    Poziom 19  

    Tak są opisane 2 przypadki:
    1. Jeśli prescaler APB jest ustawiony na 1, to zegar timera jest ustawiany na tą samą częstotliwość co APB
    2. W przeciwnym przypadku są mnożone 2 razy niż częstotliwość APB

    U mnie APB jest równe 24MHz, chyba, że coś nie tak rozumiem.

    0
  • #8 06 Lip 2011 08:01
    felekfala
    Poziom 19  

    felekfala napisał:
    W RM napisano że jeśli częstotliwość APB1 jest mniejsza niż 72 MHZ, APB2 36MHz. RM nie wyróżnia tutaj jakich rodzin to uC dotyczy stąd w wnioskuje, że jeśli Twój procek ma mniejszą częstotliwość taktowania, to traktujesz to jak byś miał już podzieloną częstotliwość i tak jak napisali taktowanie timera będzie dwa razy mniejsze niż magistrali.


    Natomiast w 100% nie jestem tego pewien i tak jak napisałem wnioskuje ponieważ RM nie wyróżnia innych przypadków.

    0
  • #9 06 Lip 2011 08:04
    y0yster
    Poziom 19  

    Na tych stronach, które podałeś nie mogę znaleźć:

    felekfala napisał:
    W RM napisano że jeśli częstotliwość APB1 jest mniejsza niż 72 MHZ, APB2 36MHz.


    Chodzi Ci o to, że jeśli APB1 jes mniejsze niż 72MHz to APB2 jest równe 36MHz?

    0
  • #10 06 Lip 2011 08:08
    felekfala
    Poziom 19  

    Wcześniej sie pomyliłem przepraszam.
    Dla APB2 f maks to 72MHz, a dla APB1 to 36MHz i jeśli taktowanie jest mniejsze niż te wartości to timery są taktowane z f 2x mniejszą niż magistrale.

    Several prescalers allow the configuration of the AHB frequency, the high speed APB
    (APB2) and the low speed APB (APB1) domains. The maximum frequency of the AHB and
    the APB2 domains is 72 MHz. The maximum allowed frequency of the APB1 domain is
    36 MHz. The SDIO AHB interface is clocked with a fixed frequency equal to HCLK/2

    0
  • #11 06 Lip 2011 08:21
    y0yster
    Poziom 19  

    Tak, wiem o tym, że maks. częst. APB2 to 72MHz, a APB1 to 36MHz. Natomiast, gdzie w fragmencie, który przytoczyłeś jest napisane, ze timer jest taktowany 2 razy mniejszą częstotliwością?

    Dwa przypadki, gdzie częstotliwość timera jest brana pod uwagę (i ustawiana) to:

    Cytat:
    1. Jeśli prescaler APB jest ustawiony na 1, to zegar timera jest ustawiany na tą samą częstotliwość co APB
    2. W przeciwnym przypadku są mnożone 2 razy niż częstotliwość APB


    Natomiast:

    felekfala napisał:
    Several prescalers allow the configuration of the AHB frequency, the high speed APB
    (APB2) and the low speed APB (APB1) domains. The maximum frequency of the AHB and
    the APB2 domains is 72 MHz. The maximum allowed frequency of the APB1 domain is
    36 MHz. The SDIO AHB interface is clocked with a fixed frequency equal to HCLK/2


    Nie widzę, żeby to miało z tym jakiś związek.

    0
  • #12 06 Lip 2011 08:25
    felekfala
    Poziom 19  

    Wszystko już napisałem:

    felekfala napisał:
    Odpowiedź jest umieszczona w RM str n84, 85 (wersja z 1072str):

    The timer clock frequencies are automatically fixed by hardware. There are two cases:
    1. if the APB prescaler is 1, the timer clock frequencies are set to the same frequency as
    that of the APB domain to which the timers are connected.
    2. otherwise, they are set to twice (×2) the frequency of the APB domain to which the timers are connected.

    Czyli jeśli taktujesz magistralę APB z częstotliwością podzielną przez 3 czyli 24MHz to częstotliwość taktowania TIMera będzie dwa razy mniejsza czyli 12MHz.


    The timer clock frequencies are automatically fixed by hardware. There are two cases:
    i dalej masz wymienione właśnie te przypadki.

    0
  • #13 06 Lip 2011 08:30
    y0yster
    Poziom 19  

    Ok, już widzę dlaczego trzymasz się tak kurczowo tej wersji:

    felekfala napisał:

    Czyli jeśli taktujesz magistralę APB z częstotliwością podzielną przez 3 czyli 24MHz to częstotliwość taktowania TIMera będzie dwa razy mniejsza czyli 12MHz.


    Tylko ja nie dzielę częstotliwości APB przez 3. Taktowałbym ją z 3 razy mniejszą częstotliwością gdybym ustawił dzielnik. Natomiast go nie ustawiłem.

    Druga rzecz jest taka, że tyczy to się tylko ustawień programowych (ustawianie dzielnika). Sprzętowo mogę maksymalnie 24MHz. Według mnie, tylko wymuszone podzielenie (programowe) przez 3 spowodowało by to o czym mówisz. Chyba, że jest inaczej, a w Reference Manual nie udało mi się znaleźć takiego przypadku.

    Druga sprawa jest taka, że jeśli bym ustawił prescaler na APB, to częstotliwość zegara (timer'a) powinna być 2 razy większa, a nie mniejsza zgodnie z RM. Oczywiście do granic maksymalnych częstotliwości.

    0
  • #14 06 Lip 2011 20:42
    radzick
    Poziom 10  

    Gdzie ustawiasz TIM_Clock_Division_CKD? Powinno być na TIM_CKD_DIV1 (0) - to są bity CKD w TIM1->CR1. Być może tutaj masz ustawione dzielenie przez dwa.

    Co do ustawień częstotliwości taktowania procesora to czy masz możliwość to jakoś sprawdzić? Żeby mieć pewność, że ustawiłeś 24 MHz albo coś innego?

    Z tego co widzę to na elektrodzie jest to mało spotykane, ale ja korzystam z biblioteki standardowej STM. I tam procedura przestawienia zegara wygląda tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Ogólnie wolę kod, który coś mi powie za pół roku... A te kilka cykli przy inicjacji to niewielki koszt. Nawiasem mówiąc korzystam z tego samego procka i udało mi się z niego wyciągnąć 64 MHz, ale był trochę niestabilny. Przy 32 MHz spokojnie jest w stanie pracować.

    0
  • Pomocny post
    #15 06 Lip 2011 22:34
    BoskiDialer
    Poziom 34  

    1/ nadużywanie ustawiania bitów "|=". Nigdzie nie ma odpowiadającego wstępnego kasowania bitów, które są ustawiane, więc z góry zakładam, że ten kod może być zawodny. Najlepszym rozwiązaniem jest pojedyncze wpisanie do rejestru jednej wartości zawierającej żądane ustawienia wszystkich pól.

    2/

    Kod: C
    Zaloguj się, aby zobaczyć kod

    Na timer wchodzi zegar o częstotliwości 1kHz (dzielnik /24000). Ze względu na ARR=1, licznik będzie miał wartość na przemian 0,1,0,1... częstotliwość przepełniania się licznika wynosi 500Hz.


    Jako ciekawostka: Często używam timerów do generowania przebiegów PWM dla serw modelarskich, tutaj mam już wypracowane rozwiązanie najlepsze: za pomocą PSC zbijam częstotliwość do dokładnie 2MHz, do ARR wpisuję 39999 (jeden okres timera = 20ms), wtedy ustawieniami kanałów zmieniam długość impulsów. Prescaler warto użyć do zbicia zegara do jakiegoś sensownego poziomu ale wyższego niż żądana częstotliwość czegokolwiek. Wtedy przy pomocy ARR łatwo ustawić czas przepełnienia timera. Nie warto odwracać roli PSC i ARR - traci się wgląd w stan timera (brak możliwości odczytu ukrytego licznika zawartego w prescalerze).

    0
  • Pomocny post
    #16 06 Lip 2011 22:37
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Czy aby na pewno częstotliwość przerwań od timera powinna wynosić 1kHz? Skoro masz (w teorii) 24MHz podzielone przez 24000 (preskaler), to faktycznie zegar dochodzący do samego timera będzie równy 1kHz, ale wg mnie przerwanie timera będzie co dwa jego cykle, bo timer liczy tak:
    0 ... 1 (przerwanie) ... 0 ... 1 (przerwanie) ...

    EDIT: sekundy... normalnie sekundy...

    4\/3!!

    0
  • #17 06 Lip 2011 22:41
    y0yster
    Poziom 19  

    radzick napisał:
    Gdzie ustawiasz TIM_Clock_Division_CKD? Powinno być na TIM_CKD_DIV1 (0) - to są bity CKD w TIM1->CR1. Być może tutaj masz ustawione dzielenie przez dwa.


    Co do bitów CKD, to są domyślnie ustawione na 0x00 i takie pozostają, nie zmieniam ich. Natomiast Jeśli chodzi o CKD, czy to przypadkiem nie odnosi się do zewnętrznego wyzwalania timera?

    BoskiDialer napisał:
    1/ nadużywanie ustawiania bitów "|=". Nigdzie nie ma odpowiadającego wstępnego kasowania bitów, które są ustawiane, więc z góry zakładam, że ten kod może być zawodny. Najlepszym rozwiązaniem jest pojedyncze wpisanie do rejestru jednej wartości zawierającej żądane ustawienia wszystkich pól.


    Dzięki za uwagę. Zauważyłem, że podczas debugowania niektóre rzeczy zostają (w innych odrębnych przypadkach).

    BoskiDialer napisał:
    Na timer wchodzi zegar o częstotliwości 1kHz (dzielnik /24000). Ze względu na ARR=1, licznik będzie miał wartość na przemian 0,1,0,1... częstotliwość przepełniania się licznika wynosi 500Hz.


    A czy jest możliwość generowania:

    0, przerwanie; 0, przerwanie .... ?

    Freddie Chopin napisał:

    EDIT: sekundy... normalnie sekundy...


    Minuta! :P

    BoskiDialer napisał:
    Jako ciekawostka: Często używam timerów do generowania przebiegów PWM dla serw modelarskich, tutaj mam już wypracowane rozwiązanie najlepsze: za pomocą PSC zbijam częstotliwość do dokładnie 2MHz, do ARR wpisuję 39999 (jeden okres timera = 20ms), wtedy ustawieniami kanałów zmieniam długość impulsów. Prescaler warto użyć do zbicia zegara do jakiegoś sensownego poziomu ale wyższego niż żądana częstotliwość czegokolwiek. Wtedy przy pomocy ARR łatwo ustawić czas przepełnienia timera. Nie warto odwracać roli PSC i ARR - traci się wgląd w stan timera (brak możliwości odczytu ukrytego licznika zawartego w prescalerze).


    Jak bawiłem się serwami modelarskimi (zajmuję się również modelarstwem lotniczym RC) to równe 20ms jako okres dla PWM'a dla grona moich serw to za mało. Szeżej opisywałem to na swojej stronie. Prawdę mówiąc to jak (odbiornik modelarski) wysterowuje odbiega od normalnego impulsu PWM. Najpierw stan wysoki, a potem ok. 20ms stanu niskiego.

    0
  • Pomocny post
    #18 06 Lip 2011 22:44
    BoskiDialer
    Poziom 34  

    y0yster napisał:
    0, przerwanie; 0, przerwanie .... ?

    Niestety nie.. Z jednej strony dokumentacja mówi, że timer idzie po wszystkich wartościach od 0 do ARR, z drugiej strony mówi, że timer jest zablokowany gdy ARR==0. Moja rada: zamienić PSC i ARR: PSC=0, ARR=23999. Timer będzie szedł z pełną prędkością zegara, a przerwanie i tak będzie co 1ms.

    0
  • #19 06 Lip 2011 22:51
    Freddie Chopin
    Specjalista - Mikrokontrolery

    y0yster napisał:
    Dzięki za uwagę. Zauważyłem, że podczas debugowania niektóre rzeczy zostają (w innych odrębnych przypadkach).

    Jeśli używasz standardowych konfigów do OpenOCD, to dodaj do jego wywołania coś takiego:
    -c "reset_config trst_and_srst"
    Domyślnie OpenOCD zakłada, że JTAG nie ma pinów resetu i w przypadku Cortex-M3 resetuje go specjalnym rejestrem rdzenia. Reset taki jednak NIE jest pełnym resetem (nie czyści pamięci, peryferiów itd.). Jeśli JTAG ma zdefiniowane piny resetu, to OpenOCD będzie używało resetu sprzętowego, który wszystko wyczyści jak należy.

    Szczegóły tych mechanizmów są do znalezienia w dokumentacji OpenOCD (komenda "cortex_m3 reset_config"), przydługawa debata jest gdzieś na liście dyskusyjnej.

    4\/3!!

    0
  • #20 06 Lip 2011 22:55
    y0yster
    Poziom 19  

    Freddie Chopin napisał:
    y0yster napisał:
    Dzięki za uwagę. Zauważyłem, że podczas debugowania niektóre rzeczy zostają (w innych odrębnych przypadkach).

    Jeśli używasz standardowych konfigów do OpenOCD, to dodaj do jego wywołania coś takiego:
    -c "reset_config trst_and_srst"
    Domyślnie OpenOCD zakłada, że JTAG nie ma pinów resetu i w przypadku Cortex-M3 resetuje go specjalnym rejestrem rdzenia. Reset taki jednak NIE jest pełnym resetem (nie czyści pamięci, peryferiów itd.). Jeśli JTAG ma zdefiniowane piny resetu, to OpenOCD będzie używało resetu sprzętowego, który wszystko wyczyści jak należy.

    Szczegóły tych mechanizmów są do znalezienia w dokumentacji OpenOCD (komenda "cortex_m3 reset_config"), przydługawa debata jest gdzieś na liście dyskusyjnej.

    4\/3!!


    Niestety nie używam OpenOCD. Ale to dobre miejsce na mały apel :].
    Posiadam STM32-DISCOVERY, który jest debugowany poprzez SWD. Może OpenOCD niedługo będzie spierał również to.

    0
  • #21 06 Lip 2011 23:11
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Bardzo niedługo - prace nad implementacją SWD trwają i są bardzo zaawansowane. Zasadnicza część kodu odpowiedzialnego za SWD stworzona została przez Polaka (; Więcej szczegółów można odnaleźć na liście dyskusyjnej <:

    Niedługo (~1miesiąc) będzie wersja OpenOCD 0.5.0 wydana bez żadnych przełomowych nowości, a potem już prace nad SWD ruszą pełną parą - teraz są nieco przystopowane, aby wydana wersja była stabilna.

    4\/3!!

    0
  • #22 06 Lip 2011 23:19
    nsvinc
    Poziom 35  

    Jednego tylko nie rozumiem... czemu prace nad obsługą SW trwają tak długo? Przecież sam protokół jest naprawdę prosty, i lekko przypomina half-duplex SPI. Czemu od ponad roku trwa bujanka wokół tego tematu, skoro kompatybilność SW z JTAG jest praktycznie 100%, a po prostu bity są przesyłane inaczej?...

    0
  • #23 06 Lip 2011 23:33
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Projekty open-source mają to do siebie, że rozwijają się wtedy, jeśli ktoś chce im poświęcić swój czas. Protokół może i jest prosty, ale aby stworzyć dobry, uniwersalny, czytelny i sprawny kod to jednak trochę trzeba się naklepać. Dodatkowo jeden z bardzo aktywnych programistów OpenOCD, działający właśnie na polu rozszerzenia OpenOCD o obsługę SWD (przy okazji też programista jądra Linuxa) zmarł kilka miesięcy temu...

    Jest też kwestia potrzeby takiego SWD. Jest fajne, ale...
    1. To tak naprawdę nowość
    2. Wiele kontrolerów obsługujących SWD obsługuje też JTAGa
    3. Wiele JTAGów nie obsługuje "wprost" SWD

    Nie ma co szukać powodów dla których jest tak, a nie inaczej, tylko trzeba się pogodzić z open-source'ową rzeczywistością.

    4\/3!!

    0