- Què és un senyal PWM?
- PWM que utilitza PIC16F877A:
- Programació de PIC per generar senyals PWM:
- Esquemes i proves:
- Treballant en maquinari:
Aquest és el nostre 10è tutorial sobre l' aprenentatge de microcontroladors PIC mitjançant MPLAB i XC8. Fins ara, hem tractat molts tutorials bàsics com LED parpellejant amb PIC, temporitzadors en PIC, interfície LCD, interfície de 7 segments, ADC mitjançant PIC, etc. Si sou un principiant absolut, visiteu la llista completa de tutorials PIC aquí i començar a aprendre.
En aquest tutorial, aprendrem a generar senyals PWM mitjançant PIC PIC16F877A. La nostra MCU PIC té un mòdul especial anomenat Comparar mòdul de captura (CCP) que es pot utilitzar per generar senyals PWM. Aquí generarem un PWM de 5 kHz amb un cicle de treball variable del 0% al 100%. Per variar el cicle de treball estem utilitzant un potenciòmetre, per tant, es recomana aprendre un tutorial ADC abans de començar amb PWM. El mòdul PWM també utilitza temporitzadors per configurar la seva freqüència, per tant, apreneu a fer servir temporitzadors aquí prèviament. A més, en aquest tutorial utilitzarem un circuit RC i un LED per convertir els valors PWM a tensió analògica i utilitzar-lo per atenuar la llum LED.
Què és un senyal PWM?
La modulació d’amplada de pols (PWM) és un senyal digital que s’utilitza més habitualment en circuits de control. Aquest senyal s’estableix com a alt (5v) i baix (0v) en un temps i una velocitat predefinits. El temps durant el qual el senyal es manté elevat s’anomena “hora puntual” i el temps durant el qual el senyal es manté baix es diu “temps apagat”. Hi ha dos paràmetres importants per a un PWM com es descriu a continuació:
Cicle de treball del PWM:
El percentatge de temps en què el senyal PWM roman ALT (puntual) s’anomena cicle de treball. Si el senyal sempre està activat, està en un 100% de cicle de treball i si sempre està apagat, és un 0% de cicle de treball.
Cicle de treball = Temps d’activació / (Temps d’encès + Temps d’APAGAT)

