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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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...)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
#chip16f1719,1
#optionExplicit'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'
#startupInitPPS, 85SubInitPPS'Module: PWM4RB5PPS=0x000F'PWM4OUT > RB5EndSub'Template comment at the end of the config file
#definePWM_Timer2_Freq .5'Set frequency, just change the number
#definePWM_4_Duty50'Set the duty, just change the value
#definePWM_4_Clock_Source2'Set the clock source'Set the PWM as an outputDirPortb.5out'Enable PWM ModulesPWMOn(4, PWMModule)'Enable PWM ModuleDoLoop
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
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.
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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... :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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?
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...)
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
regarding GCGB... the UI does not support the extra parameter.
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.
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.
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 isSo, 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 forSETPWMDUTYCODE
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.
Full code is attached. I have added an 8Hz demo - works very nicely.
Enjoy
Last edit: Anobium 2021-12-19
Of course you could "roll you own". As you cannot expect every situation to be covered by the GCB compiler. Here's an example...
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.
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... :)
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
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.
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
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!
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
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.
Dir is very specific to the chip. So, I add to ensure all ok.
Enjoy.
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
Excellent!
:-)