El PWM consisteix en definir una freqüència de treball a la que a l'inici d'un període comença un pols (s'activa la sortida). Segons el percentatge de temps que està actiu el pols la sortida està activa més o menys temps i, per tant, la sortida té un valor mig de tensió elèctrica diferent.

El PIC 16F690 té un registre PWM. Aquest registre pot funcionar en diferents modes de captura, comparació i sortida PWM. El registre pot funcionar com a PWM en mode normal o en mode millorat. En mode normal controla una sortida i en mode millorat pot controlar quatre sortides en configuracions típiques de convertidors.
El PWM normal surt per la pota que correspon a RC5 i es fa servir el Timer 2 per controlar el temps. Aquest és un temporitzador de 8 bits. El Timer 2 té un registre anomenat PR2 que permet especificar fins a quin valor compta el Timer 2. Si, per exemple, posem un 5 a PR2 tindrem que aquest temporitzador comptarà: 0, 1, 2, 3, 4, 5, 0, 1, etc. Combinant el prescalat del Timer 2 (1, 4 o 16) amb la possibilitat de triar el valor de comptatge ens permet generar un PWM de la freqüència desitjada.
La generació del tON es pot controlar amb una resolució de 10 bits malgrat el Timer 2 sigui de 8 bits. Per definir el valor cal aplicar el percentatge desitjat sobre el valor de PR2 multiplicat per 4. El resultat d'això es guarda posant els 8 bits de més pes al registre CCPR1L i els altres dos bits a DC1B1 i DC1B0 al registre CCP1CON. Si no es necessita la resolució de 10 bits, es poden mantenir DC1B1 i DC1B0 a zero i posar el percentatge del valor de PR2 al registre CCPR1L.

Imaginem que volem fer un PWM a una freqüència de 440 Hz i amb un temps d'activació del 35 %.
Amb la configuració bàsica del microcontrolador, el rellotge treballa a 4 MHz que dona una freqüència de 1 MHz al rellotge del programa, amb el que es controla el Timer 2. Per tant ens caldria que el Timer 2 comptés fins a:

Però el Timer 2 és de 8 bits, per tant només pot comptar fins a 256 valors. Per tant, ens cal posar una prescala a Timer 2. Aquesta prescala ha de ser superior a:

Com el Timer 2 pot tenir prescales d'1, 4 i 16, agafarem aquesta darrera. Així el nombre que ens cal comptar serà:

Però atès que el comptador comença a 0, caldrà comptar de 0 a 141 per tenir 142.
El Timer 2 es configura a T2CON. En el mode PWM els cinc bits més significatius no tenen utilitat. El bit 2 engega el Timer quan està activat, si està desactivat el Timer no treballa. Els bits 0 i 1 configuren la prescala, segons la següent taula:
| Bit 1 | Bit 0 | Prescala |
| 0 | 0 | 1 |
| 0 | 1 | 4 |
| 1 | 0 | 16 |
| 1 | 1 |
Així, doncs, T2CON haurà de ser 00000111 on els dos darrers bits són els que permeten triar la prescala.
Ara ens cal trobar el valor de CCP per aconseguir el temps d'activació desitjat. Com treballem amb 10 bits, el valor de CCP pot anar de 0 a quatre cops PR2; és a dir 568.
Per a un 35 %, el valor corresponent serà 199.
Hem de separar els dos bits de menys pes i quedar-nos amb la resta. Els vuit bits de més pes seran la part entera de dividir per 4:

I els dos bits de més pes seran:
Per al mode normal, la configuració del registre CCP1CON ha de ser 00111100; on els dos bits marcats en color són els que corresponen a DC1B.
Per fer servir el PWM convé seguir la següent seqüència:
| 1 | Desactivar la sortida corresponent al PWM configurant-la com a entrada a TRISC |
| 2 | Carregar el valor de PR2 |
| 3 | Posar els valors corresponents a CCP1CON |
| 4 | Posar els valors corresponents a CCPR1L |
| 5 | Esborrar el bit TMR2IF per veure quan el Timer 2 acaba |
| 6 | Ajustar la prescala del Timer 2 |
| 7 | Activar el bit TMR2ON per engegar el Timer 2 |
| 8 | Esperar a que el Timer 2 hagi fet un cicle complet i activi TMR2IF |
| 9 | Activar la sortida corresponent al PWM a TRISC |
El següent tros de programa fa aquesta seqüència amb els valors de l'exemple anterior.
...
bsf RP0 ; Tria el banc 1
movlw 00100000B ; Definim com volem les E/S del port C
movwf TRISC ; RC5 (sortida del PWM) com a entrada
bcf RP0 ; Tria el banc 0
clrf PORTC ; Desactiva les sortides del port C
movlw 141 ; Valor que correspon aproximadament a 440 Hz (LA3)
movwf PR2 ; Ho posem com a comparació al Timer 2
movlw 00001100B ; Configura el PWM, bits P1M (bits 7-6) a 00 mode senzill
; DC1B = 11 (bits 5-4) els dos bits de menys pes són 0
; CCP1M = 11xx en mode senzill els bit 0 i 1 no afecten
movwf CCP1CON ; Ho posa com a configuració del PWM
movlw 49 ; Valor que correspon a un cicle del 35 % a 440 Hz
movwf CCPR1L ; Registre que ens dona l'amplada de tON
bcf TMR2IF ; Desactiva el bit d'interrupció del Timer 2
movlw 00000011B ; Configura el Timer 2
; bits T2KCPS (bits 1-0) a 11 prescalat de 16
; bit 2 (TMR2ON) a 0, Timer aturat
; Postscaler TOUTPS (bits 6-3) no afecten al PWM
movwf T2CON ; Ho posa com a configuració del Timer 2
bsf TMR2ON ; Activa el Timer 2
; No convé engegar el PWM fins que el Timer 2 no ha fet un cicle
btfss TMR2IF ; Espera l'activació del bit d'interrupció del Timer 2
goto $-1
bsf RP0 ; Tria el banc 1
bcf TRISC,5 ; Posem RC5 (sortida del PWM) com a sortida
bcf RP0 ; Tria el banc 0
...

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.