Freqüència d'un PWM:
La freqüència d'un senyal PWM determina la velocitat amb què un PWM completa un període. Un període està completament activat i desactivat d’un senyal PWM tal com es mostra a la figura anterior. Al nostre tutorial establirem una freqüència de 5 KHz.
PWM que utilitza PIC16F877A:
Els senyals PWM es poden generar al nostre microcontrolador PIC mitjançant el mòdul CCP (Compare Capture PWM). La resolució del nostre senyal PWM és de 10 bits, és a dir, per a un valor de 0 hi haurà un cicle de treball del 0% i per a un valor de 1024 (2 ^ 10) hi haurà un cicle de treball del 100%. Hi ha dos mòduls CCP a la nostra MCU PIC (CCP1 i CCP2), això vol dir que podem generar dos senyals PWM en dos pins diferents (pin 17 i 16) simultàniament, al nostre tutorial estem utilitzant CCP1 per generar senyals PWM al pin 17.
Els registres següents s’utilitzen per generar senyals PWM mitjançant la nostra MCU PIC:
- CCP1CON (registre de control CCP1)
- T2CON (registre de control del temporitzador 2)
- PR2 (registre de períodes de mòduls de temporitzador 2)
- CCPR1L (registre CCP 1 baix)
Programació de PIC per generar senyals PWM:
Al nostre programa llegirem un voltatge analògic de 0-5v des d’un potenciòmetre i el maparem a 0-1024 mitjançant el nostre mòdul ADC. A continuació, generem un senyal PWM amb una freqüència de 5000Hz i variam el seu cicle de treball en funció de la tensió analògica d’entrada. És a dir, del 0 al 1024 es convertirà al cicle de treball del 0% al 100%. Aquest tutorial suposa que ja heu après a utilitzar ADC a PIC, si no, llegiu-lo des d’aquí, ja que ometrem els detalls al respecte en aquest tutorial.
Per tant, un cop establerts els bits de configuració i escrivit el programa per llegir un valor analògic, podem procedir amb PWM.
Cal configurar el mòdul CCP per al funcionament PWM:
- Establiu el període PWM escrivint al registre PR2.
- Definiu el cicle de treball PWM escrivint al registre CCPR1L i als bits <5: 4> CCP1CON.
- Feu que el pin CCP1 sigui una sortida netejant el bit TRISC <2>.
- Establiu el valor de prescala TMR2 i activeu Timer2 escrivint a T2CON.
- Configureu el mòdul CCP1 per al funcionament de PWM.
Hi ha dues funcions importants en aquest programa per generar senyals PWM. Una és la funció PWM_Initialize () que inicialitzarà els registres necessaris per configurar el mòdul PWM i, a continuació, definirà la freqüència amb què hauria de funcionar el PWM; l’altra funció és la funció PWM_Duty () que establirà el cicle de treball del senyal PWM a els registres necessaris.
PWM_Initialize () {PR2 = (_XTAL_FREQ / (PWM_freq * 4 * TMR2PRESCALE)) - 1; // Configuració de les fórmules PR2 mitjançant el full de dades // Fa que el PWM funcioni en 5KHZ CCP1M3 = 1; CCP1M2 = 1; // Configureu el mòdul CCP1 T2CKPS0 = 1; T2CKPS1 = 0; TMR2ON = 1; // Configureu el mòdul Temporitzador TRISC2 = 0; // Feu el pin de port a C com a sortida}
La funció anterior és la funció d’inicialització PWM, en aquesta funció El mòdul CCP1 està configurat per utilitzar PWM fent que el bit CCP1M3 i CCP1M2 sigui tan alt.

El precalificador del mòdul de temporitzador es configura fent que el bit T2CKPS0 sigui tan alt i T2CKPS1 tan baix, el bit TMR2ON està configurat per iniciar el temporitzador.

Ara hem d’ establir la freqüència del senyal PWM. El valor de la freqüència s’ha d’escriure al registre PR2. La freqüència desitjada es pot establir mitjançant les fórmules següents
Període PWM = * 4 * TOSC * (valor de prescala TMR2)
Reorganitzar aquestes fórmules per obtenir PR2 donarà
PR2 = (Període / (4 * Tosc * TMR2 Prescala)) - 1
Sabem que Period = (1 / PWM_freq) i Tosc = (1 / _XTAL_FREQ). Per tant…..
PR2 = (_XTAL_FREQ / (PWM_freq * 4 * TMR2PRESCALE)) - 1;
Un cop configurada la freqüència, no caldrà tornar a cridar aquesta funció tret que i fins que haguem de canviar la freqüència de nou. Al nostre tutorial he assignat PWM_freq = 5000; de manera que podem obtenir una freqüència de funcionament de 5 KHz per al nostre senyal PWM.
Ara definim el cicle de treball del PWM mitjançant la funció següent
PWM_Duty (sense signar int duty) {if (duty <1023) {duty = ((float) duty / 1023) * (_ XTAL_FREQ / (PWM_freq * TMR2PRESCALE)); // En reduir // duty = (((float) duty / 1023) * (1 / PWM_freq)) / ((1 / _XTAL_FREQ) * TMR2PRESCALE); CCP1X = deure & 1; // Emmagatzema el primer bit CCP1Y = duty & 2; // Emmagatzema el bit 0 CCPR1L = duty >> 2; // Emmagatzema el bit restant de 8}}
El nostre senyal PWM té una resolució de 10 bits, per tant, aquest valor no es pot emmagatzemar en un registre únic, ja que el nostre PIC només té línies de dades de 8 bits. Per tant, hem d’utilitzar altres dos bits de CCP1CON <5: 4> (CCP1X i CCP1Y) per emmagatzemar els dos darrers LSB i després emmagatzemar els 8 bits restants al registre CCPR1L.
El temps del cicle de treball PWM es pot calcular mitjançant les fórmules següents:
Cicle de treball PWM = (CCPRIL: CCP1CON <5: 4>) * Tosc * (valor de prescala TMR2)
Reorganitzar aquestes fórmules per obtenir el valor de CCPR1L i CCP1CON donarà:
CCPRIL: CCP1Con <5: 4> = Cicle de treball PWM / (valor de prescala Tosc * TMR2)
El valor del nostre ADC serà de 0-1024, i necessitem que estigui entre el 0% i el 100%, per tant, PWM Duty Cycle = duty / 1023. A més per convertir aquest cicle de treball en un període de temps, hem de multiplicar-lo pel període (1 / PWM_freq)
També sabem que Tosc = (1 / PWM_freq), per tant…
Duty = (((float) duty / 1023) * (1 / PWM_freq)) / ((1 / _XTAL_FREQ) * TMR2PRESCALE);
Resoldre l’equació anterior ens donarà:
Duty = ((float) duty / 1023) * (_XTAL_FREQ / (PWM_freq * TMR2PRESCALE));
Podeu consultar el programa complet a la secció Codi següent, juntament amb el vídeo detallat.
Esquemes i proves:
Com és habitual, verificem la sortida mitjançant la simulació Proteus. A continuació es mostra el diagrama del circuit.

Connectar un potenciòmetre a 7 º pin d'alimentació en una tensió de 0-5. El mòdul CCP1 té el pin 17 (RC2), aquí es generarà el PWM que es pot verificar mitjançant l’oscil·loscopi digital. A més per convertir-ho en un voltatge variable , hem utilitzat un filtre RC i un LED per verificar la sortida sense abast.
Què és un filtre RC?
Un filtre RC o un filtre de pas baix és un circuit senzill amb dos elements passius, és a dir, la resistència i el condensador. Aquests dos components s’utilitzen per filtrar la freqüència del nostre senyal PWM i convertir-lo en un voltatge continu CC.
Si examinem el circuit, quan s’aplica una tensió variable a l’entrada de R, el condensador C començarà a carregar-se. Ara, en funció del valor del condensador, el condensador trigarà una estona a carregar-se completament, un cop carregat, bloquejarà el corrent continu (recordeu que els condensadors bloquegen el corrent continu però permeten el corrent altern), per tant, apareixerà el voltatge continu d’entrada a la sortida. El PWM d’alta freqüència (senyal de corrent altern) es connectarà a terra a través del condensador. Així, s’obté una CC pura a través del condensador. Es va trobar que el valor de 1000 Ohm i 1 UF era adequat per a aquest projecte. El càlcul dels valors de R i C implica l’anàlisi de circuits mitjançant la funció de transferència, que queda fora de l’abast d’aquest tutorial.

La sortida del programa es pot verificar mitjançant l’oscil·loscopi digital com es mostra a continuació, variar el potenciòmetre i el cicle de treball del PWM hauria de canviar. També podem notar la tensió de sortida del circuit RC mitjançant el voltímetre. Si tot funciona com s’espera, podem procedir amb el nostre maquinari. Consulteu el vídeo al final per obtenir un procés complet.

Treballant en maquinari:
La configuració del maquinari del projecte és molt senzilla, només reutilitzarem la nostra placa PIC Perf que es mostra a continuació.

També necessitarem un potenciòmetre per alimentar el voltatge analògic, he connectat alguns cables finals femella a la meva olla (que es mostra a continuació) perquè els puguem connectar directament a la placa PIC Perf.


Finalment, per verificar la sortida necessitem un circuit RC i un LED per veure com funciona el senyal PWM, simplement he utilitzat una petita placa de perf i he soldat el circuit RC i el LED (per controlar la brillantor), tal com es mostra a continuació.

Podem utilitzar cables de connexió femella a femella senzills i connectar-los segons els esquemes mostrats anteriorment. Un cop feta la connexió, carregueu el programa al PIC mitjançant el nostre pickit3 i hauríeu de poder obtenir una tensió variable en funció de l’entrada del vostre potenciòmetre. La sortida variable s’utilitza aquí per controlar la brillantor del LED.
He utilitzat el meu multímetre per mesurar les sortides variables, també podem notar que la brillantor del LED canvia per diferents nivells de voltatge.

Això és el que hem programat per llegir el voltatge analògic del POT i convertir-lo en senyals PWM que al seu torn s'han convertit en tensió variable mitjançant filtre RC i el resultat es verifica mitjançant el nostre maquinari. Si teniu algun dubte o us quedeu atrapats en algun lloc, utilitzeu la secció de comentaris que hi ha a continuació, estarem encantats d’ajudar-vos. El treball complet està funcionant al vídeo.
Consulteu també els nostres altres tutorials PWM sobre altres microcontroladors:
- Tutorial de Raspberry Pi PWM
- PWM amb Arduino Due
- Dimmer LED basat en Arduino mitjançant PWM
- Dimmer d'energia LED mitjançant microcontrolador ATmega32
