การทำงาน CCP ร่วมกับ Timer2 ในโหมดมอดูเลชั่นทางความกว้างของพัลส์ (PWM Pulse Width Modulator)
 
     
   
     
     
     
 
 
 
PWM OUTPUT
 
     
  การคำนวนค่าคาบเวลาของการกำเนิดสัญญาณ  
 
Tpwm=Tosc*4*t2div*(period+1) สมการที่1
period = (Tpwm/(Tosc*4*t2div) )-1 สมการที่2
 
 
  เมื่อ Tpwm เป็นคาบเวลาของ PWM  
  Tosc เป็นคาบเวลาี่ของ XTAL  
  t2div เป็น prescaler ของ timer 2  
  period = มีค่า 0-255 (คาบเวลาเพื่อ Reset สัญญาณนาฬิกา Timer2)  
     
 
     
  การหาคาบเวลาที่มากที่สุด  
 
จากสมการที่1 t2div=16,period = 255  
TpwmMax=Tosc*4*16*(255+1) = Tosc*16384 สมการที่3
 
     
  เช่นหากใช้ XTAL=4 MHz จะสามารถสร้างสัญญาณที่กว้างที่สุด  
  TpwmMax= 0.25E-6*16384 = 4.096E-3 หรือ 4 ms (หรือความถี่ต่ำที่สุด =1/TpwmMax = 244.14 Hz)  
     
  คาบเวลาที่น้อยที่สุด  
 
จากสมการที่1 t2div=1,period = 0  
TpwmMin=Tosc*4*1*(0+1) = Tosc*4 สมการที่4
 
     
  เช่นหากใช้ XTAL=4 MHz จะสามารถสร้างสัญญาณที่น้อยที่สุด  
  TpwmMax= 0.25E-6*4 = 1E-6 หรือ 1 us (หรือความถี่สูงที่สุด =1/TpwmMin = 1 MHz)  
     
     
  การใช้งานฟังก์ชัน  
  set_pwm1_duty (value)  
  value คือค่าตัวแปรหรือค่าคงที่ขนาด 8 หรือ 16 บิท  
     
 
value = (Td*fosc)/t2div สมการที่5
คาบเวลาของ duty cycle หาได้จาก  
Td = (Tpwm*dutycycle)/100; สมการที่6
แรงดันเฉลี่ยของสัญญาณ PWM หาได้จาก  
Vpwm=(dutycycle*Vcc)/100 สมการที่7
   
 
     
  เมื่อ Td เป็นคาบเวลาของ duty cycle ,fosc เป็นความถี่ของ XTAL ,t2div เป็น prescaler ของ timer 2  
  dutycycle คือ % ความกว้างของ pluse, Vpwm คือแรงดันเฉลี่ยของสัญญาณ PWM  
     
  ตัวอย่าง ต้องการหาค่า period เพื่อใช้ผลิตความถี่ 1KHz เมื่อใช้ XTAL=4MHz, t2div = 4,duty cycle = 50%  
     
  จากสมการที่1  
  Tpwm=(2.5*10^-7)*4*4*(128) = 512 us  
  จากสมการที่2  
  period = (1*10^-3/(2.5*10^-7*4*4))-1 = 250-1 =249  
     
  1KHz มีคาบเวลา T = 1/f = 1 ms  
  จากสมการที่4  
  Td = (1E-3*50)/100= 500 us  
     
  จากสมการที่5  
  value = ((500*10^-6)*(4*10^6))/4 = 500  
   
  ตัวอย่างการใช้งาน PWM ผลิตความถี่ 1 KHz duty cycle 50% เมื่อใช้คริสเตอลมีความถี่ 4 MHz  
 
 
     
  ตัวอย่างโปรแกรม  
 
//Generate PWM Pluse 1KHz duty cycle 50% at RB3/CCP1 (PIN9)

//#include <16F628.h>
#include <16F648A.h> #use delay(clock=4000000) #fuses XT,PUT,BROWNOUT,MCLR,NOWDT,NOPROTECT,NOLVP #define TxD PIN_A0 #define RxD PIN_A1 void main(void) { setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM setup_timer_2(T2_DIV_BY_4, 249, 1); set_pwm1_duty(500); while( TRUE ) ; //Loop here }  
 
     
  ผลการทำงาน  
  จะเกิดเอาต์พุตความถี่ 1 KHz duty cycle 50% ออกทางขา RB3/CCP1  
     
  ตัวอย่างค่า prescaler ต่างๆ  
     
  7.8KHz  
  setup_timer_2(T2_DIV_BY_1,127, 1);
set_pwm1_duty(256);
 
     
  1.9KHz  
  setup_timer_2(T2_DIV_BY_4,127, 1);
set_pwm1_duty(256);
 
     
  487Hz  
  setup_timer_2(T2_DIV_BY_16,127, 1);
set_pwm1_duty(256);