Searching \ for 'hardware PWM output pin' 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/io/pwm/index.htm?key=pwm
Search entire site for: 'hardware PWM output pin'.

Truncated match.
PICList Thread
'hardware PWM output pin'
1999\08\16@115932 by Andre Abelian

picon face
Hi to all engineers.

I was wondering if possible to change  hardware PWM  output pin.
In my project I need 4 outputs to turn each one on at different
duty cycle ( software PWM works ) but hardware PWM seams like
I am stock on one pin any idea ?

Andre

1999\08\17@003903 by Mark Willis

flavicon
face
Bit-banging it is the way I'd go, then.  Probably run 4 state machines
in one (something like this quick hack of a piece of protocode):  Here,
PWM1 is to be on 10 of 12 cycles, PWM2 12 of 40, etc.  (Yeah, it's not
optimized or anything, and it's untested.  So flame me <G>)  One obvious
optimization:  At runtime, if ratio can have common factors thrown out,
do so (i.e. case # 1 here would become 5 of 6, # 2 would become 3 of 10,
# 3 1 of 4, and # 4 stay the same.)

Bool PWM1State = False, PWM2State = False;
Bool PWM3State = False, PWM4State = False;
Int PWM1On = 10,  PWM1Cycles = 12,  PWM1Counter = 0;
Int PWM2On = 12,  PWM2Cycles = 40,  PWM2Counter = 0;
Int PWM3On = 15,  PWM3Cycles = 60,  PWM3Counter = 0;
Int PWM4On = 13,  PWM4Cycles = 20,  PWM4Counter = 0;

While (True) do
{
 PWM1State = (PWM1Counter < PWM1On);
 PWM2State = (PWM2Counter < PWM2On);
 PWM3State = (PWM3Counter < PWM3On);
 PWM4State = (PWM4Counter < PWM4On);
 SetPWMPins (PWM1State, PWM2State, PWM3State, PWM4State);
 PWM1Counter++;  If (PWM1Counter >= PWM1Cycles) PWM1Counter = 0;
 PWM2Counter++;  If (PWM2Counter >= PWM2Cycles) PWM2Counter = 0;
 PWM3Counter++;  If (PWM3Counter >= PWM3Cycles) PWM3Counter = 0;
 PWM4Counter++;  If (PWM4Counter >= PWM4Cycles) PWM4Counter = 0;
}

 Mark

Andre Abelian wrote:
>
> Hi to all engineers.
>
> I was wondering if possible to change  hardware PWM  output pin.
> In my project I need 4 outputs to turn each one on at different
> duty cycle ( software PWM works ) but hardware PWM seams like
> I am stock on one pin any idea ?
>
> Andre

1999\08\17@115550 by Andre Abelian

picon face
Sorry  Mark I am not good at C can you convert it to assembly.

Andre




{Quote hidden}

1999\08\17@131155 by Scott Dattalo

face
flavicon
face
On Tue, 17 Aug 1999, Andre Abelian wrote:

> Date: Tue, 17 Aug 1999 09:00:50 -0700
> From: Andre Abelian <spam_OUTengelecTakeThisOuTspamearthlink.net>
> To: .....PICLISTKILLspamspam@spam@MITVMA.MIT.EDU
> Subject: Re: hardware PWM output pin
>
> Sorry  Mark I am not good at C can you convert it to assembly.

Here's a routine I posted about a year or so ago that implements in
assembly mostly of what Mark writes in C. The only difference is that
these multiple pwms are synchronized. That is, they all turn on at the
same time but turn off at the time defined by the pwm pulse width. If you
need variable frequencies, I wrote one of those too using vertical
counters.

The way you'd go about using this routine is by:

1) define the pulse width of the 8 (or fewer ) pwms and store this info in
the pwm0-pwm7 file registers. You may wish to shadow these values since
the pwm_multiple routine will modify the registers.

2) Isochronously call pwm_multiple. It'd probably be easiest to just
create a timer interrupt and to call the routine from the handler (or
place it in line).




