i have some pic10f322 chips i was looking at using due to their size ( sot 23-6 ) and needing one pwm output, but as they do not have a ccp module this gives 2 options, either software pwm (which cannot run independently im sure i read somewhere) or using the chips pwm module but needing to use the associated registers.
i would prefer to use the registers for the pwm as i would like one or two other things to be done by the pic10f as well but i cannot comfortably get the swing of it and often get lost with fosc/ tosc, how to know what value i need to put in the PR2,dch:dcl registers ect ect
does anyone have any usefull guides/tutorials or the like to make the whole setting of pwm registers and understanding how i come to the solution of what values i put into them.
i have looked at too many different supposed tutorials via google but everyone has their own way of explaining things and it gets very confusing very quickly, understanding these registers and comfortably calculating/using them is something i really should be able to get to grips with.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
But the 10f322 has two PWM modules but no CCP like you say.
The datasheet has explicit instructions on how to setup. I could not explain it better. Best to roll up the sleeves and have a play with the PR2, TMR2 and prescale registers to see the cause and effect.
Some starter code to have a play with:
'set up CCP1 for PWM
#define PWM PORTA.0
dir PWM in 'disable PWM pin
PWM1CON = 0
PR2 = 255 'makes for best resolution
'PR2 = 0x3F '63 kHz with 1:1 prescale 16Mhz clock
'PR2 = 0x65 '4.9 Khz with 1:1 prescale 8 Mhz clock
PWM1DCH = 0 'be sure to clear low and high DC bits
PWM1DCL = 0 'O.K. to turn on for AL8805 to get max dutycyle??? no diff D.C still = 99.6%
'TMR2IF = 0
'*&#! 310 Hz with Fosc=8,PR2=0x65,prescale=64:ps=4 !%@!:ps=1 $&!!!
'7.9 kHz with Fosc=8,PR2=0x255,prescale=1 NOT BAD steady PWM still blinky at low D.C.
'1.975 kHz with Fosc=8,PR2=0x255,prescale=4 NOT BAD steady PWM still blinky at low D.C.
'493 Hz with Fosc=8,PR2=0x255,prescale=64 NOT BAD steady PWM still blinky at low D.C.
T2CON = b'00000110' 'set prescaler = 64 and start TMR2
'T2CON = b'00000101' 'prescale = 4
'T2CON = b'00000100' 'prescale = 1 and start TMR2 19kHz with PR2 = 0xFF
dir PWM out 'enable PWM pin
PWM1CON = b'11000000' 'enable PWM1 module and PWM1 pin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The latest version of Great Cow BASIC does support PWM (using the PWM module) and the CCP/PWM approach. However, the chip you have is limited in RAM so I agree with Kent - datasheet and MCC will help.
A few pointers - timer2 - use the standard Great Cow BASIC libraries - I see little point in rewriting all that code (but, if you want to - then do).
For PWM - it is really only a registers - see the code below this is essentially the register shown in Kents posting.
Anobium
#chip 10f322,16
#Config WRT_OFF, MCLRE_ON,
#define PMWOUT1 PORTA.0
Dir PMWOUT1 OUT
'Setup the timer
Inittimer2 16, 1
StartTimer 2
'PWM1POL active_high, PWM1OE disabled and PWM1EN enabled
PWM1CON = 0x80;
'50% PWM based upon TMR2
'PWM1DCH 127
PWM1DCH = 0x7F;
'PWM1DCL 3;
PWM1DCL = 0xC0;
do forever
loop
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
thanks for the help guys, its not so much not reading the datasheet its just trying to understand how i come to the values i need to apply for each register, the calculation examples given can be a bit confusing and i end up going around in circles.
the kids and wife are snoozing away now so i have been spending the last hour or two armed with ipad and many different browser windows open along with notepad and calculator putting pieces together and finally sort of getting it.
its been 20 years since i left school and i sure as heck dont remember any maths class having funky calculations like the microchip sheets ( dots used for a multiply symbol dont help, or no arithmatic symbol between values that assumably need to be calculated with each other) lol but i think im a bit more on course with it now for understanding ( gradually ).
i will just have to sit down and play with some code and hardware over the next day or two, thankfully i will only need two different duty cycle values to switch between so once i get the calculations down on paper then i can test with the chip and stick the logic analyzer on the output as well and see how it goes.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Good approach. Some working code helps. Try this below, examine, then change the values - this is a good learning appoach. This will give you a 50% @ 125Khz. Over to you
#chip 10f322,16
#Config MCLRE_ON
#define PMWOUT1 PORTA.0
Dir PMWOUT1 OUT
' PWM1POL active_hi, PWM1OE enabled and PWM1EN enabled
PWM1CON = 0xC0
'Set PWM hi value
' PWM1DCH 15
PWM1DCH = 0x0F
'Set PWM lo value
' PWM1DCL 3
PWM1DCL = 0xC0
' T2CKPS 1:1, TOUTPS 1:16 and TMR2ON off
T2CON = 0x78
' PR2 31 - PWM pr2 value
PR2 = 0x1F
StartTimer 2
do forever
loop
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
well the logic shows a duty cycle of 5.6% but the frequency shows as 7.96khz so its a start to understanding the registers, so now ill go and have a look at your recent demo code evan.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ok i calculated my pr2 value wrong for my desired 2khz, correctly redone with pr2 value of 249 and now its showing 2khz bang on with the logic, now to check my duty cycle calculation again.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
PWM2CON = b'11000000' 'enable PWM1 module and PWM1 pin
; ----- Main body of program commences here.
do
loop
~~~
and screenshot of logic data.
thanks evan and kent for the code snippets and advice,now using pwm directly via registers is not so much a daunting task now :)
tony
edit:
just in case anyone else is as dumbfounded as i was with these registers this is the info i used to correctly (eventually) calculate them, if you know the preferred frequency and duty cycle you would like then this should help, copied from microchips wikidot site :
Frequency
Typically a desired frequency is already known so the period formula can be reworked to solve for the PR2 value that meets the frequency requirement.
(1)
PR2=[(Fosc)/(4∗TMR2Prescale∗PWMFrequency)]−1
For example, if we use the internal oscillator set to Fosc = 4 Mhz along with a TMR2 prescaler of 1:16 and want a PWM with a frequency of 500 Hz; then PR2 is calculated to be 124:
(2)
PR2=[4Mhz/(4∗16∗500Hz)]–1=124
If the number ever calculates to a value larger than 255, then you would have to increase the prescaler to a larger ratio or lower the oscillator speed.
Duty Cycle
The Duty Cycle desired is also typically a known value, so once the frequency is set via the PR2 value then the pulse width calculation can be reworked to solve for the PWMxDCH:PWMxDCL value with the formula below:
(3)
PWMxDCH:PWMxDCL=4∗(PR2+1)∗DutyCycleRatio
Since PR2 was already calculated as 124, and assuming a 50% duty cycle, then the answer below is calculated:
(4)
PWMxDCH:PWMxDCL=4∗(124+1)∗0.5=250
250 in binary is 0011111010 which gets broken up between the two registers to:
just managed to sit down now and load your code onto the pic evan, that is quite interesting to watch the led's brightness slightly dim as the frequency value is incremented, a nice little piece of code.
now to dig out the shoe horn and squeeze the rest of what i will try and get into this tiny little chip and program space lol
thank you kent and evan,something else new and worthwhile has been pushed into the grey matter at last with regard to those once daunting pwm registers.
having the bult in gcb functions for pwm is quite often a time and headache saver and used in quite alot of my other projects but now i can use option b if im in a bind with things like this pic10f.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The 10f322 was truly a godsend when it came out. Try the 10f200 or 10f222 if you really want to feel uncomfortable :), or NOT if you value your time saved with GCBasic commands.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i do actually have some of those laying around as well, in pdip and yes sot 23-6 ( i have serious obsession issues with tiny smt bordering shamefull addiction :P ), i know what you mean with those ones lol tried some gcb on one once and that was it.
for the size of these 10f322 in sot 23-6 i may as well try and make some use of them as i only need the 4 pins they offer but dont like wasting pins of the bigger chips if i can avoid it but anyway i can now attempt to move forward with this and squeeze the buggers full lol.
thanks for your help with these kent.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ok one other question i forgot to ask was regarding one of the bits in the PWMxCON register, what is the purpose of bit 5 PWMxOUT, all it states is "pwm module output value bit", what does that relate to?
im not sure of that one or what its function is, i can see the other appropriate bits for enabling the module, enabling the pin and changing the polarity but this bit 5 has me stumped with no clue to its intended purpose.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Have a look at the block diagram, it shows PWMxOUT can go to the CLC or the CWG. With the CWG added to the PWM module it looks a lot like a CCP or ECCP module in more advanced devices. So you could do half or full bridge motor control or any number of other things. I think I tried current control LED with the shutdown and autorestart feature with a compartor input. Further investigation required if that really works or not. Not sure how it would be used with the CLC.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i have some pic10f322 chips i was looking at using due to their size ( sot 23-6 ) and needing one pwm output, but as they do not have a ccp module this gives 2 options, either software pwm (which cannot run independently im sure i read somewhere) or using the chips pwm module but needing to use the associated registers.
i would prefer to use the registers for the pwm as i would like one or two other things to be done by the pic10f as well but i cannot comfortably get the swing of it and often get lost with fosc/ tosc, how to know what value i need to put in the PR2,dch:dcl registers ect ect
does anyone have any usefull guides/tutorials or the like to make the whole setting of pwm registers and understanding how i come to the solution of what values i put into them.
i have looked at too many different supposed tutorials via google but everyone has their own way of explaining things and it gets very confusing very quickly, understanding these registers and comfortably calculating/using them is something i really should be able to get to grips with.
tony
But the 10f322 has two PWM modules but no CCP like you say.
The datasheet has explicit instructions on how to setup. I could not explain it better. Best to roll up the sleeves and have a play with the PR2, TMR2 and prescale registers to see the cause and effect.
Some starter code to have a play with:
The latest version of Great Cow BASIC does support PWM (using the PWM module) and the CCP/PWM approach. However, the chip you have is limited in RAM so I agree with Kent - datasheet and MCC will help.
A few pointers - timer2 - use the standard Great Cow BASIC libraries - I see little point in rewriting all that code (but, if you want to - then do).
For PWM - it is really only a registers - see the code below this is essentially the register shown in Kents posting.
Anobium
thanks for the help guys, its not so much not reading the datasheet its just trying to understand how i come to the values i need to apply for each register, the calculation examples given can be a bit confusing and i end up going around in circles.
the kids and wife are snoozing away now so i have been spending the last hour or two armed with ipad and many different browser windows open along with notepad and calculator putting pieces together and finally sort of getting it.
its been 20 years since i left school and i sure as heck dont remember any maths class having funky calculations like the microchip sheets ( dots used for a multiply symbol dont help, or no arithmatic symbol between values that assumably need to be calculated with each other) lol but i think im a bit more on course with it now for understanding ( gradually ).
i will just have to sit down and play with some code and hardware over the next day or two, thankfully i will only need two different duty cycle values to switch between so once i get the calculations down on paper then i can test with the chip and stick the logic analyzer on the output as well and see how it goes.
tony
Good approach. Some working code helps. Try this below, examine, then change the values - this is a good learning appoach. This will give you a 50% @ 125Khz. Over to you
This got me thinking. What a good demo program! Decomposing this program to learn. Tony thank you.
I just posted an adapted version of this code to the demo folders here
Put a scope or LED on Porta.0 and examine. Then, change the parameters - cool! I think this is a good learning aid.
thanks evan, i have just managed to sit down and grab some time to attempt the register calculations.
at the moment just random oscillator and duty cycle values to play with
as an example 8mhz clock, 4:1 prescaler and desired frequency of 2khz i came to the following numbers:
20% duty cycle:
PR2 = 62
PWMxDCH = b'00001111
PWMxDCL = b'11000000
95% duty cycle:
PR2 = 62
PWMxDCH = b'00111100
PWMxDCL = b'00000000
am i hopefully sort of /even close or way off in the distance, no time to get back to the breadboard yet to try in hardware, fingers crossed lol
tony
ok i have just loaded this code onto the 10f and have just had a quick mess around with the register for 20% and then 5% and see changes to the led
the test code used for 5%
~~~
#chip 10f322, 8
#config MCLRE = off
'set up CCP1 for PWM
define PWM PORTA.1
dir PWM in 'disable PWM pin
PWM2CON = 0
PR2 = 62
PWM2DCH = b'000000011'
PWM2DCL = b'010000000'
T2CON = b'00000101' 'prescale = 4
dir PWM out 'enable PWM pin
PWM2CON = b'11000000' 'enable PWM1 module and PWM1 pin
; ----- Main body of program commences here.
do
loop
~~~
ill just have to dig the logic analyzer out and see what it shows for frequency,
tony
Last edit: tony golding 2016-09-06
well the logic shows a duty cycle of 5.6% but the frequency shows as 7.96khz so its a start to understanding the registers, so now ill go and have a look at your recent demo code evan.
tony
ok i calculated my pr2 value wrong for my desired 2khz, correctly redone with pr2 value of 249 and now its showing 2khz bang on with the logic, now to check my duty cycle calculation again.
tony
ok finally all done and correct, 2khz frequency and 5% duty cycle
corrected code and registers
~~~
#chip 10f322, 8
#config MCLRE = off
'set up CCP1 for PWM
define PWM PORTA.1
dir PWM in 'disable PWM pin
PWM2CON = 0
PR2 = 249
PWM2DCH = b'000001100'
PWM2DCL = b'010000000'
T2CON = b'00000101' 'prescale = 4
TMR2 = 0
dir PWM out 'enable PWM pin
PWM2CON = b'11000000' 'enable PWM1 module and PWM1 pin
; ----- Main body of program commences here.
do
loop
~~~
and screenshot of logic data.
thanks evan and kent for the code snippets and advice,now using pwm directly via registers is not so much a daunting task now :)
tony
edit:
just in case anyone else is as dumbfounded as i was with these registers this is the info i used to correctly (eventually) calculate them, if you know the preferred frequency and duty cycle you would like then this should help, copied from microchips wikidot site :
Frequency
Typically a desired frequency is already known so the period formula can be reworked to solve for the PR2 value that meets the frequency requirement.
(1)
PR2=[(Fosc)/(4∗TMR2Prescale∗PWMFrequency)]−1
For example, if we use the internal oscillator set to Fosc = 4 Mhz along with a TMR2 prescaler of 1:16 and want a PWM with a frequency of 500 Hz; then PR2 is calculated to be 124:
(2)
PR2=[4Mhz/(4∗16∗500Hz)]–1=124
If the number ever calculates to a value larger than 255, then you would have to increase the prescaler to a larger ratio or lower the oscillator speed.
Duty Cycle
The Duty Cycle desired is also typically a known value, so once the frequency is set via the PR2 value then the pulse width calculation can be reworked to solve for the PWMxDCH:PWMxDCL value with the formula below:
(3)
PWMxDCH:PWMxDCL=4∗(PR2+1)∗DutyCycleRatio
Since PR2 was already calculated as 124, and assuming a 50% duty cycle, then the answer below is calculated:
(4)
PWMxDCH:PWMxDCL=4∗(124+1)∗0.5=250
250 in binary is 0011111010 which gets broken up between the two registers to:
(5)
PWMxDCH=00111110 : PWMxDCL=10
Last edit: tony golding 2016-09-06
just managed to sit down now and load your code onto the pic evan, that is quite interesting to watch the led's brightness slightly dim as the frequency value is incremented, a nice little piece of code.
now to dig out the shoe horn and squeeze the rest of what i will try and get into this tiny little chip and program space lol
thank you kent and evan,something else new and worthwhile has been pushed into the grey matter at last with regard to those once daunting pwm registers.
having the bult in gcb functions for pwm is quite often a time and headache saver and used in quite alot of my other projects but now i can use option b if im in a bind with things like this pic10f.
tony
The 10f322 was truly a godsend when it came out. Try the 10f200 or 10f222 if you really want to feel uncomfortable :), or NOT if you value your time saved with GCBasic commands.
i do actually have some of those laying around as well, in pdip and yes sot 23-6 ( i have serious obsession issues with tiny smt bordering shamefull addiction :P ), i know what you mean with those ones lol tried some gcb on one once and that was it.
for the size of these 10f322 in sot 23-6 i may as well try and make some use of them as i only need the 4 pins they offer but dont like wasting pins of the bigger chips if i can avoid it but anyway i can now attempt to move forward with this and squeeze the buggers full lol.
thanks for your help with these kent.
tony
ok one other question i forgot to ask was regarding one of the bits in the PWMxCON register, what is the purpose of bit 5 PWMxOUT, all it states is "pwm module output value bit", what does that relate to?
im not sure of that one or what its function is, i can see the other appropriate bits for enabling the module, enabling the pin and changing the polarity but this bit 5 has me stumped with no clue to its intended purpose.
tony
Have a look at the block diagram, it shows PWMxOUT can go to the CLC or the CWG. With the CWG added to the PWM module it looks a lot like a CCP or ECCP module in more advanced devices. So you could do half or full bridge motor control or any number of other things. I think I tried current control LED with the shutdown and autorestart feature with a compartor input. Further investigation required if that really works or not. Not sure how it would be used with the CLC.
ah ok, thanks kent i overlooked that diagram and was looking more at the descriptions trying to find it.
tony