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++/Keil] Zmiana częstotliwości przebiegów generowanych przez TIM1

micmac89 12 Paź 2011 21:15 2871 7
  • #1 12 Paź 2011 21:15
    micmac89
    Poziom 9  

    Witam,
    Jestem w trakcie realizacji projektu, w którym mam konieczność sterowania trzech silników krokowych. W tym celu stworzyłem sterowniki w oparciu o dostępne układy scalone. Prędkość silników jest sterowana za pomocą sygnału prostokątnego.
    Do sterowania układem wykorzystuję mikrokontroler stm32 w postaci płytki startowej Discovery.
    Program został napisany w języku C++ z wykorzystaniem bibliotek dołączanych przez producenta. Do generowania przebiegów sterujących prędkością silnika wykorzystałem trzy kanały timera 1. Wszystko działało bardzo dobrze do momentu, gdy postanowiłem zmieniać w trakcie działania programu częstotliwość (zadawałem ją poprzez UART). Komunikacja przebiega prawidłowo, po odebraniu paczki z prędkościami, przepisuję je do zmiennych, których używam do zadania wartości do której liczy jeden z kanałów. Co ciekawe, gdy przepisuję tę samą wartość do każdego z kanałów wówczas mogę realizować zmianę prędkości (każdego z silników jednocześnie). Gdy zaś nadaję 3 bajty z prędkościami, wówczas tylko jeden z bajtów powoduje zmianę prędkości. Wszystkie kanały są w stanie pracować z wartością, którą przypisze im się na sztywno w trakcie wykonywania programu.
    Poniżej zamieszczam konfigurację timer'a 1:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Ponadto dołączony jest zegar oraz włączone są przerwania.
    W pętli głównej wykonuję następujące instrukcje:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    A także procedura obsługi przerwania:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Muszę przyznać, że cała sytuacja jest dla mnie bardzo dziwna, jeśli ktoś spotkał się z podobnym problemem, lub jest w stanie ukazać co zrobiłem tutaj źle to byłbym zobowiązany.
    Proszę również o sugestie w jaki sposób było by możliwe rozwiązanie tego problemu.

    Pozdrawiam, z góry dziękuję za jakiekolwiek sugestie.

    0 7
  • #2 12 Paź 2011 22:23
    markosik20
    Poziom 33  

    Pokaż funkcję obsługi przerwania z UARTA. W jaki sposób sprawdzasz że przyszły trzy bajty danych a nie jeden?

    0
  • #3 12 Paź 2011 23:50
    micmac89
    Poziom 9  

    Dane nadaję w postaci paczki, kod ASCII litery P, potem 3 bajty prędkości, po czym bajt z kodem litery K. W programie testowałem również czy nadając daną wartość odczytuję ją poprawnie, dla każdego bajtu tak było. Wydaje mi się, że to nie tu tkwi problem, jednak mimo to załączam kod obsługi przerwania od UART1:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  • #4 13 Paź 2011 17:18
    markosik20
    Poziom 33  

    micmac89 napisał:
    Gdy zaś nadaję 3 bajty z prędkościami, wówczas tylko jeden z bajtów powoduje zmianę prędkości.


    A sprawdzałeś w debug'u zawartość RxBuf po ustawieniu breakpoint'a za ?
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 15 Paź 2011 11:25
    micmac89
    Poziom 9  

    Jak wspominałem komunikacja przebiega prawidłowo, wysyłałem daną wartość i następnie sprawdzałem czy dostałem to co chcę i tak właśnie było. Wykonałem również to co napisałeś i wyniki potwierdziły się. Problemem jest zmiana częstotliwości 3 kanałów jednocześnie, gdy otrzymam nowe prędkości nadpisuję zmienne w których przechowuję wartości do których mają zliczać liczniki, w przerwaniu powinny się one przeładować, jednak aktualizacja zachodzi tylko dla jednego kanału.

    0
  • #6 18 Paź 2011 16:58
    micmac89
    Poziom 9  

    Uprościłem znacząco zadanie tak by wyeliminować wpływ komunikacji na wartość przepisywaną do zmiennych, które służą do aktualizacji rejestrów CC.
    Otóż na chwilę obecną program "mruga" dwiema diodami, po naciśnięciu przycisku chciałbym zmienić wartość zmiennych. Jak się okazuje mogę zmienić w ten sposób tylko częstotliwość kanału pierwszego, zatem tak jak poprzednio mogę zmieniać częstotliwość tylko jednego kanału.
    Poniżej zamieszczam kod programu:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0
  • #7 19 Paź 2011 08:52
    nibbit
    Poziom 19  

    Ja tam widzę, że zmieniasz tylko wartość zmiennych CC1 i CC2 a nie rejestrów chyba, że to są definicje rejestrów. Jeśli nie to potrzebujesz:

    Cytat:
    TIM1->CCR1 = CC1;
    TIM1->CCR2 = CC2;

    A ponadto jak masz tryb OC to możesz w ten sposób zmieniać jedynie wypełnienie, bo częstotliwość jest ustawiana wspólna dla wszystkich 4 kanałów.

    0
  • #8 26 Paź 2011 23:09
    micmac89
    Poziom 9  

    Nie wiem, czy do końca zrozumiałem Twoją odpowiedź, gdyż kłóci się z tym co obserwuję w układzie. Mogę zmieniać częstotliwość jednego z kanałów w trakcie wykonywania programu.
    Problem został rozwiązany, dany kanał przy zmianie okresu jest załączany i wyłączany w procedurze obslugi przerwania.

    0