Menu

(Very) Newbie help with HPWM

2018-08-14
2018-08-18
  • Adrian Arnold

    Adrian Arnold - 2018-08-14

    Hi all,

    Newbiew to GCB and Pic, having previously worked with Picaxe, I'm having problems getting something as simple as a hpwm command to work.

    Basically, I'm trying to output two fixed PWN signals, one at 57.6khz, one at 1.8khz at around 95% duty using a 16F1825 (well, an old picaxe 14m2 that I erased) chip

    I know it's programmed fine previously as I've managed a simple "HelloWorld" type prog with a flashing LED

    Code is attached but I@m getting absoloutly nothing off of either pin - pin 5 is CCP1 and pin 7 is CCP2 as I understand it

     
  • Adrian Arnold

    Adrian Arnold - 2018-08-14

    Code is attached here - How'd you attach it to the initial message

     
  • Anobium

    Anobium - 2018-08-14

    Look ok except you are not using integers. Use the following:

      HPWM 1, 58, 245
      HPWM 2, 2, 245
    
     
    • Adrian Arnold

      Adrian Arnold - 2018-08-14

      Hi Anobium,

      Tried that. Both pins gave ~1.9hz so both seemed to e working on the 2nd command

       
  • Adrian Arnold

    Adrian Arnold - 2018-08-14

    Ok, so I changed the speed on the chip to #chip 16F1825,32

    Which has helped. I'm now getting ~27kHz on ccp1 and 1.8 on ccp 2 so half way there :)

    Any ideas why ccp1 seems to stick at 27 khz?

    Ag no.. nix that, if I take the commands out of the do loop, then they both stick on the ~1.9 so it does look like it's only doing the lastip having 2 ccp command across both pins, despite the chip having 2 ccp modules.

    Perhaps if I move it to ccp 2 & 3 as ccp 1& 2 are both extended ccp?

    Edit: Nope. It looking like it's only executing the last command

    Confirmed as I put a 5 second wait between the two hpwm commands and I got the 57k output, but then when it switched to the next hpwm command it all went to the 2k

    Time to try to SW version I think.

     

    Last edit: Adrian Arnold 2018-08-14
  • kent_twt4

    kent_twt4 - 2018-08-14

    The Hardware CCP/PWM module should work, but I don't see where the CCPTMRS (PWM Timer Selection Control Register) bits are being set. By default you have Timer2 in PWM mode in PWM mode, which would describe your behavior. And looking at Help it indeed only supports Timer2. Manually manipulating the registers would be an option for the 16f1825.

    It would take a PIC device like say in the 16f157x device family with a dedicated PWM module to take advantage of the separate timers with GCB PWM library. Never tried the HPWMUpdate command, have always set pwm up manually.

    The AVR devices can have independant timers by defining separate TimerCounter constants if available.

     
    • Adrian Arnold

      Adrian Arnold - 2018-08-14

      Got it!

      ccptmrs=b'00000100' ' set it so ccp 2 uses timer4 and ccp1 uses timer 2

      add and it works fine now.... Now I just have to try and get the frequency down to 1.8 hz

       
  • kent_twt4

    kent_twt4 - 2018-08-14

    Good!

    I would be tempted to set up a TMR1 interrupt with a counter/flag that increments to twenty. So set the Timer1 register to roll over every 20 times for the 1.8kHz, or 36kHz. Set the output pin high for counts 19/20 and off for 1/20 (for the 95% duty cycle) inside the interrupt procedure .

     
  • Anobium

    Anobium - 2018-08-15

    I should have looked a little more..... CCP1 and CCP2 do not exist on this part.. this is ECCP1 and ECCP2 but CCP3 and CCP4 do exist. My error.

    See my later post.

     

    Last edit: Anobium 2018-08-15
  • Anobium

    Anobium - 2018-08-15

    A tested method. :-) I have tested on a 16F1825 and I have three channels at different frequencies and duty cycles. This works as expected. I would recommend you use the optimisation technique to reduce code, shown in the test program (also attached).

    Download the program attachment and place in a development foilder, then replace the existng pwm.h in the lowlevel directory with the .h attached.

    'Command as follows:
    ' HPWM_CCPTimerN   CCP_Channel, Frequency, Duty, Timer Source.  Timer source defaults to timer 2, so, the timersource is optional.
    
          HPWM_CCPTimerN  3, 30, 77 , 4
          HPWM_CCPTimerN  4, 40, 102, 6
          HPWM  1, 10, 26                     'still defaults to timer2
    

    Do test - let me know the result.

     

    Last edit: Anobium 2018-08-15
  • Anobium

    Anobium - 2018-08-15
     
    • Adrian Arnold

      Adrian Arnold - 2018-08-15

      Seems to work fine.

      CCP3 output: 29.4 kHz
      CCP4 output 38.4 kHz

       
      • Anobium

        Anobium - 2018-08-15

        Excellent.   I will move the revised library to the code for the next release.

        Thank you for pointing out this omission.

        Anobium

         
  • Anobium

    Anobium - 2018-08-16

    @Adrian and all.

    If folks are really interested in understanding the PWM command options then this is a really interesting subject.

    We have a few options to make PWM work. But, as with all libraries they evolve and the evolution of the PWM library has been pretty large. So, always get the latest pwm.h library.

    For the 16f1825 we have three methods, plus hand cranking, to enable PWM.
    1) Fixed mode for PWM Channel 1 only. This is legacy and still works today. Simple restate two constants and turn the PWMOn.

      PWMOn
    

    2) The method shown above. The latest library is purely an adaption to support different timers. This method is dynamic - you can change the frequency and the duty in your program - this is useful but does use program memory. For one channel the dynamic methods use 767 words

          HPWM_CCPTimerN  3, 30, 77 , 4
          HPWM_CCPTimerN  4, 40, 102, 6
          HPWM  1, 10, 26                     'still defaults to timer2
    

    3) The fixed mode that support three timers and five PWM channel. This is NOT dynamic but does only use 83 words to enable the PWM. (and, I am sure we can optimise further!). This mode required a few constants to specific the timer source, frequency and duty but consider that the this is supported across the fullest range of operating frequencies... 83 words is not too bad.

        #define PWM_Timer6_Freq 20        'Set frequency in KHz, just change the number
        #define PWM_1_Duty 50              'Set the duty
        #define PWM_1_Clock_Source 6       'Set the clock source
        PWMOn (1)
    

    So, lots of options for PWM.

    I will post a new pwm.h today - so, if you are eager to experiment please ensure the version of the pwm.h is dated after 16th Aug 2018.

    Enjoy,

    Anobium

     

    Last edit: Anobium 2018-08-16
    • Anobium

      Anobium - 2018-08-16

      Latest library is here: https://sourceforge.net/p/gcbasic/code/HEAD/tree/GCBASIC/trunk/include/lowlevel/pwm.h?format=raw

      Code example of fixed mode. Full program attached.

          #define PWM_Timer2_Freq 20        'Set frequency in KHz, just change the number
          #define PWM_Timer4_Freq 40        'Set frequency in KHz, just change the number
          #define PWM_Timer6_Freq 60        'Set frequency in KHz, just change the number
      
      
          #define PWM_1_Duty 20
          #define PWM_1_Clock_Source 2
      
          #define PWM_2_Duty 40
          #define PWM_2_Clock_Source 4
      
          #define PWM_3_Duty 60
          #define PWM_3_Clock_Source 6
      
          PWMOn (1)    'Will enable any valid CCP/PWM channel
      
          PWMOn (2)    'Will enable any valid CCP/PWM channel
      
          PWMOn (3)    'Will enable any valid CCP/PWM channel
      
       
      • Anobium

        Anobium - 2018-08-16

        And, I thought some ASM to shown the level of optimisation we have.

        Simple piece of user code. Remember, this is portable code and you can change the frequency and you still get the correct PWM.

        Three defines and then turn on the PWM channel. To generate a 60kHz signal, at 60% Duty.

        #define PWM_Timer6_Freq 60        'Set frequency in KHz, just change the number
        #define PWM_3_Duty 60
        #define PWM_3_Clock_Source 6
        PWMOn (3)    'Will enable any valid CCP/PWM channel
        

        Generates. Sets up the timer, sets up the duty, selects the correct timer and then enables PWM. This combination generates extra ASM to ensure setup is correct but not to shabby.

        INITPWM   'automatically added to your code.
        STARTOFFIXEDCCPPWMMODECODE
        STARTOFFIXEDPWMMODECODE
            movlw   143
            banksel T6CON
            andwf   T6CON,W
            banksel SYSTEMP1
            movwf   SysTemp1
            banksel T6CON
            movwf   T6CON
            banksel PIR3
            bcf PIR3,TMR6IF
            banksel T6CON
            bsf T6CON,TMR6ON
            movlw   133
            movwf   PR6
            banksel CCPTMRS
            bsf CCPTMRS,C3TSEL1
            bcf CCPTMRS,C3TSEL0
        SETPWMDUTYCODE
        ENDOFFIXEDPWMMODECODE
            banksel STATUS
            return
        
        PWMON16  'PWMOn
            movlw   3
            subwf   PWMCHANNEL,W
            btfss   STATUS, Z
            goto    ENDIF1
            movlw   80
            banksel CCPR3L
            movwf   CCPR3L
            movlw   12
            iorwf   CCP3CON,F
            banksel STATUS
            return
        ENDIF1
            return
        

        :-)

         

        Last edit: Anobium 2018-08-16
  • mkstevo

    mkstevo - 2018-08-18

    Many, many, many thanks.

    I'm bookmarking this page now.

    I've been using PicAXE for any PWM stuff I've had to do as I've been put off with all the mentions of ECCP and CCP. I now feel more confident thanks to the generous work here.

    Especially as the 16F1825/1829 are my most used processors...

     
  • Mario Zandel

    Mario Zandel - 2018-08-18

    Yes, many thanks. I`m using the 16F1829 (Pickaxe 20M2)so this is great stuff!
    Marz

     

Log in to post a comment.