En aquest exemple farem servir el PWM per fer sonar unes notes musicals en un brunzidor piezoelèctric o un altaveu.
El següent programa toca la seqüència do - re - mi, fa una pausa de 0,2 s i la torna a tocar.
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
cblock 0x20 Retard1 ; Variables de retard Retard2 ValPR2 ; Aquí hi guardarem el valor de PR2 ValCCPR1L ; Aquí hi guardarem el valor de CCPR1L ValDC1B ; Aquí hi guardarem el valor de DC1B ValCCP1CON ; Aquí hi guardarem el valor de CCP1CON endc
org 0 Inici bsf STATUS,RP0 ; Tria el banc 1 movlw b'00100000' ; Definim com volem les E/S del port C movwf TRISC ; RC5 (sortida del PWM) com a entrada bcf STATUS,RP0 ; Tria el banc 0 clrf PORTC ; Desactiva les sortides del port C movlw b'00001100' ; Configura el PWM, bits P1M (bits 7-6) a 00 mode senzill ; DC1B = 00 (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 ValCCP1CON ; Ho guarda per fer-ho servir més tard movwf CCP1CON ; Ho posa com a configuració del PWM movlw b'00000011' ; 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 Bucle movlw .238 ; Valor que correspon aproximadament a do3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .119 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada movlw .212 ; Valor que correspon aproximadament a re3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .106 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada movlw .189 ; Valor que correspon aproximadament a mi3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .95 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .0 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada call RetM ; Espera 0,2 s goto Bucle
TocaNota movf ValPR2,w ; Valor de PR2 per a la nota desitjada bsf STATUS,RP0 ; Tria el banc 1 bsf TRISC,5 ; Posem RC5 (sortida del PWM) com a entrada movwf PR2 ; Ho posem com a comparació al Timer 2 bcf STATUS,RP0 ; Tria el banc 0 movf ValCCP1CON,w ; Agafa la configuració de CCP1CON andlw b'11001111' ; Posa els bits que corresponen a DC1B a zero per precaució movwf ValCCP1CON ; I ho torna a guardar swapf ValDC1B,w ; Agafa el valor que ha d'anar a DC1B ; I el guarda, permutat, a W ; Els dos bits han de quedar a les posicions 4-5 andlw b'00110000' ; Posa els altres sis bits a zero per precaució iorwf ValCCP1CON,w ; I ho afegeix a CCP1CON movwf CCP1CON ; Ho posa com a configuració del PWM movf ValCCPR1L,w ; Valor de CCPR1L movwf CCPR1L ; Registre que ens dona l'amplada de tON bcf PIR1,TMR2IF ; Desactiva el bit d'interrupció del Timer 2 bsf T2CON,TMR2ON ; Activa el Timer 2 ; No convé engegar el PWM fins que el Timer 2 no ha fet un cicle btfss PIR1,TMR2IF ; Espera l'activació del bit d'interrupció del Timer 2 goto $-1 bsf STATUS,RP0 ; Tria el banc 1 bcf TRISC,5 ; Posem RC5 (sortida del PWM) com a sortida bcf STATUS,RP0 ; Tria el banc 0 call RetM ; Espera 0,2 s bsf STATUS,RP0 ; Tria el banc 1 bsf TRISC,5 ; Posem RC5 (sortida del PWM) com a entrada ; Fem silenci bcf STATUS,RP0 ; Tria el banc 0 call RetM ; Espera 0,2 s return RetM ; Funció de retard de 0,2 s decfsz Retard1,f goto RetM decfsz Retard2,f goto RetM return end

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