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.

[stm32][C++/Keil] Zmiana częstotliwości przebiegów generowanych przez TIM1

12 Paź 2011 21:15 3063 7
  • 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.
  • Poziom 33  
    Pokaż funkcję obsługi przerwania z UARTA. W jaki sposób sprawdzasz że przyszły trzy bajty danych a nie jeden?
  • 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
  • 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
  • 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.
  • 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
  • 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.
  • 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.