3.13. Generera analoga signaler med PWM och ett RC-filter¶
ADC:n läser spänningar på ett stift. Det motsatta – att producera en mellanliggande spänning mellan 0 V och Vcc på ett stift – är svårare, eftersom en GPIO-utgång bara vet hur man driver sina två skenor. Den vanliga ersättningen är att växla stiftet mellan skenorna tillräckligt snabbt för att medelspänningen ska vara det du bryr dig om.
3.13.1. Pulsbreddsmodulering¶
En pulsbreddsmodulerad (PWM) signal är en fyrkantvåg vid en fast frekvens vars höga tid – den andel av varje cykel som tillbringas vid Vcc i stället för jord – ställs in i mjukvaran. Den andelen är arbetscykeln (duty cycle). Vågformens medelspänning är arbetscykeln gånger Vcc:
V_avg = duty × Vcc
En arbetscykel på 25 % ger i medeltal Vcc / 4; en arbetscykel på 50 % ger Vcc / 2; en arbetscykel på 75 % ger 3 × Vcc / 4.
PWM vid 25 %, 50 % och 75 % arbetscykel. Medelspänningen följer arbetscykeln.¶
Frekvensen ställs in när PWM:en konfigureras; arbetscykeln är vad mjukvaran ändrar under drift. Klassen machine.PWM omsluter en hårdvarutimerkanal som genererar vågformen utan CPU-hjälp – när den väl konfigurerats fortsätter signalen vid den valda frekvensen och arbetscykeln tills den ändras.
3.13.2. Klassen machine.PWM¶
Konstruera en PWM-instans med stiftet och en initial frekvens och arbetscykel:
from machine import PWM, Pin
pwm = PWM(Pin("P7"), freq=20_000, duty_u16=32768)
Det startar en fyrkantvåg på 20 kHz vid 50 % arbetscykel på P7. Två metoder ändrar utsignalen under drift:
pwm.duty_u16(16384) # change to 25 % (16384 / 65535)
pwm.freq(5_000) # change to 5 kHz
duty_u16() tar ett 16-bitars heltal utan tecken som mappar 0 till ”alltid låg” och 65535 till ”alltid hög”. freq() ställer in bärvågsfrekvensen i hertz.
Anteckning
Varje PWM-kanal på samma hårdvarutimer delar dess frekvens. Att anropa freq() på en kanal ändrar alla andra kanaler som är kopplade till den timern. Använd kanaler på olika timrar när utgångar måste köras vid olika frekvenser.
Anropa deinit() för att frigöra timerkanalen när utsignalen inte längre behövs.
3.13.3. Medelvärdesbildning med ett RC-lågpassfilter¶
Rå PWM är inte en jämn spänning; det är en fyrkantvåg vars medelvärde är det vi vill ha. För att extrahera det medelvärdet, skicka PWM:en genom ett lågpassfilter – samma kombination av resistor och kondensator som används för avstudsning av strömbrytare i Avstudsning.
PWM genom ett RC-lågpassfilter: kondensatorn medelvärdesbildar fyrkantvågen till en likspänning proportionell mot arbetscykeln.¶
Filtrets brytfrekvens – gränsen mellan de frekvenser det släpper igenom och de det blockerar – bestäms av samma RC-produkt som gav tidskonstanten för avstudsningskretsen:
f_c = 1 / (2π × R × C)
För att filtret ska kunna extrahera en ren likspänning från en PWM-ingång måste brytfrekvensen vara mycket lägre än själva PWM-frekvensen. Likspänningskomponenten (frekvens 0) passerar oförändrad; PWM:ens grundton (vid PWM-frekvensen) dämpas med ungefär f_c / f_PWM. Ett förhållande på 1 / 200 skär ner det kvarvarande rippelet vid utgången till ungefär 0.5 % av insvängningen.
En rimlig utgångspunkt för ett långsamt föränderligt börvärde:
PWM-frekvens
f_PWM = 20 kHz– väl över ljudfrekvensområdet och lätt för timern att generera rent.Filtervärden
R = 1.6 kΩ,C = 1 µF– vilket gerf_c = 1 / (2π × 1.6 kΩ × 1 µF) ≈ 100 Hz.
200×-dämpningen vid bärvågen reducerar PWM:ens fulla svängning till ungefär Vcc / 200 kvarvarande rippel vid V_out – omkring 16 mV vid 3,3 V.
Två praktiska anmärkningar:
Filtrets utgångsimpedans är ungefär
R. Varje nedströms last som drar ström görRoch lasten till en delare som drarV_outunder det ideala medelvärdet, precis som delaren på sidan Läsa analoga värden med ADC:n. Mata ett ADC-stift eller en högimpediant buffert, inte en last som drar milliampere.Kondensatorn tar ungefär
5 × R × C ≈ 8 mspå sig att stabilisera sig när arbetscykeln ändras;V_outligger efter inställningen av arbetscykeln med så mycket. För ett börvärde som behöver uppdateras snabbare, höj brytfrekvensen (mindreRellerC) och acceptera mer rippel.