Shop OBEX P1 Docs P2 Docs Learn Events
A "?" about the PWM object. — Parallax Forums

A "?" about the PWM object.

Zap-oZap-o Posts: 452
edited 2009-04-17 22:15 in Propeller 1
I was thinking I needed better duty resolution than 0-100 as is the current limit on the PWM object in the OB-Exchange.

Would I be exceeding some limit if I were to set the limit to 10_000?

{A simple pwm object based on code from AN001 - propeller counters
 Author: Jev Kuznetsov
 date  : 16 Oktober 2007

 usage

 OBJ
        pwm : pwmAsm

  ....

  pwm.start( Pin)               ' start pwm
  pwm.SetPeriod( period )       ' set pwm period in clock cycles
  pwm.SetDuty( duty)            ' set duty in %                               
  pwm.Stop

}
VAR
  long cog       
  long sDuty                     ' order important (the variables are read from memory in this order)  
  long sPinOut 
  long sCtraVal
  long sPeriod
  

PUB Start( Pin)  : success 
'start pwm on Pin @ 80 kHz
  longfill(@sDuty, 0, 4)       
  sDuty := 50                   ' default duty
  sPinOut := |< Pin   
  sCtraVal :=  %00100 << 26 + Pin
  sPeriod := 1000
 stop   
 Success := (cog := Cognew(@entry,@sDuty) + 1)   
  
PUB stop

'' Stop object - frees a cog
  if cog
  
    cogstop (cog~ -1) 
     longfill(@sDuty, 0, 4) 

PUB SetPeriod(counts)
' set pwm period in clock cycles, frequency = (_clkfreq / period)
   sPeriod := counts
   
PUB SetDuty(counts)
   if (counts < 0)
     counts := 0
     
   if (counts > 100)
     counts := 100
     
   sDuty := counts * sPeriod / 100

DAT
'assembly cog which updates the PWM cycle on APIN
'for audio PWM, fundamental freq which must be out of auditory range (period < 50µS)
        org

entry   mov     t1,par                'get first parameter
        rdlong  value, t1
         
        add     t1,#4                 
        rdlong  pinOut, t1
        or      dira, pinOut         ' set pinOut to output      

        add     t1, #4
        rdlong  ctraval, t1
        mov ctra, ctraval              'establish counter A mode and APIN

        add     t1, #4
        rdlong  period, t1


        mov frqa, #1                   'set counter to increment 1 each cycle

        mov time, cnt                  'record current time
        add time, period               'establish next period

:loop   rdlong value, par              'get an up to date pulse width
        waitcnt time, period           'wait until next period
        neg phsa, value                'back up phsa so that it  trips "value" cycles from now
        jmp #:loop                     'loop for next cycle



period  res 1                    
time    res 1
value   res 1
t1      res 1
pinOut  res 1
ctraval res 1





Since I am not as fluent in assembly as I would like to be I can not guess on what being done. So this Is why I ask. If I substitute a part of the code with the following will serious problems surface?

PUB SetDuty(counts)
   if (counts < 0)
     counts := 0
     
   if (counts > 100000)
     counts := 100000
     
   sDuty := counts * sPeriod / 100000

Comments

  • PhilldapillPhilldapill Posts: 1,283
    edited 2009-04-17 20:09
    You should be able to do 10,000 duty resultion with LOW frequency. If you are trying to do this with a frequency of, say 10kHz, I don't know if your resolution willstill be 1/10,000.
  • Zap-oZap-o Posts: 452
    edited 2009-04-17 20:21
    I want to run it at 10K max.

    Hum It seems to be working so far I just hate using something I am not completely familiar with. Thanks for the quick response Philldapill
  • PhilldapillPhilldapill Posts: 1,283
    edited 2009-04-17 20:52
    Zap-o, it may be "working", as in the program runs, but I don't think you actually have 0.01% resolution. I modified that same PWM object to have 0.1% resolution, but I have no way of knowing if it is REEEALLY that precise. at 0.01% resolution, you would need at minimum, 10,000 clocks per cycle. At 20MIPS(assuming it takes 1 insturction), the absolute highest frequency you can have with 0.01% resolution is 20MIPS/10,000 = 2kHz.

    That is, if I understand the PWM object correctly. Any "wizards" want to chime in?(PhiPi?)
  • Zap-oZap-o Posts: 452
    edited 2009-04-17 22:15
    Yea I am running various test and can see that there is an underlying limit.

    My problem is I cant seem to find it. If I set the period to 8_000 it seems to work. If I go over this it wants to not work which is backwards as I calculate it to be

    Given
    frequency = (clkfreq / period)
    8_000 = (80Mhz / period)
    I get a total period of 10Khz

    Any thing over 8_000 i.e. 10_000 should lower the period making it seemingly work better ? Am I thinking correctly here?
Sign In or Register to comment.