Ok, sorry to dig up this old thread, but now that I actually go to integrate it into a project, I seem to have forgotten that perfect view of the solution I had a month ago :) I am looking to use the code at http://www.dattalo.com/technical/software/pic/pwm8.asm to do multiple PWMs on one chip. My basic question is...where and when do I update the PWM counters? I plan on putting the timer checking and updating in an ISR, and triggering it with a TMR0 interrupt. This will work on the first iteration, but once a counter has hit zero, doesn't it just start again at 255? Therefore, I would need to reload the value I want in the counter so that it will start to count down again. What if after: DECFSZ pwm0,F ;If the first counter has not reached 0 IORLW 00000001b ;then we don't want to turn it off. I add something to the effect of: check pwm0 for zero if zero, reload pwm0 with proper value This would still be in the ISR. How does this sound? Plausible? Am I on the right track? I'm using an 18f252 chip, so I was thinking about using the BZ (Branch if Zero) operand. I guess I would have to do a movf pwm0,f in order to trigger the zero bit. If only there was an instruction similar to TSTFSZ (Test f, skip if 0), but skip if not zero. Can having the branch operand in an ISR cause a stack overflow if I run too many of them? Anyway, as per usual, any and all help/advice/assistance is appreciated. Thanks, Josh -- A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools. -Douglas Adams Scott Dattalo wrote: > Well, as Olin suggested, the PWM routine can be placed in a Timer > interrupt routine. You could run > > http://www.dattalo.com/technical/software/pic/pwm8.asm > > For 23 cycles / 8 PWM's. Or 46 cycles for 16 PWMs. For the last two PWMs > you could shrink the routine to just this: > > CLRW ;Build the bit mask for turning > ;off the PWM outputs. Assume that > ;all of the outputs will be turned > ;off. > ; > DECFSZ pwm0,F ;If the first counter has not reached 0 > IORLW 00000001b ;then we don't want to turn it off. > ; > DECFSZ pwm1,F ;Same for the second one > IORLW 00000010b ; > > ANDWF pwm_state,W ; Clear all of those pwm outputs > ;that have reached zero. > ; > XORLW 00000011b ;Toggle the current state. > INCFSZ rising_edge,F ;If the rising edge counter has not > XORLW 00000011b ;rolled over then toggle them again. > ;Double toggle == no effect. However, > ;if the rising edge counter does roll > ;over then a single toggle will turn > ;the pwm bits on, unless of course the > ;pwm counter has just rolled over too. > ; > MOVWF pwm_state ;Save the state > MOVWF PWM_PORT ;update the outputs > > That'd be 58 cycles for 18 outputs. If TMR0 is the interrupt source and > you don't select the prescaler, then you'd have ~75% of the CPU time > available for other things. Those "other things" would be updating all > those PWMs! (BTW, there's a way to save a few cycles by combining the > checks for "rising_edge"). -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.