Hardware PWM - Which Pin on PIC16F877A?

Discussion in 'Embedded Systems and Microcontrollers' started by Art, May 21, 2015.

  1. Art

    Thread Starter Distinguished Member

    Sep 10, 2007
    Hi Guys,
    I’m using Pic 16F877A, and have had a hardware PWM 10kHz signal working fine for a while.
    I use this code generated by an online calculator, and connect to portC.2 which is supposed to be channel 1.
    Code (Text):
    2. PR2 = 0b11111001 ;
    3. T2CON = 0b00000100 ;
    4. CCPR1L = 0b01111100 ;
    5. CCP1CON = 0b00111100 ;
    That was all fine...
    Now a little later i have a timer1 overflow interrupt running at 100 Hz interval,
    and decided to throw in a kind of timer driven software PWM of 50Hz using this code:
    Code (Text):
    2. ‘in 100 Hz timer overflow ISR straight after timer reload
    3. btfsc flipflop ,00    ; 1/2
    4. goto aaaa                 ; 2
    5. goto bbbb                ; 2
    6. aaaa:                         ‘
    7. bsf portc, 01            ; 1
    8. goto overpwm         ; 2
    9. bbbb:                         ‘
    10. nop                            ; 1
    11. bcf portc, 01             ; 1
    12. overpwm                   ‘
    13. comf flipflop ,F        ; 1 - but timing doesn’t matter here
    15. ‘instruction time 6 for flip state, 6 for flop state,
    16. ‘7 for the code to execute no matter the status
    Now I find the 50Hz signal is perfect on portC.1, but portC.2 that is supposed to have a 100Hz
    signal is also putting out the same 50Hz signal!
    It makes no difference if I move the 50Hz PWM to portC.0.
    I realise bit access is not recommended (RWM) on a hardware PWM port, but really?
    Why the same spot on 50Hz signal? I wanted both.

    Is it possible to output timer interrupt on one of the portC pins without messing up the HPWM?
    It doesn’t need to be 50Hz, just a signal I can mark, and compare to another signal with a 2 channel scope.
    Cheers, Art.
  2. JohnInTX


    Jun 26, 2012
    Yeah, maybe. Move the timer interrupt output to another port to eliminate r-m-w as a possible problem. PORTD is a good choice as it's not analog and doesn't have a lot of alternate functions. If it works, you have your answer. If it still has issues, at least you can set aside r-m-w as the primary cause. Fix it then relocate the output where you want it.

    FWIW I never r-m-w on any port on midrange PICs. On PORTC, any setup of mine that uses PORTC peripherals (I2C, PWM etc.) reserves the other PORTC lines as input only. As midrange has matured, things are better but I still won't mess with it. I have been roundly criticized by some for this caution but most of those guys haven't been where I have. The others are still debugging.. YMMV

    Good luck.
  3. Art

    Thread Starter Distinguished Member

    Sep 10, 2007
    Hi John,
    You have mentioned it before in another thread of mine, and I kept it in mind.
    You would like these dspics with latch registers.

    I’m not so sure my description of the problem is correct. The hardware PWM that was already working isn’t 50Hz, but slower than it should be.
    There’s another problem though, I think I’ll have to find. The same thing breaks the timing of the hardware PWM just for existing in the ISR
    (even if I comment the bsf/bcf instructions that write to port bits.

  4. JohnInTX


    Jun 26, 2012
    OK.. Once set up, the hardware PWM will run by itself as long as you don't mess with the setup registers (TMR2, PR2, CCPR1 etc). If its running at the wrong speed, fix that first.

    Unless changing the PWM base time or duty cycle, you don't need to reload PWM timers, registers etc. If you DO want to change duty cycle, I like to calculate the new value to put into CCPR1L then interrupt on the end of the duty cycle and jam the pre-computed values into CCPR1L.

    Post your code and we can take a look at it.