Searching \ for '3 PWMs' 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: '3 PWMs'.

Truncated match.
PICList Thread
'3 PWMs'
1998\05\19@123942 by Justin Lipton

flavicon
face
Hi,

I am new to the PIC device family and am looking to program a PIC16C74.

My application requires 3 PWM outputs (all with adjustable duty cycles).
Obviously I will use CCP1 for one PWM output leaving me bothered about
the remaining two.

The other two outputs have frequencies of 30Hz and 70Hz respectively and
need duty cycles (which will not change very often) of 50% or 10%.

Can anyone suggest a neat method for implementing these outputs?

Note that the processor is also required to be an I2C bus master (I found
these routines) and other than monitoring the bus has very little else to
do.

Thanks in advance,

Justin.

~^~^~^~^~^~^~^~^~^~^~^~^~^~
Justin Lipton
Oridion Medical Ltd.
P.O. Box 45025
91450 Jerusalem ISRAEL
Phone 972 2 589 9124
Fax 972 2 582 8868
spam_OUTjustin.liptonTakeThisOuTspamoridion.com
~^~^~^~^~^~^~^~^~^~^~^~^~^~

1998\05\19@151030 by Andrew Warren

face
flavicon
face
Justin Lipton <.....PICLISTKILLspamspam@spam@MITVMA.MIT.EDU> wrote:

> I am new to the PIC device family and am looking to program a
> PIC16C74.
>
> My application requires 3 PWM outputs (all with adjustable duty
> cycles). Obviously I will use CCP1 for one PWM output leaving me
> bothered about the remaining two.
>
> The other two outputs have frequencies of 30Hz and 70Hz respectively
> and need duty cycles (which will not change very often) of 50% or
> 10%.
>
> Can anyone suggest a neat method for implementing these outputs?
>
> Note that the processor is also required to be an I2C bus master (I
> found these routines) and other than monitoring the bus has very
> little else to do.

Justin:

How precise do those two frequencies have to be?  If a 1% error is
ok, you could do something like this:

   Setup TMR0 to generate an overflow interrupt in 90 microseconds.

   Initialize a register called TIME30 to 37; 37 is the number of
   90-microsecond periods in 3330 microseconds (approximately
   one-tenth of a 30Hz signal's period).

   Initialize a register called TIME70 to 16; 16 is the number of
   90-microsecond periods in 1440 microseconds (approximately
   one-tenth of a 70Hz signal's period).

   Two other registers, called DUTY30 and DUTY70, set the duty
   cycle of each waveform.  Set them to 1 for a 10% duty cycle, or
   to 5 for a 50% duty cycle... Your main program can modify them
   as needed during its execution.

   Initialize two more registers, called COUNT30 and COUNT70, to 10.

   When the TMR0-overflow interrupt occurs:

       Reset the TMR0 register to generate another interrupt in 90
       microseconds.

       Decrement TIME30.  If it's at 0, reset it to 37 and:

           Decrement COUNT30.  If it's less than DUTY30, pull the
           30Hz output pin high; otherwise, pull that pin low.

           If COUNT30 is at 0, reset it to 10.

       Decrement TIME70.  If it's at 0, reset it to 16 and:

            Decrement COUNT70.  If it's less than DUTY70, pull the
            70Hz output pin high; otherwise, pull that pin low.

            If COUNT30 is at 0, reset it to 10.

This'll produce a 30.03Hz signal on one pin and a 69.44Hz signal on
the other, with the duty cycle of each signal independently
adjustable in 10% steps from 0 to 100%.

A couple of notes:

   1.  When your main program changes DUTY30 or DUTY70, there may
       be a brief glitch on the corresponding output pin.

   2.  All the numbers above are in decimal.

   3.  All of this is just off the top of my head, so no
       guarantees... But it's pretty simple; I'm confident that
       it'll work just fine.

-Andy

=== Andrew Warren - fastfwdspamKILLspamix.netcom.com
=== Fast Forward Engineering - Vista, California
=== http://www.geocities.com/SiliconValley/2499 (personal)
=== http://www.netcom.com/~fastfwd (business)

1998\05\19@170801 by Harold Hallikainen

picon face
On Tue, 19 May 1998 18:27:00 +0200 Justin Lipton
<.....Justin.liptonKILLspamspam.....ORIDION.COM> writes:
>Hi,
>
>I am new to the PIC device family and am looking to program a
>PIC16C74.
>
>My application requires 3 PWM outputs (all with adjustable duty
>cycles).
>Obviously I will use CCP1 for one PWM output leaving me bothered about
>the remaining two.
>
>The other two outputs have frequencies of 30Hz and 70Hz respectively
>and
>need duty cycles (which will not change very often) of 50% or 10%.
>
>Can anyone suggest a neat method for implementing these outputs?
>


       I've gotten four 50/60 Hz PWM outputs by letting a timer run and
generating an interrupt on a CCP compare match.  The interrupt set (or
clears) the appropriate output bit, then checks to see which channel is
supposed to go on next, loads the CCP with the new value, and returns.
On a timer roll-over, all outputs (other than the 100% duty cycle) are
turned off.  You may have to switch on/off to get the duty cycle going
the way you want, but that should give a start...
       This is used for light dimming phase control in the Shoebox
dimmer at http://www.dovesystems.com (sorry, no code or schematics posted
there..., just product info).


Harold


_____________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com
Or call Juno at (800) 654-JUNO [654-5866]

1998\05\19@170812 by Scott Newell

flavicon
face
>My application requires 3 PWM outputs (all with adjustable duty cycles).
>Obviously I will use CCP1 for one PWM output leaving me bothered about
>the remaining two.

The 74 has two hardware PWM outputs, right?


>The other two outputs have frequencies of 30Hz and 70Hz respectively and
>need duty cycles (which will not change very often) of 50% or 10%.
>
>Can anyone suggest a neat method for implementing these outputs?

USART?  (Send the same character continuously.  You may want to use the 9
bit mode, and don't forget about the start bit!)


newell

1998\05\19@211830 by Scott Dattalo

face
flavicon
face
Justin Lipton wrote:
>
> Hi,
>
> I am new to the PIC device family and am looking to program a PIC16C74.
>
> My application requires 3 PWM outputs (all with adjustable duty cycles).
> Obviously I will use CCP1 for one PWM output leaving me bothered about
> the remaining two.
>
> The other two outputs have frequencies of 30Hz and 70Hz respectively and
> need duty cycles (which will not change very often) of 50% or 10%.
>
> Can anyone suggest a neat method for implementing these outputs?

Neat? That's too subjective. But here are a couple of Cool ways of
generating multiple PWM outputs. First, last week when we were talking
about PWM's I alluded to a vertical counter version. Here it is:

;------------------------------------------------------------
;vert_pwm
;
;  The purpose of this routine is to generate 4 pulse width
;modulated waveforms using vertical counters. This version
;implements 5-bit counters, but other sized counters can
;easily be created.
;  The algorithm consists of 8 vertical roll over counters:
;4 for the rising edge and 4 for the falling edge. Whenever
;a rising edge counter rolls over the corresponding PWM bit
;is driven high and when a falling edge counter rolls over it's
;driven low.
;  The four rising edge counters are grouped together in the
;lower nibble while the falling edge counters are in the upper.
;
;  The counters work on this little trick (complements to
;John Payson):
;  the following two instructions propogate the carry bit in
;the W register to the next counter bit and if there is an
;underflow (the counters are down counters), generates a carry
;out.
;
;       XORWF   bn,F    ;toggle next bit if there's a carry in
;       ANDWF   bn,W    ;Set carry if bit went from 0 to 1
;
;RAM
;  b0-b4 counters
;  pwm_state - current state of the pwm outputs
;  temp - temporary register.
;ROM
;  17 instructions
;
vert_pwm:
       COMF    b0,W            ;unconditionally toggle and get the
       MOVWF   b0              ;'carry out' if going from 0 -> 1
                               ;
       XORWF   b1,F            ;
       ANDWF   b1,W            ;
                               ;
       XORWF   b2,F            ;
       ANDWF   b2,W            ;
                               ;
       XORWF   b3,F            ;
       ANDWF   b3,W            ;
                               ;
       XORWF   b4,F            ;
       ANDWF   b4,W            ;
                               ;
       MOVWF   temp            ;save the carry out results (only
                               ;those counters that rolled over
                               ;will generate a carry out).
                               ;
       ANDLW   00001111b       ;get the rising edge counters.
                               ;
       IORWF   pwm_state,F     ;If a rising edge counter rolled over
                               ;then turn that output on.
                               ;
       SWAPF   temp,W          ;Get the falling edge counters
       XORLW   0x0f            ;and toggle them. A roll over is now
                               ;a 'zero'
                               ;
       ANDWF   pwm_state,F     ;If a falling edge counter rolled
                               ;then turn that output off
       MOVWF   PWM_PORT


The down side with the vertical counter pwm is its initialization. Try
it.

Here's another method for 8 8-bit pwms (but uses old-fashioned
horizontal counters)


;------------------------------------------------------------
;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


There's also a "Scenix virtual peripheral" similar to this bit-banging
code. However, the pwm frequencies are not constant (which in most cases
is not a big deal) and the code is slower (which in many cases is).

Now I realize that neither of these directly satisfy your 30Hz and 70Hz
frequency requirements (why do you need those frequencies anyways?).
However, you could set up a timer interrupt routine that interrupts at
210 Hz (or 420, 630, 210*n Hz) and every third time through run the 70Hz
PWM code and every 7th time through run the 30hz code. There was a
single pwm output version of code posted last week.


Scott

1998\05\20@125904 by Alvaro Deibe Diaz

flavicon
face
Puede que lo que te envio no te resulte interesante inmediatamente. Pero de
todas formas puede resultarte entretenido, te lo aseguro. Se trata de otra
aplicacion mas de los llamados "contadores verticales". Te aseguro que es
extremadamente inteligente, y tiene muchas ventajas (no he pensado en los
inconvenientes, pero estoy seguro que tambien tendra). Es como lo de los
algoritmos de ordenamiento, son curiosidades interesantes.

Es un poco dificil de seguir, asi que si necesitas que te ponga en
antecedentes, dimelo; (no es que me considere mas listo que tu, sino que ya
he visto otras veces el tema de los contadores verticales).

Chao.

-----Mensaje original-----
De:     Scott Dattalo [SMTP:EraseMEsdattalospam_OUTspamTakeThisOuTUNIX.SRI.COM]
Enviado el:     miercoles 20 de mayo de 1998 3:17
Para:   PICLISTspamspam_OUTMITVMA.MIT.EDU
Asunto: Re: 3 PWMs

Justin Lipton wrote:
{Quote hidden}

Neat? That's too subjective. But here are a couple of Cool ways of
generating multiple PWM outputs. First, last week when we were talking
about PWM's I alluded to a vertical counter version. Here it is:

;------------------------------------------------------------
;vert_pwm
;
;  The purpose of this routine is to generate 4 pulse width
;modulated waveforms using vertical counters. This version
;implements 5-bit counters, but other sized counters can
;easily be created.
;  The algorithm consists of 8 vertical roll over counters:
;4 for the rising edge and 4 for the falling edge. Whenever
;a rising edge counter rolls over the corresponding PWM bit
;is driven high and when a falling edge counter rolls over it's
;driven low.
;  The four rising edge counters are grouped together in the
;lower nibble while the falling edge counters are in the upper.
;
;  The counters work on this little trick (complements to
;John Payson):
;  the following two instructions propogate the carry bit in
;the W register to the next counter bit and if there is an
;underflow (the counters are down counters), generates a carry
;out.
;
;       XORWF   bn,F    ;toggle next bit if there's a carry in
;       ANDWF   bn,W    ;Set carry if bit went from 0 to 1
;
;RAM
;  b0-b4 counters
;  pwm_state - current state of the pwm outputs
;  temp - temporary register.
;ROM
;  17 instructions
;
vert_pwm:
       COMF    b0,W            ;unconditionally toggle and get the
       MOVWF   b0              ;'carry out' if going from 0 -> 1
                               ;
       XORWF   b1,F            ;
       ANDWF   b1,W            ;
                               ;
       XORWF   b2,F            ;
       ANDWF   b2,W            ;
                               ;
       XORWF   b3,F            ;
       ANDWF   b3,W            ;
                               ;
       XORWF   b4,F            ;
       ANDWF   b4,W            ;
                               ;
       MOVWF   temp            ;save the carry out results (only
                               ;those counters that rolled over
                               ;will generate a carry out).
                               ;
       ANDLW   00001111b       ;get the rising edge counters.
                               ;
       IORWF   pwm_state,F     ;If a rising edge counter rolled over
                               ;then turn that output on.
                               ;
       SWAPF   temp,W          ;Get the falling edge counters
       XORLW   0x0f            ;and toggle them. A roll over is now
                               ;a 'zero'
                               ;
       ANDWF   pwm_state,F     ;If a falling edge counter rolled
                               ;then turn that output off
       MOVWF   PWM_PORT


The down side with the vertical counter pwm is its initialization. Try
it.

Here's another method for 8 8-bit pwms (but uses old-fashioned
horizontal counters)


;------------------------------------------------------------
;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


There's also a "Scenix virtual peripheral" similar to this bit-banging
code. However, the pwm frequencies are not constant (which in most cases
is not a big deal) and the code is slower (which in many cases is).

Now I realize that neither of these directly satisfy your 30Hz and 70Hz
frequency requirements (why do you need those frequencies anyways?).
However, you could set up a timer interrupt routine that interrupts at
210 Hz (or 420, 630, 210*n Hz) and every third time through run the 70Hz
PWM code and every 7th time through run the 30hz code. There was a
single pwm output version of code posted last week.


Scott

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