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

STM32F407 [C] bez SPL - TIM1 i zliczanie impulsów z pinu

17 Sty 2016 00:50 1209 12
  • Poziom 12  
    Od kilku dni walczę z ćwiczenie 8.4 z kursu: https://www.elektroda.pl/rtvforum/topic3111562-60.html#15238823

    W kursie jest kod dla F103, ja próbuję to przerobić dla wersji F407. Niestety bezowocnie.
    Sam timer, kiedy wyzwalać go sygnałem zegarowym, działa prawidłowo i włącza/wyłącza diody w procedurze przerwania.
    Niestety kiedy ma zliczać impulsy na pinie PA8, wtedy mam tylko mrugającą diodę sygnalizującą pracę SysTick.
    Dodam, że jest tutaj zastosowany trick. SysTick przełącza podciąganie dla pinu PA8 dzięki czemu nie trzeba stosować zewnętrznego generowania impulsów.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Update:
    w skrócie co ma robić program: ma zliczać impulsy z pinu PA8 przy pomocy TIM1 i po określonej ich liczbie wykonywać procedurę dla przerwania d TIM1.
  • Pomocny post
    Specjalista - Mikrokontrolery
    Całkiem źle programujesz timer. Kolejność:

    PSC,
    ARR,
    SMCR
    CCMRx
    CCER
    DIER
    CR1

    Główny błąd - to zaczynanie od CR1 - włączasz timer przed zaprogramowaniem go.

    Jeszcze taki drobiazg:
    TIM1->SR = (uint16_t) ~TIM_SR_UIF;

    - wyrzuć (uint16_t)
  • Poziom 12  
    Mam tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    i nadal nie działa z wyzwalaniem przez SysTick natomiast częściowo działa kiedy zwieram PA8 do masy. Częściowo dlatego, że dzieje się to po pięciu (z zakomentowanym preskalerem) ale po jakiejś przypadkowej liczbie zwarć, mniejszej niż pięć. Próbowałem eksperymentować z filtrowaniem bitami ICF w rejestrze CCMR1 ale akurat tutaj to już kompletnie nie wiem o robię.
  • Pomocny post
    Specjalista - Mikrokontrolery
    Dzieje się to po pięcu impulsach, a jedno zwarcie palcem generuje dowolną liczbę impulsów - typowo 2..3.

    Jeśli PA8 jest wejściem timera, to nie może być równocześnie wyjściem GPIO - przecież wyłączyłeś funkcję GPIO na PA8.
  • Poziom 12  
    Tutaj jest kod przykładu, który przerabiam dla swojego uC:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zdaję sobie sprawę, że zwieranie przewodem powoduje przypadkową liczbę zwarć.
  • Poziom 12  
    AAAAAAAA!

    :crazyeyes:

    Dziękuję :)

    1. Gdzie znaleźć informację na ten temat? Tak na przyszłość, żebym wiedział co czytać pierwsze.

    2. Da radę zrobić taki trik w F4?

    Update:

    1. W RM, opis GPIO :)
    2. Tak, sterowaniem bitami w rejestrze PUPDR, dokładniej trzeba zmieniać podciąganie w taki sposób:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Co każde trzy błyski diody na PD15 następuje zmiana stanu na PD12 i PD14.

    Kluczowe okazało się prawidłowe skonfigurowanie licznika (kolejność ustawiania bitów) oraz zmiana wartości PUPDR:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Początkowo zapomniałem o bicie PUPDR8_0 i działy się dziwne rzeczy, ponieważ pin PA8 zbierał zakłócenia.
  • Specjalista - Mikrokontrolery
    __DSB() jest w tym przypadku całkowiecie zbędne - po włączeniu timera długo go nie używasz.

    Po co zerujesz bity, o których wiadomo, że już są wyzerowane?

    Dlaczego konfigurujesz każdą linię oddzielnie, zamiast zapsiać MODER i inne rejestry jeden raz a porządnie, bez operacji logicznych?
  • Poziom 27  
    BlueDraco napisał:
    TIM1->SR = (uint16_t) ~TIM_SR_UIF;
    - wyrzuć (uint16_t)

    Czemu? To rzutowanie jest błędne czy po prostu zbędne? Intencja była taka, aby nie wpisywać beztrosko jedynek w górną (zastrzeżoną) połowę rejestru.
  • Poziom 38  
    BlueDraco napisał:
    Całkiem źle programujesz timer. Kolejność:

    PSC,
    ARR,
    SMCR
    CCMRx
    CCER
    DIER
    CR1

    Główny błąd - to zaczynanie od CR1 - włączasz timer przed zaprogramowaniem go.

    Jeszcze taki drobiazg:
    TIM1->SR = (uint16_t) ~TIM_SR_UIF;

    - wyrzuć (uint16_t)


    Zmiana preskalera wymaga wygenerowania update.
  • Poziom 12  
    BlueDraco napisał:
    __DSB() jest w tym przypadku całkowiecie zbędne - po włączeniu timera długo go nie używasz.

    Po co zerujesz bity, o których wiadomo, że już są wyzerowane?

    Dlaczego konfigurujesz każdą linię oddzielnie, zamiast zapsiać MODER i inne rejestry jeden raz a porządnie, bez operacji logicznych?


    Bo dopiero zaczynam i korzystam z bezpiecznego schematu, który działa on kilku tygodni i testując nowe rzeczy chcę mieć pewność, że jakiś głupi błąd nie jest przyczyną problemów. Stąd trochę pisania 'na zapas'. Mam wszystko rozpisane jasno i przejrzyście (dla mnie). Docelowo będę korzystał z funkcji konfiguracyjnych kolegi szczywronek.

    BlueDraco napisał:
    Całkiem źle programujesz timer. Kolejność:

    PSC,

    tutaj akurat preskaler można zostawić nieustawiony. Działa poprawnie. Dobrze rozumuję?
  • Specjalista - Mikrokontrolery
    tadzik85: w najgorszym przypadku preskaler zmieni się na końcu pierwszego okresu . to chyba nie problem. Przy zatrzymanym timerze preskaler powinien zmienić się od razu, ale podobno różnie z tym bywa. Ja się na ten problem dotychczas nie wpakowałem.

    wronek:
    Niby góra zastrzeżona, ale w praktyce i na zdrowy rozsądek to albo nie ma tam nic (rejestr ma 16 bitów), albo są lub będą tam w przyszłości znaczniki działające tak, jak te na dole, czyli lepiej zer tam nie pisać.

    A im program krótszy, tym lepszy. ;)
  • Poziom 27  
    @BlueDraco - no tak, faktycznie jedynki wydają się bezpieczniejsze. Swoją drogą zauważyłem, że praktycznie wszyscy zapisują coś do pól zastrzeżonych i nikt się tym specjalnie nie przejmuje... z producentem (SPL/HAL) włącznie.