;------------------------------------------------------------
;pwm_multiple
;
;  The purpose of this routine is to generate 8 pulse width
;modulated waveforms. The algorithm consists of 9 counters
;that change the state of the pwm bits whenever they roll over.
;One of the counters, rising_edge, will drive the pwm bits
;high when it rolls over. The other 8 counters pwm0-pwm7 will
;drive their corresponding bits low when they roll over.
;
;
;RAM:
; pwm0-pwm7 - pwm counters
; rising_edge - rising edge counter
; pwm_state - current state of the pwm outputs.
;ROM
; 23 instructions
;Execution time
; 23 cycles

pwm_multiple

       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       ;
                               ;
       DECFSZ  pwm2,F          ;and so on...
        IORLW  00000100b       ;
                               ;
       DECFSZ  pwm3,F          ;
        IORLW  00001000b       ;
                               ;
       DECFSZ  pwm4,F          ;
        IORLW  00010000b       ;
                               ;
       DECFSZ  pwm5,F          ;
        IORLW  00100000b       ;
                               ;
       DECFSZ  pwm6,F          ;
        IORLW  01000000b       ;
                               ;
       DECFSZ  pwm7,F          ;
        IORLW  10000000b       ;
                               ;
                               ;
       ANDWF   pwm_state,W     ; Clear all of those pwm outputs
                               ;that have reached zero.
                               ;
       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.
                               ;
       MOVWF   pwm_state       ;Save the state
       MOVWF   PWM_PORT        ;update the outputs


you may want to update the pwmx counters when the rising edge counter
rolls over. So you could do something like:

       movf    rising_edge,w
       skpz
        return

       movf    pwm0_shadow,w
       movwf   pwm0
       .
       .
       .
Scott

{Quote hidden}

1999\08\17@191923 by Mark Willis

flavicon
face
Scott Dattalo wrote:
> On Tue, 17 Aug 1999, Andre Abelian wrote:
>
> > Date: Tue, 17 Aug 1999 09:00:50 -0700
> > From: Andre Abelian <engelecspamKILLspamearthlink.net>
> > To: .....PICLISTKILLspamspam.....MITVMA.MIT.EDU
> > Subject: Re: hardware PWM output pin
> >
> > Sorry  Mark I am not good at C can you convert it to assembly.
>
> Here's a routine I posted about a year or so ago that implements in
> assembly mostly of what Mark writes in C. The only difference is that
> these multiple pwms are synchronized. That is, they all turn on at the
> same time but turn off at the time defined by the pwm pulse width. If you

Quite do-able in my QuickHack code, just set the PWM{i}Cycles numbers
all to the same in my routine <G>  Probably a better way to do it in
Assembly, here, and you save 3 Int's worth of storage - I did say it
wasn't optimized <G>.  I'll also add that it's sometimes good to use a
comparison on PWM'ing, to a variable (like my PWM1On) instead of to a
constant (for example: if you're trying to PWM 3.3VDC from 5VDC off a
PIC pin, you want to do feedback, watching the actual voltage, not the
theoretical voltage!)  (Make sure your algorithm does what you need it
to do, not just what "theoretically is right", for you beginners <G>)

10 second C lesson, here:  (Not that this was really C, more quick &
dirty C-Like Pseudocode <G>)

Bool PWM1State = False;  means PWM1State is a variable, initialized to
0, with 2 states (1 for true, 0 for false.)  Though in C, nonzero
usually is used to mean True.

Int PWM1On = 10;  means Integer variable (could be 8-bit or 16-bit, in
assembler I'd use 8-bit probably) initialized to 10.

While (True) do { } means do the same things repeatedly forever (could
be Label:  [Stuff in { }] followed by Goto Label, in assembler.

PWM1State = (PWM1Counter < PWM1On)  means that if PWM1Counter < PWM1On,
set PWM1State to True, else False (use ClrW then IORLW like Scott
Dattalo did, same thing.)

SetPWMPins (PWM1State, PWM2State, PWM3State, PWM4State) is a function
call - I imply MovWF PWM_Port there.

PWM1Counter++ means increment PWM1Counter.

If (PWM1Counter >= PWM1Cycles) PWM1Counter = 0 is sort of obvious <G>

 Mark

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