PHXSYS wrote: > > Hello > > I have an application where I want to PWM a FET to drive a gauge. Is there any > rule for the frequency PWM should be applied. I don't want to dedicate my > 16F84 to a PWM task. Can I run at i.e. 50HZ and complete other tasks in > between, kind of like a R/C servo? I suppose it really depends on the > characteristics of the driven device, but I am looking for some general rules. General rule 1: The faster the PWM frequency the better. Of course there are exceptions, but this is a GENERAL rule. For your application, I would suggest implementing an RTCC interrupt routine and do something like this with phased counters: At the beginning of every interrupt: Save_registers: ; .... ;PWM code DECFSZ rising_edge_counter,F goto $+2 BSF PWM_PORT,PWM_BIT DECFSZ falling_edge_counter,F goto $+2 BCF PWM_PORT,PWM_BIT the_rest_of_the_interrupt: ;... And in the main code do something like this: ;Timer initialization code .... ;Get the pulse width CALL get_next_pulse_width ;Disable interrupts ; PIC dependendent.... CLRF rising_edge_counter MOVF pulse_width,W MOVWF falling_edge_counter ;Enable interrupts .... The way this code works is by comparing the phase of two roll-over (or actually roll-under) decrementing counters. A picture explains it best: rise -------_-----------------------_------------------------ fall -------------_-----------------------_------------------ PWM _______------__________________------___________________ Both counters rollover at the same rate. However, the time at which they rollover is different. When the rising edge counter rolls over, the PWM output is turned on. When the falling edge counter rolls over, the PWM output turns off. I like this approach because nothing needs to be 'done' once the pulse width is defined. The rollover automagically takes care of everything. There's a neat trick with vertical counters that will allow you to expand on this concept and have 4 PWMs at the same time. If you don't have the luxury of interrupts, then you might consider this approach. CALL get_next_pulse_width COMF pulse_width,W MOVWF pulse_low ;Turn the PWM port into an output BSF STATUS,RP0 BSF PWM_PORT,PWM_BIT BCF STATUS,RP0 BSF PWM_PORT,PWM_BIT ;High DECFSZ pulse_width ;loop for high time goto $-1 BCF PWM_PORT,PWM_BIT ;low DECFSZ pulse_low ;loop for low time goto $-1 ;Turn the PWM port into an input (and thus high impedance) BSF STATUS,RP0 BCF PWM_PORT,PWM_BIT BCF STATUS,RP0 This approach generates a single pulse width modulated pulse and then turns the PWM output into an input. (I'm assuming there's an RC filter at the PWM output that's grabbing just the DC component.) While the I/O line is an input it has high impedance and thus does not significantly load the RC filter. While the I/O line is an output it of course is being PWM'd and thus generates the desired signal. I tried a variation of this (the above code has not been tested) to cut the number I/O pins in half needed for Byte Craft Tip #4. BC tip #4 is an 'A/D converter' made from two PIC I/O pins, a couple resistors, and a capacitor. Dynamically changing the I/O direction allows you to implement the tip with just one I/O pin. Unfortunately, 5-bits was about all it was good for. Scott