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