Menu

pwm registers, needing idiots tutorial/guide

Help
2016-09-06
2016-09-07
  • tony golding

    tony golding - 2016-09-06

    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

     
  • kent_twt4

    kent_twt4 - 2016-09-06

    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
    
     
  • Anobium

    Anobium - 2016-09-06

    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
    
     
  • tony golding

    tony golding - 2016-09-06

    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

     
    • Anobium

      Anobium - 2016-09-06

      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
      
       
  • Anobium

    Anobium - 2016-09-06

    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.

     
  • tony golding

    tony golding - 2016-09-06

    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

     
  • tony golding

    tony golding - 2016-09-06

    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
  • tony golding

    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

     
  • tony golding

    tony golding - 2016-09-06

    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

     
  • tony golding

    tony golding - 2016-09-06

    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
  • tony golding

    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

     
  • kent_twt4

    kent_twt4 - 2016-09-06

    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.

     
  • tony golding

    tony golding - 2016-09-07

    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

     
  • tony golding

    tony golding - 2016-09-07

    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

     
  • kent_twt4

    kent_twt4 - 2016-09-07

    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.

     
  • tony golding

    tony golding - 2016-09-07

    ah ok, thanks kent i overlooked that diagram and was looking more at the descriptions trying to find it.

    tony

     

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.