3.13. Generowanie sygnału analogowego za pomocą PWM i filtru RC¶
ADC odczytuje napięcia na pinie. Operacja odwrotna – wytworzenie pośredniego napięcia między 0 V a Vcc na pinie – jest trudniejsza, ponieważ wyjście GPIO potrafi jedynie sterować dwiema swoimi szynami. Standardowym zamiennikiem jest przełączanie pinu między szynami na tyle szybko, aby liczyło się jego średnie napięcie.
3.13.1. Modulacja szerokości impulsu¶
Sygnał z modulacją szerokości impulsu (PWM) to fala prostokątna o stałej częstotliwości, której czas stanu wysokiego – ułamek każdego cyklu spędzony na Vcc zamiast na masie – jest ustawiany w oprogramowaniu. Ten ułamek to współczynnik wypełnienia (duty cycle). Średnie napięcie przebiegu to współczynnik wypełnienia pomnożony przez Vcc:
V_avg = duty × Vcc
Współczynnik wypełnienia 25 % daje średnią Vcc / 4; 50 % daje Vcc / 2; 75 % daje 3 × Vcc / 4.
PWM przy współczynniku wypełnienia 25 %, 50 % i 75 %. Średnie napięcie podąża za współczynnikiem wypełnienia.¶
Częstotliwość jest ustawiana podczas konfiguracji PWM; współczynnik wypełnienia to wartość, którą oprogramowanie zmienia w locie. Klasa machine.PWM obejmuje sprzętowy kanał licznika czasu (timera), który generuje przebieg bez udziału CPU – po skonfigurowaniu sygnał trwa z wybraną częstotliwością i współczynnikiem wypełnienia aż do zmiany.
3.13.2. Klasa machine.PWM¶
Utwórz instancję PWM z pinem oraz początkową częstotliwością i współczynnikiem wypełnienia:
from machine import PWM, Pin
pwm = PWM(Pin("P7"), freq=20_000, duty_u16=32768)
To uruchamia falę prostokątną 20 kHz przy współczynniku wypełnienia 50 % na P7. Dwie metody zmieniają wyjście w locie:
pwm.duty_u16(16384) # change to 25 % (16384 / 65535)
pwm.freq(5_000) # change to 5 kHz
duty_u16() przyjmuje 16-bitową liczbę całkowitą bez znaku, odwzorowując 0 na „zawsze niski”, a 65535 na „zawsze wysoki”. freq() ustawia częstotliwość nośnej w hercach.
Informacja
Każdy kanał PWM na tym samym sprzętowym liczniku czasu (timerze) współdzieli jego częstotliwość. Wywołanie freq() na jednym kanale zmienia każdy inny kanał przypisany do tego timera. Gdy wyjścia muszą działać z różnymi częstotliwościami, użyj kanałów różnych timerów.
Wywołaj deinit(), aby zwolnić kanał licznika czasu (timera), gdy wyjście nie jest już potrzebne.
3.13.3. Uśrednianie za pomocą filtru dolnoprzepustowego RC¶
Surowy sygnał PWM nie jest gładkim napięciem; to fala prostokątna, której średnia jest tym, czego chcemy. Aby wydobyć tę średnią, przepuść PWM przez filtr dolnoprzepustowy – to samo połączenie rezystora i kondensatora używane do eliminacji drgań styków w Eliminacja drgań styków.
PWM przez filtr dolnoprzepustowy RC: kondensator uśrednia falę prostokątną do napięcia stałego proporcjonalnego do współczynnika wypełnienia.¶
Częstotliwość odcięcia filtru – granica między częstotliwościami, które przepuszcza, a tymi, które blokuje – jest wyznaczana przez ten sam iloczyn RC, który dał stałą czasową dla układu eliminacji drgań styków:
f_c = 1 / (2π × R × C)
Aby filtr wydobył czyste napięcie stałe z wejścia PWM, częstotliwość odcięcia musi być znacznie niższa niż sama częstotliwość PWM. Składowa stała (częstotliwość 0) przechodzi bez zmian; podstawowa harmoniczna PWM (przy częstotliwości PWM) jest tłumiona mniej więcej o f_c / f_PWM. Stosunek 1 / 200 redukuje resztkowe tętnienie na wyjściu do około 0.5 % zakresu wejściowego.
Rozsądny punkt wyjścia dla wolno zmieniającej się wartości zadanej:
Częstotliwość PWM
f_PWM = 20 kHz– znacznie powyżej zakresu słyszalnego i łatwa do czystego wygenerowania przez timer.Wartości filtru
R = 1.6 kΩ,C = 1 µF– dającef_c = 1 / (2π × 1.6 kΩ × 1 µF) ≈ 100 Hz.
200-krotne tłumienie przy nośnej redukuje pełny zakres PWM do mniej więcej Vcc / 200 resztkowego tętnienia na V_out – około 16 mV przy 3,3 V.
Dwie praktyczne uwagi:
Impedancja wyjściowa filtru wynosi w przybliżeniu
R. Każde obciążenie po stronie wyjścia, które pobiera prąd, zamieniaRi to obciążenie w dzielnik, który ściągaV_outponiżej idealnej średniej, dokładnie jak dzielnik na stronie Odczyt sygnałów analogowych za pomocą ADC. Zasilaj pin ADC lub bufor o wysokiej impedancji, a nie obciążenie pobierające miliampery.Kondensatorowi zajmuje około
5 × R × C ≈ 8 ms, aby ustabilizować się przy zmianie współczynnika wypełnienia;V_outopóźnia się względem ustawienia wypełnienia o tyle właśnie. W przypadku wartości zadanej, która musi się aktualizować szybciej, podnieś częstotliwość odcięcia (mniejszeRlubC) i zaakceptuj większe tętnienie.