I'm using PIC16F886 and there is one thing I don't quite understand in setting hardware PWM up. In datasheet there are detailed instructions on how to do this, but maybe somebody can explain why I first need to disable the PWM pin output driver. Then after everything is set up, it should be enabled after an interrupt
Here are the steps from the datasheet:
Disable the PWM pin (CCPx) output drivers as an input by setting the associated TRIS bit.
Set the PWM period by loading the PR2 register.
Configure the CCP module for the PWM mode by loading the CCPxCON register with the appropriate values.
Set the PWM duty cycle by loading the CCPRxL register and DCxB<1:0> bits of the CCPxCON register.
Configure and start Timer2:
Clear the TMR2IF interrupt flag bit of the PIR1 register.
Set the Timer2 prescale value by loading the T2CKPS bits of the T2CON register.
Enable Timer2 by setting the TMR2ON bit of the T2CON register.
Enable PWM output after a new PWM cycle has started:
Wait until Timer2 overflows (TMR2IF bit of the PIR1 register is set).
Enable the CCPx pin output driver by clearing the associated TRIS bit.
In my understanding, Timer2 even shouldn't overflow because it's value is constantly compared to PR2 register whose value in most cases will be smaller than maximum value of Timer2. And as soon as PR2 value is reached, TMR2 is cleared so no overflow.
Ok, still, if an overflow flag set on TMR2 = PR2, why skip the first pulse then? In this situation I will have to wait for the first overflow somewhere in main loop or implement an overflow interrupt handler just for this purpose.
Normally the PWM module is run at many kHz and so waiting for a new period takes less than a milli second and only has to be done once at initialization. What speed are you intending the PWM to run at? Why can't you wait 1mS when your code first starts?
Yes, F will be couple of kHz so not very long to wait, I agree. But the question still remains unanswered - should these steps be performed at all? All examples I have seen just make CCPx pin an output and then all the rest setup is performed regarding Timer and CCP registers. Unfortunately datasheet, which is very recent by the way, does not mention anything regarding this subject.
My guess would be that this is just a precautionary setup. It is to ensure the pin is in a known state during setup. If your external circuitry won't be harmed by a random pulse at startup then I wouldn't worry about it.
If initial duty cycle is set to 0%, TMR2IF flag will be set immediately, right? In that case I can probably enable the CCPx pin output driver right after starting the Timer2 (this operation replaces step 6).
Ahh... yes. PR2 defines period not duty cycle. Prescaler will have to be set to 1 as well, so I think it is not worth doing this. I'll just wait for the first overflow in PWM setup routine by polling the TMR2IF bit. It will probably be only 3 additional instructions.