KursyPoradnikiInspirujące DIYForum

Wszystko, co musisz wiedzieć, aby uruchomić PWM

Wszystko, co musisz wiedzieć, aby uruchomić PWM

W artykule chciałbym wytłumaczyć inicjalizację i wykorzystanie sprzętowego PWM-u w robotach, np. do sterowania prędkością silników.

Pamiętam, że jako początkujący miałem z tym duży problem. Znałem zasadę działania PWM, ale nie wiedziałem jak to połączyć z resztą programu.

Gdy zaczynałem przygodę z programowaniem, w Internecie, można było znaleźć dużo przykładów w Bascomie oraz całkowitą pustkę jeśli chodzi o język C. Dodatkowo, sytuacji nie ułatwiał mi brak znajomości języka angielskiego. Próby szukania czegokolwiek w dokumentacji były porażkami.

Dlatego pamiętając o takich niby błahych – choć myślę, że częstych i utrudniających szybkie „wejście” w robotykę - problemach początkujących, chciałbym wytłumaczyć, jak sobie z nimi radzić. W tym artykule wskażę jakich rozdziałów i tabel szukać w dokumentacji, aby odpowiednio ustawić timery oraz jak to później wykorzystać w przykładowym kodzie robota.

Inicjalizacja PWM

W przykładzie posłużę się wykorzystaniem licznika (timera) 16-bitowego ustawionego w tryb Fast PWM. Posiada on dwa kanały, więc może służyć np.: do sterowania dwóch silników.

Tryb Fast PWM 8-bit oznacza, że wypełnienie sygnału będziemy mogli regulować w zakresie od 0 do 255, gdzie 0 będzie oznaczało ciągły stan niski, a 255 ciągły stan wysoki. Oto czynności, które należy wykonać w celu inicjalizacji PWM:

Szukamy w nocie katalogowej (datasheet) rozdziału dotyczącego np.: Timera 1 (jest to Timer 16-bitowy). W nim odszukujemy tabelkę Waveform Generation Mode Bit Description. Przykładowo dla mikrokontrolera ATMEGA8A (nota w załączniku) jest to tabela 16-5, która znajduje się na str. 101:

tabela_1

Widzimy z niej, że musimy ustawić na 1 bity WGM12 i WGM10, aby Timer pracował w wybranym przez nas trybie. W naszym przypadku (ATMEGA8A, 16-bitowy Timer1) bity te znajdują się w dwóch różnych rejestrach (TCCR1A oraz TCCR1B).

Widać to w dokumentacji (rejestry są rozpisane na poszczególne bity, w naszym przypadku TCCR1A znajduje się na str. 99, TCCR1B na str. 101). W przypadku liczników 8 bitowych mamy tylko jeden rejestr TCCRx (gdzie x jest numerem licznika), a do wyboru mamy zazwyczaj tylko cztery tryby pracy.

Kolejnym krokiem jest podłączenie Timera do odpowiedniego pinu mikrokontrolera oraz określenie sposobu sterowania tymże wyjściem. W tym celu szukamy tabelki Compare Output Mode, Fast PWM. W naszym przypadku jest to tabelka 16-3 na str. 100:

tabela_2

Interesują nas w zasadzie tylko dwie ostatnie opcje. Wybieramy: Clear OC1A/OC1B on Compare Match, set OC1A/OC1B at BOTTOM, (non-inverting mode) – oznacza to, że na starcie mamy stan wysoki, a podczas przerwania (gdy wartość licznika będzie taka sama, jak wpisana przez nas do OCRx) wyjście jest ustawiane w stan niski.

„Na chłopski rozum” mówiąc – im większą wartość wpiszemy do OCRx, tym dłużej na wyjściu będzie panował stan wysoki (wyższe „średnie” napięcie). Po wpisaniu maksymalnej wartości (w naszym przypadku 255, ponieważ wybraliśmy tryb 8-bit) na wyjściu będzie ciągle ustawiony stan wysoki, a po wpisaniu 0, na wyjściu będzie ciągle panował stan niski. Kolejne ustawienie działa w odwrotny sposób. Musimy więc ustawić w TCCR1A bity COM1A1 i COM1B1.

Wybór prescalera

Ostatnią czynnością jest wybranie prescalera. Od niego będzie zależała częstotliwość, z jaką będzie pracował nasz PWM. Generalnie, co do odpowiedniej częstotliwości zdania są mocno podzielone, tutaj możemy przeczytać dyskusję która była prowadzona na naszym forum na ten temat, ale ostrzegam, jest bardzo długa!

Za wartość prescalera odpowiadają bity CSxy. Aby dowiedzieć się, jakie mamy możliwości wyboru szukamy tabelki Clock Select Bit Description. W naszym przypadku jest to tabelka 16-6 na str. 102. W naszym przykładzie wybierzemy prescaler o wartości 64. Jak widać w tabelce, musimy w tym celu ustawić bity CS11 oraz CS10 w TCCR1B.

tabela_3

Jak więc obliczyć częstotliwość (f) naszego PWM? Załóżmy, że taktujemy nasz mikrokontroler częstotliwością 16MHz. Musimy więc podzielić ją przez prescaler oraz przez pojemność naszego licznika. Częstotliwość naszego PWM będzie wynosiła więc około 976Hz (16 000 000Hz / 64 / 256).

Inicjalizacja PWM powinna więc wyglądać tak:

Implementacja w programie robota

Teraz możemy przejść do wykorzystania PWM w programie (np.: robota). Po pierwsze musimy odpowiednie piny ustawić jako wyjścia. W przypadku omawianego mikrokontrolera (ATmega8A) są to PB1 oraz PB2. Nie można również pominąć pozostałych pinów, którymi sterowany będzie mostek H. Jednak to zależy już od konkretnej konstrukcji.

Następnie, w programie, musi nastąpić odpowiednie ustawienie PWM, czyli dokładnie, to czym zajmowaliśmy się poprzednio. Dalej można już pisać właściwy program. W celu zmiany wypełnienia sygnału PWM wystarczy wpisywać odpowiednie wartości do rejestrów OCR1A oraz OCR1B.

Przykładowy szkielet widoczny jest poniżej:

Podsumowanie

Mam nadzieje, że ten krótki artykuł udowodnił, że korzystanie z dokumentacji nie jest takie trudne. Wystarczy wiedzieć czego szukać, a najważniejsze informacje znaleźć można bez problemu w stosunkowo prostych tabelach. W razie problemów zachęcam do pytania w komentarzach.

Pierwsza publikacja: Grabki, 04-07-2012
Edycja i przeniesienie na blog: Treker, 26-05-2015, grafika tytułowa: Hudyvolt

Załączniki

C, częstotliwość, inicjalizacja, konfiguracja, prescaler, programowanie, PWM

Trwa ładowanie komentarzy...