Searching \ for '[PIC]: Ultra fast low res PWM challenge' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ios.htm?key=pwm
Search entire site for: 'Ultra fast low res PWM challenge'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Ultra fast low res PWM challenge'
2002\02\20@095334 by Michael Rigby-Jones

flavicon
face
I've spent some time playing with an RC car controller and needed a very
fast 2 channel PWM routine.  Resolution was not important, so 8 steps (3
bits) was fine.

My first attempt which I'm sure can easily be bettered:

       clrf    outport         ; clear shadow register
       incf    pwmcount,w      ; increment pwm counter
       andlw   0x07            ; 8 step PWM, so roll counter over after 7
       movwf   pwmcount

       movf    pwmset1,w
       subwf   pwmcount,w      ; subtract setpoint from counter
       skpc
       bsf     outport,0       ; result negative so turn on PWM output in
shadow register

       movf    pwmset2,w
       subwf   pwmcount,w      ; subtract setpoint from counter
       skpc
       bsf     outport,1       ; result negative so turn on PWM output in
shadow register

So this gives a 4 cycle overhead for the counter and clearing the shadow
register, and 4 cycles for each additonal channel. This actually gives nine
steps; 0 gives 0%, 8 or greater gives 100%.

I have seen Scott Dattalos very fast PWM routines, but they seem to incur
too much overhead if the duty cycle needs to be varied.

Regards

Mike

--
http://www.piclist.com hint: To leave the PICList
spam_OUTpiclist-unsubscribe-requestTakeThisOuTspammitvma.mit.edu


2002\02\20@122025 by Michael Rigby-Jones

flavicon
face
I've spent some time playing with an RC car controller and needed a very
fast 2 channel PWM routine.  Resolution was not important, so 8 steps (3
bits) was fine.

My first attempt which I'm sure can easily be bettered:

       clrf    outport         ; clear shadow register
       incf    pwmcount,w      ; increment pwm counter
       andlw   0x07            ; 8 step PWM, so roll counter over after 7
       movwf   pwmcount

       movf    pwmset1,w
       subwf   pwmcount,w      ; subtract setpoint from counter
       skpc
       bsf     outport,0       ; result negative so turn on PWM output in
shadow register

       movf    pwmset2,w
       subwf   pwmcount,w      ; subtract setpoint from counter
       skpc
       bsf     outport,1       ; result negative so turn on PWM output in
shadow register

So this gives a 4 cycle overhead for the counter and clearing the shadow
register, and 4 cycles for each additonal channel. This actually gives nine
steps; 0 gives 0%, 8 or greater gives 100%, which is actually quite handy.

I have seen Scott Dattalos very fast PWM routines, but they seem to incur
too much overhead if the duty cycle needs to be varied.  The pwm duty cyle
is set every loop, so this must be taken into consideration.

Regards

Mike

--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-requestKILLspamspam@spam@mitvma.mit.edu


2002\02\21@060943 by PY2NI

flavicon
face
   Hi I did something like this, ages ago (Z-80, 8085 era). I just use one
byte with a circular  counter. You just have to rotate and output one
particular bit (B0 ie.). I couldn't find nothing faster than this, Z80 has
rotates os shifts, I don't remember now, where the carry bit don't interfere
with operation, it makes the things even easier ( b0->b7 , b1 ->b2,....
b7->b6).
   You just have to perform the rotation and output a particular bit. Hope
it helps.


Regards
Horta


{Quote hidden}

nine
{Quote hidden}

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2002\02\21@063132 by Michael Rigby-Jones

flavicon
face
{Quote hidden}

Thanks for the tip, by coincidence I coded a rouine that does exactly that
last night.

       clrf            outport         ; clear all output bits in the
shadow register

       rrf             pwm1,w          ; put bit 0 into carry
       rrf             pwm1,f          ; rotate byte
       skpnc
       bsf             outport,0       ; if carry set and set output bit

       rrf             pwm2,w          ; put bit 0 into carry
       rrf             pwm2,f          ; rotate byte
       skpnc
       bsf             outport,1       ; if carry set, then set output bit

       movf    outport         ; update the PORT from the shadow reg
       movwf   PORTB

This is actually no faster than the original method, but has a couple of
advantages, and one disadvantage.  The disadvantage is that the duty cycle
can no longer be set directly, you have to translate to a bit pattern which
adds some overhead:

setpwm: ; call with duty cycle in W.  Need to add any bank switching, and
limit maximum W!!!
       addwf   PCL,f
       retlw   b'00000000'
       retlw   b'00000001'
       retlw   b'00010001'
       retlw   b'01001001'
       retlw   b'01010101'
       retlw   b'10110101'
       retlw   b'11101101'
       retlw   b'01111111'
       retlw   b'11111111'


To set a pwm channel you'd simply use the following which (I think) takes 8
cycles.

       movlw   5
       call            setpwm
       movwf   pwm1

One advantage of this method is that one byte less RAM is needed (no PWM
base counter), the other (possible) advantage is that the PWM frequency for
mid range settings can be increased which can make filtering easier, or
maybe reduce motor whine.  This is quite a nice way to do things if you have
the PWM running under an interrupt timer and it is not updated very
frequently.

Regards

Mike

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2002\02\21@162729 by Peter L. Peres

picon face
If you can live with 256 steps of resolution then you can use something
like:

       clrf    Fref
       incf    Fref,f          ; Fref = 1

pwm_again:
       incfsz  Fref,f
       goto    ($+2)
       clrf    Fio             ; all channels are 0

       ; first channel
       movlw   CH0_MASK        ; has a 1 in the o/p of that mask
       incfsz  Fch0,f          ; increment channel data directly
       goto    ($+2)
       iorwf   Fio,f           ; when crossing 0 set the bit

       ; next channel
       movlw   CH1_MASK
       incfsz  Fch1,f
       goto    ($+2)
       iorwf   Fio,f

       ; ... more like this

       ; code to load etc channels here (your choice)

       goto    pwm_again       ; forever

The code has constant run time and is very flexible, for example you can
replace the iorwf with xorwf or you can implement full stroke
(differential) PWM to achieve +/-5v excursion by using two io pins for a
channel and activating them 180 degrees out of phase, f.ex. by replacing
the clrf at the top of the loop with a suitable load and the iorwf of th
channel with a xorwf so both bits toggle together.

There will be a small bias (offset) added to each channel because of its
position in the loop (wrt the clrf).

If you allow the loop to run 256 times then you do not need to reload the
pwm counters in despite of their incrementing. You can also sequence the
channels (must if your PSU is crummy) by replacing the incfsz with decfsz
on certain channels.

The Fref contains a running phase reference that can be useful.

The loop timing is Tloop = 4 + 5 * channels + Your_Overhead + 2 cycles.
This times 256 is the PWM frequency. For 20 msec PWM period (standard
servos) and 4MHz clock and no interrupts (bit banged) you have 'time' for
14 channels in the loop. You can also eliminate the loop and have a fast
timer ISR run the code (but probably not at 4MHz).

If you reload the channel data at an unfortunate time the respective
output may skip one output pulse. To avoid this reload when Fref == 1 at
the bottom of the loop (or 0 at top).

hope this helps,

Peter

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


More... (looser matching)
- Last day of these posts
- In 2002 , 2003 only
- Today
- New search...