Scott, if I use the INFSNZ/BRA method you showed, do I still need to AND right before it? I've confused myself sufficiently to not be able to figure it out. Help! I like the NEGF version...I will investigate that once I get the problem I just mentioned clear in my head. Help! 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: > If you're using the 18F series then you can save an instruction: > > Instead of doing this (at the end of the routine) > > XORLW 11111111b ;Toggle the current state. > INCFSZ rising_edge,F ;If the rising edge counter has not > XORLW 11111111b ;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. > > You save the instruction by: > > INFSNZ rising_edge,F > BRA UpdatePWMs ;When the rising edge counter rolls over > ; then update everything. > > MOVWF pwm_state ;Save the state > MOVWF PWM_PORT ;update the outputs > > RETURN > > Then: > > UpdatePWMs: > > ; (note the reversed order from above - this ensures the > ; pwm_port is written isochronously). > > MOVWF PWM_PORT ;update the outputs > MOVWF pwm_state ;Save the state > > ; copy the current duty cycles into counters > > MOVFF pwm0DC,pmw0 > ... > > RETURN > > Everytime the "rising_edge" counter rolls over, 17 extra cycles are spent > updating the PWM counters. However, the counters don't need to be updated > if nothing has changed (they just roll over). So you could save 15 > instructions by adding a flag: > > UpdatePWMs: > > ; (note the reversed order from above - this ensures the > ; pwm_port is written isochronously). > > MOVWF PWM_PORT ;update the outputs > MOVWF pwm_state ;Save the state > > BTFSS ShouldUpdate,bitn > return > > BCF ShouldUpdate,bitn > > ; copy the current duty cycles into counters > > MOVFF pwm0DC,pmw0 > ... > > ---- > > You can also dynamically adjust the PWM. However, this runs the risk of > creating an abrupt discontinuity. See the comments in the code (on my web > page) on how this can be done. > > ---- > > BTW, If you're using the 18F there's a way to save many instructions: > > DCFSNZ pwm0,F ;When the pwm counter reaches 0 > BTG PWM_LATCH,0 ;toggle it's output > > .... > > DCFSNZ pwm7,F > BTG PWM_LATCH,7 > > DCFSNZ rising_edge,F > NEGF PWM_LATCH,F ; tricky - drive all ouput highs. > > 18 cycles versus 23. > > The NEGF works because all of the outputs are cleared by executing a > single BTG (bit toggle) instruction every 256 iterations. At the end of > 256 cycles, all 8 outputs are cleared and the NEGF will turn them all back > on. Of course, this assumes that when the PWM engine was started that the > output latch was initialized to all ones. > > A slightly better ending: > > DECFSZ rising_edge,F > RETURN > > NEGF PWM_LATCH,F > > ; update the PWM's: > > BTFSS ShouldUpdate,bitn > return > > BCF ShouldUpdate,bitn > > MOVFF pwm0DC, pwm0 > ... > > RETURN -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu