Tony Nixon [sales at picnpoke.com] of ICmicro's says:
Assume PIC runs at 4MHz 1000Hz wanted at 50% duty cycleThese PWM enable steps are taken from the 16F87X data sheet
- Set the PWM period (1000Hz = 0.001S) by writing to the PR2 register.
PWM Period = [PR2 + 1]*4*Tosc*TMR2 PreScale valueUse 4 for TMR2 prescale. You can try other values but make sure it works with the duty cycle calcs as well.
Tosc = 1/4000000 = 2.5*10-7Rearranging the equation gives...
PR2 = (Period/(4 * Tosc * TMR2 Prescale)) - 1Therefore...
PR2 = (0.001/(4 * 2.5 * 10-7 * 4)) - 1 = 249 bsf STATUS,RP0 movlw d'249' ; when TMR2 = 249 = end of Period movwf PR2 bcf STATUS,RP0- Set the PWM Duty Cycle by writing to the CCPR1L register and CCP1CON<5:4> bits.
CCPR1L contains the upper 8 bits of the 10 bit Duty Cycle value CCP1CON<5:4> contain the lower 2 bits
PWM Duty Cycle = (CCPR1L:CCP1CON<5:4>)*Tosc*TMR2 Prescale Value CCPR1L:CCP1Con<5:4> = PWM Duty Cycle / (Tosc * TMR2 Prescale) PWM Duty Cycle = 50% of Period PWM Duty Cycle = 50% of 0.001 = 0.0005 CCPR1L:CCP1Con<5:4> = 0.0005 / (2.5 * 10-7 * 4) CCPR1L:CCP1Con<5:4> = 500 500 in 10 bit binary = 0111110100 CCPR1L = 01111101 CCP1Con<5:4> = 00Write the 10 bit value
movlw b'01111101' ; set bits 9 - 2 movwf CCPR1L bcf CCP1CON,CCP1X ; set bit 1 bcf CCP1CON,CCP1Y ; set bit 0- Make the CCP1 pin an output by clearing the TRISC<2> bit
bsf STATUS,RP0 movlw b'11111011' andwf TRISC bcf STATUS,RP0- Set The TMR2 prescale value and enable TMR2 by writing to T2CON.
We decided previously to set the prescale value to 4.
TMR2 prescale are bits 1 and 0 in T2CON
TMR2 enable is bit 2movlw b'00000101' ; TMR2 = on, prescale = 1:4 movwf T2CON- Configure the CCP1 module for PWM
movf CCP1CON,W andlw b'00110000' ; mask all but previously set Duty Cycle bits iorlw b'00001111' ; and enable PWM mode movwf CCP1CONA 1000 Hz square wave with a 50% duty cycle should now be coming out of RC2.
Liew Danny Jiefu says:
how do you use the pwm after setting it up, for example like on the leds? could u write a sample program?
Comments:
Searching for so long on internet on how to program PWM for 16f877 and finally I found this! Thanks alot Tony. The datasheet should have consider adding your tutorial to it in the furture. Btw...movf CCP1CON,W andlw b'00110000' ; mask all but previously set Duty Cycle bits iorlw b'00001111' ; and enable PWM mode movwf CCP1CONWhat is the rationale behind this? I know it work but how?
See also: