Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

strategy to vary the duty cyle of PWM

Status
Not open for further replies.

Rooney_04

New Member
hi.

i m currently working on RC-helicopter motor controller. So basically using PIC 16f887A to generate the PWM. At first i m using ADC or PCM transmitter to convert the data to digital n transmit it to the PIC.

the problem is i need strategies or ideas or suggestions how to vary the duty cycle. i would the program to be like for example the ADC or PCM transmitter transmit digital data 1001 and pic will received it. Then PIC will be executes of 50% duty cycle. If the data transmit 1010, PIC will executes 80% duty cycle. it sort like PIC is predetermined as code received. As we know varying the duty cycle will vary the speed of the motor in RC helicopter.

thank you and really appreciate if anyone can help me...
 
This is simple if you understand what duty cycle and PWM is. Consider the following equations:

[LATEX]D = \frac{t}{T}[/LATEX]

Where:

[LATEX]t = On Duration[/LATEX]

[LATEX]T = Period of Frequency[/LATEX]

It's important to know what frequency you'll be driving your hardware at, otherwise these equations don't work.

Let's say you want to drive a motor at 50Hz, with a 50% duty cycle. Thus:

[LATEX]0.5 = \frac{t}{0.02} \rightarrow D = 10mS[/LATEX]

[LATEX]V_{O} = D * V_{IN}[/LATEX]

If you have a duty cycle of 50%, with an input voltage of 1V, then obviously your output voltage will be 0.5V.

Now it's just a matter of coding it correctly, what compiler are you using and in what language? I've done this in C18, so if you need help let me know.
 
Last edited:
The first step involves creating a PWM function. You will include the following parameters in your function:

  1. I/O Pin
  2. Duty Cycle
  3. Frequency

Can you go from there? I'm not going to give you all the answers, you will have to provide the effort.
 
Last edited:
The first step involves creating a PWM function. You will include the following parameters in your function:

  1. I/O Pin
  2. Duty Cycle
  3. Frequency

Can you go from there? I'm not going to give you all the answers, you will have to provide the effort.

Can you give me more hint because i m new to PIC programiing
 
I dont think so. I need the strategy to vary the duty cycle. I need to know the PIC programming

QUOTE=Pommie;917916]Did that thread not help? If not, what more do you want?

Mike.[/QUOTE]
 
ISR soft PWM

Hi:
I did some software PWM driven by a 1ms ISR as my PWM frequncy ranges from abt 20Hz thru 50Hz and I had already used the ECCP module to provide a precise 10ms Timer1 interrupt so the PWM hardware module was not available.

Here it is in asm, to help u understand the variables used are:

a flag bit PWMflag,0 , bit 0 here sets or stops the PWM.
I used PORTB,2 as the driver pin, but u can use any u like which is an advantage over the hardware PWM.
The PWMwidth decides the duty cycle, it must be 0>PWMwidth<PWMperiod
PWMperiod is the period (in millisec) so 1/PWMperiod is the frequency.

So by varying the PWMwidth variable in your code u can vary the pulsewidth from PortB,2 over the PWMperiod timebase and achieve PWM control.


Code:
btfsc PWMflag,0; skip if clr, else. This flag enables PWM when set (1).
	goto DoPWM
	bcf PORTB,2 ; clear the pwm portb2. DIRECT DRIVEN BY ISR for time critical accuracy.
	clrf PWMcount ; reinit this.
	goto Finish; done
DoPWM	incf PWMcount,f
	movf PWMcount,w
	subwf PWMperiod,w ;test count vs pwmperiod
	btfss STATUS,Z; skip if =,else
	goto Pulsewidth

	clrf PWMcount ; reset the counter.
	bsf PORTB,2 ; set the output pulse high at start of cycle!
	goto Finish; done
Pulsewidth ; manage duty cycle here
	Movf PWMwidth,w; get width of On cycle duty in ms
	subwf PWMcount,w ; test to see if on cycle finished.
	btfss STATUS,C; skip if PWMcount>= PWMwidth, else
        goto Pulsehigh
	bcf PORTB,2; set pulse low as ON cycle finished.
	goto Finish; done
Pulsehigh
	bsf PORTB,2 ; set pulse high

Finish ; rest of ISR code.
 
Last edited:
Doesn't help. I don't really follow what you're working on.

Just wondering what 20 to 50 duty cycle steps would be useful for...
 
Last edited:
Rooney,

You need to create a function for frequency first, here's my approach in C18 using the PIC18F1320. You can change it for your PIC.

Code:
    void freq(char pins, unsigned int frqcy, unsigned int timer) // Frequency Function 16-bits
    {    
            unsigned int times;
            TRISA = ~(pins & 0xFF);

            INTCONbits.TMR0IF = 0;   // Clear OVF Flag
            LATA = pins;   // Initialize LATA 
            TMR0L = frqcy & 0xFF;                    
            TMR0H = (frqcy >> 8) & 0xFF;                  
            T0CON|=0x80;
        
            for(times=timer;times>0;times--)   // Duration
            {
                 TMR0H = (frqcy >> 8) & 0xFF;   //Load TMR0H byte first
                TMR0L = frqcy & 0xFF;   // Load TMR0L byte next
                while(!INTCONbits.TMR0IF);   // Wait for timer
`                INTCONbits.TMR0IF = 0;   // Clear OVF Flag
                LATA = ~LATA;   // Invert output   
            }
    }

Next you need to work on your PWM function using the frequency function.
 
Last edited:
Hi, Rooney

Looks you didn't SEARCH very far ...

Found in YOUR PicC EXAMPLES FOLDER :

Code:
/////////////////////////////////////////////////////////////////////////
////                           EX_PWM.C                              ////
////                                                                 ////
////  This program will show how to use the built in PIC PWM.        ////
////  The program takes an analog input and uses the digital         ////
////  value to set the duty cycle.  The frequency is set by          ////
////  the user over the RS-232.                                      ////
////                                                                 ////
////  Configure the CCS prototype card as follows:                   ////
////      Connect a scope to pin C2                                  ////
////      Connect pin A0 to output of the POT                        ////
////                                                                 ////
...

#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)

Alain
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top