- Vad är en PWM-signal?
- PWM med PIC16F877A:
- Programmering av PIC för att generera PWM-signaler:
- Scheman och testning:
- Arbetar med hårdvara:
Detta är vår 10: e handledning om inlärning av PIC-mikrokontroller med MPLAB och XC8. Hittills har vi täckt många grundläggande handledning som LED blinkar med PIC, Timers i PIC, gränssnitt LCD, gränssnitt 7-segment, ADC med PIC etc. börja lära sig.
I den här handledningen lär vi oss hur man genererar PWM-signaler med PIC PIC16F877A. Vår PIC MCU har en speciell modul som heter Compare Capture module (CCP) som kan användas för att generera PWM-signaler. Här genererar vi en PWM på 5 kHz med en variabel arbetscykel från 0% till 100%. För att variera arbetscykeln använder vi en potentiometer, därför rekommenderas det att lära sig ADC-handledning innan du börjar med PWM. PWM-modulen använder också timers för att ställa in dess frekvens och lär dig hur man använder timers i förväg här. Vidare kommer vi i denna handledning att använda en RC-krets och en LED för att konvertera PWM-värdena till analog spänning och använda den för att dimma LED-lampan.
Vad är en PWM-signal?
Pulsbreddsmodulering (PWM) är en digital signal som oftast används i styrkretsar. Denna signal är inställd hög (5v) och låg (0v) på en fördefinierad tid och hastighet. Tiden under vilken signalen förblir hög kallas "i tid" och den tid under vilken signalen förblir låg kallas "avstängningstid". Det finns två viktiga parametrar för en PWM som diskuteras nedan:
PWM: s arbetscykel:
Procentandelen tid under vilken PWM-signalen förblir HÖG (i tid) kallas som arbetscykel. Om signalen alltid är PÅ är den i 100% arbetscykel och om den alltid är av är den 0% arbetscykel.
Driftscykel = Slå PÅ-tid / (Slå PÅ-tid + Stäng av tid)
Frekvens av en PWM:
Frekvensen för en PWM-signal avgör hur snabbt en PWM slutför en period. En period är fullständig PÅ och AV för en PWM-signal som visas i figuren ovan. I vår handledning kommer vi att ställa in en frekvens på 5KHz.
PWM med PIC16F877A:
PWM-signaler kan genereras i vår PIC Microcontroller med hjälp av CCP (Compare Capture PWM) -modulen. Upplösningen för vår PWM-signal är 10-bit, det vill säga för ett värde på 0 kommer det att finnas en arbetscykel på 0% och för ett värde av 1024 (2 ^ 10) finns en arbetscykel på 100%. Det finns två CCP-moduler i vår PIC MCU (CCP1 och CCP2), det betyder att vi kan generera två PWM-signaler på två olika stift (stift 17 och 16) samtidigt, i vår handledning använder vi CCP1 för att generera PWM-signaler på stift 17.
Följande register används för att generera PWM-signaler med vår PIC MCU:
- CCP1CON (CCP1-kontrollregister)
- T2CON (Timer 2 Control Register)
- PR2 (Timer 2-moduler Periodregister)
- CCPR1L (CCP Register 1 Low)
Programmering av PIC för att generera PWM-signaler:
I vårt program läser vi en analog spänning på 0-5v från en potentiometer och kartlägger den till 0-1024 med vår ADC-modul. Sedan genererar vi en PWM-signal med frekvensen 5000Hz och varierar dess arbetscykel baserat på ingången Analog spänning. Det vill säga 0-1024 kommer att konverteras till 0% -100% Driftscykel. Denna handledning förutsätter att du redan har lärt dig att använda ADC i PIC om inte, läs det härifrån, för vi hoppar över detaljer om det i denna handledning.
Så när konfigurationsbitarna har ställts in och programmet är skrivet för att läsa ett analogt värde kan vi fortsätta med PWM.
Följande steg bör tas när du konfigurerar CCP-modulen för PWM-drift:
- Ställ in PWM-perioden genom att skriva till PR2-registret.
- Ställ in PWM-arbetscykeln genom att skriva till CCPR1L-registret och CCP1CON <5: 4> bitar.
- Gör CCP1-stiftet till en utgång genom att rensa TRISC <2> -biten.
- Ställ in TMR2-förskalningsvärdet och aktivera Timer2 genom att skriva till T2CON.
- Konfigurera CCP1-modulen för PWM-drift.
Det finns två viktiga funktioner i detta program för att generera PWM-signaler. Den ena är PWM_Initialize () -funktionen som initierar de register som krävs för att ställa in PWM-modulen och sedan ställer in frekvensen vid vilken PWM ska fungera, den andra funktionen är PWM_Duty () -funktionen som ställer in PWM-signalens arbetscykel i de register som krävs.
PWM_Initialize () {PR2 = (_XTAL_FREQ / (PWM_freq * 4 * TMR2PRESCALE)) - 1; // Ställa in PR2-formlerna med hjälp av datablad // Får PWM att fungera i 5KHZ CCP1M3 = 1; CCP1M2 = 1; // Konfigurera CCP1-modulen T2CKPS0 = 1; T2CKPS1 = 0; TMR2ON = 1; // Konfigurera timer-modulen TRISC2 = 0; // gör portnål på C som utdata}
Ovanstående funktion är PWM-initialiseringsfunktionen, i denna funktion CCP1-modulen är inställd på att använda PWM genom att göra biten CCP1M3 och CCP1M2 så hög.
Timermodulens förskalare ställs in genom att göra bit T2CKPS0 så hög och T2CKPS1 så låg bit TMR2ON är inställd för att starta timern.
Nu måste vi ställa in frekvensen för PWM-signalen. Frekvensens värde måste skrivas till PR2-registret. Den önskade frekvensen kan ställas in med hjälp av nedanstående formler
PWM-period = * 4 * TOSC * (TMR2 förskalningsvärde)
Att omorganisera dessa formler för att få PR2 kommer att ge
PR2 = (Period / (4 * Tosc * TMR2 Prescale)) - 1
Vi vet att Period = (1 / PWM_freq) och Tosc = (1 / _XTAL_FREQ). Därför…..
PR2 = (_XTAL_FREQ / (PWM_freq * 4 * TMR2PRESCALE)) - 1;
När frekvensen är inställd behöver denna funktion inte anropas igen om vi inte behöver ändra frekvensen igen. I vår handledning har jag tilldelat PWM_freq = 5000; så att vi kan få en 5 KHz arbetsfrekvens för vår PWM-signal.
Låt oss nu ställa in PWM: s arbetscykel med hjälp av funktionen nedan
PWM_Duty (osignerad int duty) {if (duty <1023) {duty = ((float) duty / 1023) * (_ XTAL_FREQ / (PWM_freq * TMR2PRESCALE)); // Vid minskning // duty = ((((float) duty / 1023) * (1 / PWM_freq)) / ((1 / _XTAL_FREQ) * TMR2PRESCALE); CCP1X = plikt & 1; // Lagra den första biten CCP1Y = duty & 2; // Lagra 0: e biten CCPR1L = plikt >> 2; // Lagra den påminnande 8 biten}}
Vår PWM-signal har 10-bitars upplösning, därför kan detta värde inte lagras i ett enda register eftersom vår PIC bara har 8-bitars datalinjer. Så vi har andra två bitar av CCP1CON <5: 4> (CCP1X och CCP1Y) för att lagra de två sista LSB och sedan lagra de återstående 8 bitarna i CCPR1L-registret.
PWM-arbetscykeltiden kan beräknas med formlerna nedan:
PWM Duty Cycle = (CCPRIL: CCP1CON <5: 4>) * Tosc * (TMR2 Prescale Value)
Omorganisera dessa formler för att få värdet av CCPR1L och CCP1CON ger:
CCPRIL: CCP1Con <5: 4> = PWM Duty Cycle / (Tosc * TMR2 Prescale Value)
Värdet på vår ADC kommer att vara 0-1024, vi måste ha den i 0% -100%, därför är PWM Duty Cycle = duty / 1023. För att konvertera denna arbetscykel till en tidsperiod måste vi multiplicera den med perioden (1 / PWM_freq)
Vi vet också att Tosc = (1 / PWM_freq), alltså..
Drift = (((float) duty / 1023) * (1 / PWM_freq)) / ((1 / _XTAL_FREQ) * TMR2PRESCALE);
Att lösa ovanstående ekvation ger oss:
Duty = ((float) duty / 1023) * (_XTAL_FREQ / (PWM_freq * TMR2PRESCALE));
Du kan kontrollera hela programmet i kodavsnittet nedan tillsammans med den detaljerade videon.
Scheman och testning:
Som vanligt låt oss verifiera utdata med Proteus-simulering. Den kopplingsschema visas nedan.
Anslut en potentiometer till 7: e stift för att mata in en spänning på 0-5. CCP1-modulen är med stift 17 (RC2), här kommer PWM att genereras som kan verifieras med det digitala oscilloskopet. För att konvertera detta till en variabel spänning har vi använt ett RC-filter och en LED för att verifiera utgången utan räckvidd.
Vad är ett RC-filter?
Ett RC-filter eller ett lågpassfilter är en enkel krets med två passiva element, nämligen motståndet och kondensatorn. Dessa två komponenter används för att filtrera frekvensen för vår PWM-signal och göra den till en variabel likspänning.
Om vi undersöker kretsen, när en variabel spänning appliceras på ingången till R, börjar kondensatorn C att laddas. Baserat på kondensatorns värde tar kondensatorn lite tid att bli fulladdad, en gång laddad kommer den att blockera likströmmen (kom ihåg att kondensatorerna blockerar likström men tillåter växelström), varför ingångens likspänning visas över utgången. Den högfrekventa PWM (AC-signalen) kommer att jordas genom kondensatorn. Således erhålls en ren likström över kondensatorn. Ett värde på 1000 Ohm och 1uf visade sig vara lämpligt för detta projekt. Beräkning av värdena för R och C involverar kretsanalys med hjälp av överföringsfunktion, som inte omfattas av denna handledning.
Programmets utdata kan verifieras med hjälp av det digitala oscilloskopet som visas nedan, variera potentiometern och PWM: s arbetscykel bör ändras. Vi kan också märka utgångsspänningen från RC-kretsen med Voltmeter. Om allt fungerar som förväntat kan vi fortsätta med vår hårdvara. Läs vidare videon i slutet för fullständig process.
Arbetar med hårdvara:
Hårdvaruinstallationen av projektet är väldigt enkel, vi ska bara återanvända vårt PIC Perf-kort som visas nedan.
Vi behöver också en potentiometer för att mata in den analoga spänningen, jag har anslutit några honkablar till min kruka (visas nedan) så att vi kan ansluta dem direkt till PIC Perf-kortet.
Slutligen för att verifiera utgången behöver vi en RC-krets och en LED för att se hur PWM-signalen fungerar, jag har helt enkelt använt ett litet perf-kort och lödt RC-kretsen och lysdioden (för att kontrollera ljusstyrkan) på den som visas nedan
Vi kan använda enkla kvinnliga till kvinnliga anslutningsledningar och ansluta dem enligt schemat som visas ovan. När anslutningen är klar laddar du upp programmet till PIC med vår pickit3 och du skulle kunna få en variabel spänning baserat på ingången till din potentiometer. Den variabla utgången används för att styra ljusstyrkan på lysdioden här.
Jag använde min multimeter för att mäta de variabla utgångarna, vi kan också märka att ljusstyrkan på LED-lampan ändras för olika spänningsnivåer.
Det är det vi har programmerat att läsa av den analoga spänningen från POT och konvertera till PWM-signaler som i sin tur har omvandlats till variabel spänning med hjälp av RC-filter och resultatet verifieras med hjälp av vår hårdvara. Om du är tveksam eller fastnar någonstans vänligen använd kommentarsektionen nedan, vi hjälper dig gärna. Den kompletta arbets arbetar i videon.
Kolla även våra andra PWM-handledning på andra mikrokontroller:
- Raspberry Pi PWM-handledning
- PWM med Arduino Due
- Arduino-baserad LED-dimmer med PWM
- Power LED-dimmer med ATmega32 Microcontroller