I need to generate PWM signal with PIC18F2550 microcontroller at near 20kHz. I read the datasheet, I found it too complex and confusing, then I started to search for a sample code on the net to finally see this PWM tool.
I used it with parameters \$ F_{OSC} \$=20MHz and \$ F_{PWM} \$=20kHz to generate these two different codes for corresponding two different duty cycle percentages.
// Duty cycle = 0%
PR2 = 0b11111001 ;
T2CON = 0b00000100 ;
CCPR1L = 0b00000000 ;
CCP1CON = 0b00001100 ;
// Duty cycle = 100%
PR2 = 0b11111001 ;
T2CON = 0b00000100 ;
CCPR1L = 0b11111001 ;
CCP1CON = 0b00111100 ;
The datasheet tells me that the 4th and 5th bits of the CCP1CON register are the LSBs of the "PWM duty cycle with" value, and its MSBs are stored in the CCPR1L register, isn't it?
That makes, for 0% duty cycle, the 10-bit PWM duty cycle timing is,
00000000 + 00 = 0x000
And for 100% duty cycle,
11111001 + 11 = 0x3E7
So, according to this tool, I must set the values between 0x000 and 0x3E7 to the relevant PWM registers to have duty cycle ratios between 0% and 100%. At this point I become confused and the following questions arise in my mind:
- What is this 0x3E7 value? How is it calculated? How would I find it myself if I hadn't had such an online tool?
- What is the resolution of this PWM signal (i.e.; what is the time difference of length of two duty cycles for two sequential values like 0x3E6 and 0x3E7)?
- Why can't I load higher values to the CCPR1L register like all ones (0xFF); that would make 0x3FF for the overall PWM duty cycle length value. What happens if I do so?
- The tool says that, I can use PWM feature only with 9-bit resolution with the working parameters I specified. So, why the number 0x3E7 is a 10-bit number? Is the "9-bit" comes from integer truncated value of \$log_2(0x3E7)\$?
This happened to be a long question, but it would help me greatly if someone kindly explains me the overall steps and logic of PWM signal creation with PIC microcontrollers.
Thanks.