Menu

Limits of HPWM

2021-12-18
2022-01-05
  • Stefano Corradini

    Hello everybody !
    I'm a new user and I was trying the PWM commands.
    Maybe it's wrong but I think there is a little limitation in the frequency parameters.
    An example: in HWPWM it seems not possible to set output frequency less than 1kHz even if the hardware allows it.
    I mean, with low frequency clock (e.g. 4MHz or less) and e.g. with PWM 10 bit resolution it should be possible and also lower with a clock slower than that.
    I'm aware that some workaraond would be possible but they require more code and/or to loose time in delays, etc.
    Is it possible to change this parameter? I had a look in the forum and I see that also others said something like this so I guess it could be a good improvement.
    Moreover, about the HPWM, it seems that in Graphical mode there is no way to add parameter(s) as for allowed in 10 bit resolution.
    Thanks in advance for any answer about

     
    • Anobium

      Anobium - 2021-12-18

      The limitation is because we have to pass an integer value.

      It would very easy to add a factor divider parameter.

      Can you post your chip code? And, the command parameters you are using?

       
  • Stefano Corradini

    Hello Anobium,
    first of all thank You very much for Your so prompt and kind answer.
    I must confess that till now I've just been able to achieve a let to blink... :)
    I'm not so newbie but it's the first time I use GCB and I was begin from the beginning.
    So, I don't have any (decent) code to send You but I would appreciate if You kindly tell me how to add the divider parameter You said.
    The target I have in mind is to have a sort of "continuos command" for a little servo, as many makers try to do
    (oh, I forgot, I apologize for my english...)

     
  • Anobium

    Anobium - 2021-12-18

    Typically, you would use

    HPWM PWMChannel. PWMFreq, PWMDuty, PWMTimerSelected , PWMResolution

    Like HPWM 2, 1, 512, 2. 1023, where you are selecting HW PWM 2, at a frequency of 1, using 512 to set the duty to 50%, timer 2, and a resolution of 1023 for the 10bit.

    So, you can factorise the last parameter.

    Like HPWM 2, 1, 512, 2. 10230, where you are selecting HW PWM 2, at a frequency of 1, using 512 to set the duty to 50%, timer 2, and a resolution of 10230 for the 10bit factorised by 10. This should give a frequency of .1

     
  • Anobium

    Anobium - 2021-12-18

    regarding GCGB... the UI does not support the extra parameter.

     
  • Stefano Corradini

    Thanks a lot for explanation and examples.
    I thought it was not possible because I read these sentences in manual:

    frequency sets the frequency of the PWM output. It is measured in KHz. The maximum value allowed is 255 KHz. The minimum value varies depending on the clock speed. 1 KHz is the minimum on chips 16MHz or under and 2 Khz is the lowest possible on 20 MHz chips.

    Optional resolution specifies the desired resolution to be used. These can be either 255 or 1023. The rational of this optional parameter is to support the duty cycle with a BYTE or a WORD range. If you call the method with a WORD the resolution will be set to 1023.

    So, I understand that these statements maybe aren't updated, I mean about explanation about frequency and resolution can be more than 1023.

    Ok, thanks again for support, I will do as suggested.

     
    • Anobium

      Anobium - 2021-12-19

      Ignore all my comments regarding increasing the last parameter - that is correct for changing the resolution not the frequency.

      This shows how to get PWM Hz signals every time.


      The following code is a method that needs no knowledge of the registers. It just works.
      This example uses a 16F1719, it is a PPS chip. So, as a PPS chip we need to set the PPS register (I used PPSTool),
      Then, use the fixed mode PWM parameters to set the frequency (this can be a decimal number), set the duty and then set the PWM clock source. This example gens a square wave at 500Hz, 50% duty cycle.

      #chip 16f1719,1
      #option Explicit
      
      
      
          'Generated by PIC PPS Tool for Great Cow Basic
          'PPS Tool version: 0.0.5.5
          'PinManager data: 07/03/2017
          '
          'Template comment at the start of the config file
          '
          #startup InitPPS, 85
      
          Sub InitPPS
      
                  'Module: PWM4
                  RB5PPS = 0x000F    'PWM4OUT > RB5
      
          End Sub
          'Template comment at the end of the config file
      
      
          #define PWM_Timer2_Freq .5         'Set frequency, just change the number
          #define PWM_4_Duty 50             'Set the duty, just change the value
          #define PWM_4_Clock_Source 2      'Set the clock source
      
         'Set the PWM as an output
          Dir Portb.5 out
      
      
          'Enable PWM Modules
          PWMOn  ( 4, PWMModule ) 'Enable PWM Module
      
          Do
          Loop
      

      You can now use compilers intelligence to do some clever stuff. Like to change the PWM parameters. You can use the method above to set all the registers, then, change them as you now the correct registers from the ASM. Registers change between chips, and, you can review the ASM and be assured it will work.

      Examples

      PWMOn ( 4, PWMModule ) 'Enable PWM Module. In the ASM this is

      ;PWMOn  ( 4, PWMModule ) 'Enable PWM 6 Module
          movlw   4
          banksel PWMCHANNEL
          movwf   PWMCHANNEL
          movlw   255
          movwf   PWMHARDWARE
          call    PWMON20
      

      So, we can look at the sub PWMON20 and this shows that we have two PWM modules and it shows the registers to be used. If you look at the ASM for SETPWMDUTYCODE you will see the code for duty... this shows the registers - PWM4DCH, PWM4DCL are used.

      So, you change program for the 1719 to the following to set the Duty to any value.

      'Enable PWM Modules
      PWMOn  ( 4, PWMModule ) 'Enable PWM Module
      
      'Create an ALIAS to the registers
      Dim PWM4 as WORD alias PWM4DCH, PWM4DCL
      
      Do
        For PWM4 = 0 to 0x7E00 Step 0x100
            wait 10 ms
        Next
      Loop
      

      Full code is attached. I have added an 8Hz demo - works very nicely.

      Enjoy

       

      Last edit: Anobium 2021-12-19
  • David Stephenson

    Of course you could "roll you own". As you cannot expect every situation to be covered by the GCB compiler. Here's an example...

    sub inipwm5
    pwmtmrs=b'00000101' 'select timer2 for all
    pwm5con=b'00000000' 'clr reg
    pr2=199 'set period 5 kHz
    'Fosc/(Fpwm*4) - 1
    pwm5dch=100 '100 ->50%
    'high bits=(pr2+1)*duty
    pwm5dcl=0 'set duty cycle
    pir1.1=0 'clr interrupt timer2
    t2con=b'00000100' 'start timer
    dir porta.0 out 'enable PWM pin
    set pwm5con.7 on 'enable PWM5
    end sub
    
     
    • Anobium

      Anobium - 2021-12-19

      Great Cow BASIC is intended to cover the majority of cases. The fixed mode PWM is extremely useful and shows the sheer power of the compiler across all the chips.

       
  • Stefano Corradini

    Yes, I agree, GCB it's a good balance of several points and I'm sure it's difficult to cover different requirements related to different chips.
    But, it seems that to achieve a low frequency pwm requires "some complication" (thanks to Anobium and David for Your suggestions).

    @ Anobium: I saw fixed mode, and it could be the best solution for me... I didn't think at it because in manual there are these statements:
    - The fixed mode can use CCP1 only, and, the parameters of the PWM cannot be dynamically changed in the user program. The parameters are fixed by the definition of two constants.
    since I have to change it, I thought it wasn't the solution I'm looking for,
    - These are the PWM timers supported by the PWM modules, where nn is the frequency.
    in this case I thought that nn was again just an integer, if it isn't so, could I set it as 0.05 (50Hz)?

    Please consider I'm using a 16F88 and its capability are few as comparison to chips such as 16F1719, moreover some of these things require the max of knowledge I have at the moment.
    OK, it could be a motivation to learn more (or to change type of chip... :)

     
  • Anobium

    Anobium - 2021-12-19

    16F88 - works in the same way, but, easier.

    There is no complexity to the using low freq simply use #define PWM_Freq .5 'Frequency of PWM in KHz

    Evan


    Re

    The fixed mode can use CCP1 only, and, the parameters of the PWM cannot be dynamically changed in the user program. The parameters are fixed by the definition of two constants.

    This is correct from the basic usage. If you change the registers, using some logic, then this you can change the duty (and, even the Freq). See the attached demo.

    These are the PWM timers supported by the PWM modules, where nn is the frequency.
    in this case I thought that nn was again just an integer, if it isn't so, could I set it as 0.05 (50Hz)?

    When using the fixed mode the calculation can use non-integers, as in the demo attached. The calcs are completed within the preprocessor of the compiler and therefore.


    Same code for a 16F88 is attached. As the chip is NOT a PPS, and, use the CCP PMW the code is easier but very similar.

    Enjoy

     
  • Stefano Corradini

    Hi Evan, thanks a lot for explanation.
    In the last example You kindly sent me, I see that the frequency for 16F88 is set to 0.125 (MHz, of course) while the PWM_Freq is 0.5 (kHz as stated in comment), so I see that these two parameters aren't limited to integers... that's sound very nice to me, I didn't find this in manual.

    "Enjoy" ... it's absolutely right! My plans are to try but also to have however a look to CCP functioning.
    I see it's not unavoidable, but it's in case of need to override some setup and to increase a little bit my knowledge ( I read the alias for register CCPR1L and it's a new challenge for me... :) ).

    Thanks again for kindness and support and please accept my Wishes for Merry Xmas and Happy New Year!

     
    • Anobium

      Anobium - 2021-12-20

      Do enjoy.

      There a few places where a Constant value can be a decimal value. :-)

      The simple code shows that the compiler can really help, and, the documented ASM help learn the specific registers of a specifc chip.

      My advice, if you can, put that old chip in the bin and buy a new chip. Faster and more capable. Try a 18fxxK42

       
  • Stefano Corradini

    Hi Evan,
    I did the test and also some "in depth" reading of CCP functioning ... :)
    It's ok, I just have a little note regarding the line
    Dir Portb.0 out
    The (old) 16F88 has the CCP1 out on RB3 as default, unless the Configuration Word 1 register isn't changed and so I changed the Dir statement accordingly.
    I also see that's right about (few) availability of decimal values, checking other modes .
    Anyway, thanks again for help, now I can go on adding further code for the application I have in mind.
    About suggestion: yes, I'm aware there are better chips, but I have to use not so big devices, with few pins and in PDIP case.

     
    • Anobium

      Anobium - 2021-12-26

      Dir is very specific to the chip. So, I add to ensure all ok.

      Enjoy.

       
  • Stefano Corradini

    Hi Evan,
    everything works like a charm... :)
    for the sake of correctness, I must sat that You was right: the output pin is RB0 as You wrote and not RB3 as I supposed.
    The default value for the related register is 0x3FFF but it's a 14 bit,
    It isn't in datasheet (!), I found it here in SourceForge:
    https://gputils.sourceforge.io/html-help/PIC16F88-conf.html
    Anyway, thanks again.
    Cheers,
    Stefano

     
    • Anobium

      Anobium - 2022-01-05

      Excellent!

      :-)

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.