Jump to content
Sign in to follow this  
Shree

Confused Between Period And Duty Cycle Of Pwm

Recommended Posts

Hello Wizards,

Sorry for being such a confused soul. But I am going berserk trying to implement a half bridge E-PWM module in order to drive 2 MOSFETS in push pull mode. I wrote the following code:

#include <system.h>
#pragma CLOCK_FREQ 8000000
#pragma DATA _CONFIG, _WDT_OFF & _INTOSCIO & _CP_OFF & _PWRTE_ON & _IESO_OFF & _FCMEN_OFF & _CPD_OFF & _MCLRE_OFF & _BOR_ON

void main()
{
//Setting up internal oscillator of 8MHz
osccon.IRCF2=1;
osccon.IRCF1=1;
osccon.IRCF0=1;
osccon.OSTS=0;
osccon.SCS=0;

trisc=0;
portc=0;
pr2=63; // 32uS=[PR2+1] * 4 * 125nS *1 [PWM Period= ((PR2+1)*4*Tosc*TMR2 Prescaler)]
ccpr1l=128; //16uS=[DCB:DCB0] * 125nS *1 [Pulse Width=(CCPR1L:CCP1CON<5:4>) *Tosc* TMR2 Prescale] 
ccp1con=0x8c; //Half Bridge Mode and PWM mode all pins active high
pwm1con=4; //dead band Delay of 4*Tosc * n: 4*125nS*4= 2uS
t2con=4; //TMR2 On with pre and post scaler 1:1
while(1){;}
}

From the above program I am trying to get two complimentory pulses of 16uS (2uS deadband delay + 14uS ON) and 16uS off on pin P1A and P1B. Both are being used as active high. So total period on each pin is 32uS. My first confusion is if the period is total of ON time and OFF time, then how could the value loaded in PR2 registor is lesser then that in CCPR1L (In my case double as the duty cyle is 50%) and secondly is there something more to be added to the above code to acheive my task? I checked the O/P on the scope, but only P1A is showing some erraneous output. Guys I was never so much confused. Is this so hard to do?

plz help me

Thanks in advance

Shree

Share this post


Link to post
Share on other sites
Hello Wizards,

Sorry for being such a confused soul. But I am going berserk trying to implement a half bridge E-PWM module in order to drive 2 MOSFETS in push pull mode. I wrote the following code:

#include <system.h>
#pragma CLOCK_FREQ 8000000
#pragma DATA _CONFIG, _WDT_OFF & _INTOSCIO & _CP_OFF & _PWRTE_ON & _IESO_OFF & _FCMEN_OFF & _CPD_OFF & _MCLRE_OFF & _BOR_ON

void main()
{
//Setting up internal oscillator of 8MHz
osccon.IRCF2=1;
osccon.IRCF1=1;
osccon.IRCF0=1;
osccon.OSTS=0;
osccon.SCS=0;

trisc=0;
portc=0;
pr2=63; // 32uS=[PR2+1] * 4 * 125nS *1 [PWM Period= ((PR2+1)*4*Tosc*TMR2 Prescaler)]
ccpr1l=128; //16uS=[DCB:DCB0] * 125nS *1 [Pulse Width=(CCPR1L:CCP1CON<5:4>) *Tosc* TMR2 Prescale] 
ccp1con=0x8c; //Half Bridge Mode and PWM mode all pins active high
pwm1con=4; //dead band Delay of 4*Tosc * n: 4*125nS*4= 2uS
t2con=4; //TMR2 On with pre and post scaler 1:1
while(1){;}
}

From the above program I am trying to get two complimentory pulses of 16uS (2uS deadband delay + 14uS ON) and 16uS off on pin P1A and P1B. Both are being used as active high. So total period on each pin is 32uS. My first confusion is if the period is total of ON time and OFF time, then how could the value loaded in PR2 registor is lesser then that in CCPR1L (In my case double as the duty cyle is 50%) and secondly is there something more to be added to the above code to acheive my task? I checked the O/P on the scope, but only P1A is showing some erraneous output. Guys I was never so much confused. Is this so hard to do?

plz help me

Thanks in advance

Shree

 

Hi Shree,

I don't know about your code, but I can tell u how the PWM module works.

First there are three important registers associated with it. they are

1) tmr2 or timer2 register

2) pr2 register also called the period register.

3) ccpr1l & ccpr1h which holds the 10bit duty cycle value.

 

a)PWM generates a square wave form output at the ccp pin.

b)Any square wave form has an ON time & OFF time.

c) The ON time is called the duty or duty cycle.

d) One ON time plus one OFF time is called the period or T. Frequency of the wave form is f = 1 / T .

e) The ON time is decided by the duty cycle value(10bit ccpril & ccp1con<5:4>) register.

f) The Period or frequency is controlled by the pr2 value.

 

How it works?

Two comparators keep comparing the pr2 register value & duty cycle value with timer2(tmr2) value which is free running.

When the tmr2 value equals pr2 value the ccp pin is made high & next when it reaches ccpr1l + ccp1con<5:4> value it makes the pin low.

Also when tmr2 value equals pr2 value a flag is set & the tmr2 is reset to zero. You can enable the interrupt bit TMR2IE. You can try to

change the duty cycle value in the ISR. You can also toggle your i/o pins in the ISR.

Use this sample code on PIC16F72 or similar. Use external RC. R value is 10k & C value is 68pf. You can see the output in ccp pin. Also two out of phase

50hz pulse in RB0 & RB1.

 

#include <system.h>

// Set clock frequency to 1MHz.

#pragma CLOCK_FREQ 1000000

//set configuration fuse.
#pragma DATA _CONFIG, _RC_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF

int duty_cycle;	//global variable

/*Interrupt service routine (ISR).On timer2 interrupt, program 
 will jump to this code location.  */	
void interrupt( void )
{
char pulse;
/*generate two 50hz 180 degree out of phase pulses & externally
AND it with the 100Hz pwm pin to get a modulated 50Hz to drive
mosfets connected to a transformer in a push-pull configuration.
A/D conversion of the the output voltage can act as feed back to
adjust the duty-cycle ( not yet implemented in this code).
*/
pulse = portb;  
pulse.0 = ~ pulse.0;
pulse.1 = ~ pulse.1;  
portb = pulse;

pir1.1=0;  //clear TMR2 to pr2 match interrupt flag
}

void load_duty_cycle(void)   
{	
ccpr1l.7 = duty_cycle.9;  
ccpr1l.6 = duty_cycle.8;		   
ccpr1l.5 = duty_cycle.7;  
ccpr1l.4 = duty_cycle.6;  
ccpr1l.3 = duty_cycle.5; 
ccpr1l.2 = duty_cycle.4;  
ccpr1l.1 = duty_cycle.3;  
ccpr1l.0 = duty_cycle.2;  
ccp1con.5 = duty_cycle.1;  
ccp1con.4 = duty_cycle.0; 
}



// The main code configures the pwm registers
void main()
{
trisa = 255;
  	trisb = 0;		 //configure port B as output
  	trisc = 0;	   // portc as out put
portb = 1;		 //set port B to 1
portc = 0;	   //clear portc



// enable interrupts
intcon.6=1;	 //enable peripheral interrupt	 
intcon.7=1;	 //enable global interrupt

pie1.1=1;	   //tmr2 to pr2 match interrupt

//configure the ccp1con register to enable PWM module.

/*ccpxm3:ccpxm0: mode select bits<3:0>
11xx = for PWM mode.  
*/
ccp1con=0b00001100; //


//PWM period=[(PR2)+1]*4*Tosc*(TMR2 prescaler value)

/*our pmw period is 10ms(100Hz),Tosc is 1/1000,000Hz & prescaler 
is 16.For which PR2+1 works out to 156.25. Lets round it to 156 &
make PR2 to 155. 
*/

//load the period value into pr2 register.
pr2 = 155;


/*timer2 control register
we have selected
bit6-3...(0000) 1:1 for post scaler
bit2.....(1) timer2 on
bit1-0...(11) prescaler is 16
*/

t2con = 0b00000111;  

/*PWM duty cycle = (ccpr1l:ccp1con<5:4>)*Tosc*(TMR2 prescaler value)
Here i have taken 2ms as an example value for duty cycle, Tosc & pre-
scaler are same as above.We will get 10 bit values when we work with
larger duty cycle but for our example we get the value as 125.
*/

//load the duty cycle values 


while( 1 )
{
int b0;
for(b0=1;b0<563;b0++)
{
duty_cycle = b0;
load_duty_cycle();
delay_ms(9);
}

}
}

 

hope this helps

Regards

Raghunathan.P

Share this post


Link to post
Share on other sites

Hello,

Thanks so much for being a help. I think I am getting a bit of it. But I didnt get the concept of the duty cycle and the total period. Considering your example, we have a 10ms period which would load the PR2 register with a value of 155 for 1MHz clock Freq and 1:16 prescaler for TMR2. Now as said by you the ON time of the pulse is determined by 10 bits of CCPR1L and CCP1CON<5:4>. If I consider that the pulse has duty cycle of 50% i.e. it remains ON for 5mS and off for 5mS, the formula stated for getting the values in the above 10bit yeilds a result 0f 312.5 (which is double of the PR2+1 value). I am confused about how can the ON time value be more then the total period value?

Secondly I am trying to use a ECCP in half bridge mode. I wanted to know the exact coding method that is to be followed for implementing the ECCP in halfbridge. Have the interrupts to be used even if I want a fixed frequency (say 50% duty cycle) output on P1A and P1B pins, which would drive a MOSFET drive in Push-pull mode. Further more there is a deadband control register PWM1CON, the value entered in which would create a deadband of that value multiplied by 4Tosc. But nothing is mentioned about the value in CCPR1L register with this deadband. I mean say if I want a deadband of 1mS in 5mS ON time, i.e. the actaul ON time is only 4mS, then what should be the CCPR1L value? Should it be 312(for 5mS) as in above example or should it be calibareted for 4mS?

I hope I am not making a mess and thanks for your efforts to explain the concept in detail. For sure I know much more now then before.

Regards

Shree

Share this post


Link to post
Share on other sites
Hello,

Thanks so much for being a help. I think I am getting a bit of it. But I didnt get the concept of the duty cycle and the total period. Considering your example, we have a 10ms period which would load the PR2 register with a value of 155 for 1MHz clock Freq and 1:16 prescaler for TMR2. Now as said by you the ON time of the pulse is determined by 10 bits of CCPR1L and CCP1CON<5:4>. If I consider that the pulse has duty cycle of 50% i.e. it remains ON for 5mS and off for 5mS, the formula stated for getting the values in the above 10bit yeilds a result 0f 312.5 (which is double of the PR2+1 value). I am confused about how can the ON time value be more then the total period value?

Secondly I am trying to use a ECCP in half bridge mode. I wanted to know the exact coding method that is to be followed for implementing the ECCP in halfbridge. Have the interrupts to be used even if I want a fixed frequency (say 50% duty cycle) output on P1A and P1B pins, which would drive a MOSFET drive in Push-pull mode. Further more there is a deadband control register PWM1CON, the value entered in which would create a deadband of that value multiplied by 4Tosc. But nothing is mentioned about the value in CCPR1L register with this deadband. I mean say if I want a deadband of 1mS in 5mS ON time, i.e. the actaul ON time is only 4mS, then what should be the CCPR1L value? Should it be 312(for 5mS) as in above example or should it be calibareted for 4mS?

I hope I am not making a mess and thanks for your efforts to explain the concept in detail. For sure I know much more now then before.

Regards

Shree

 

Shree,

The PWM output at the ccp pin is designed for 100hz and the two out of phase pulse generated in the ISR will have half the freq of the ccp pin ie.50hz.

Now the pulse out at the ccp pin can have 0 to 100 % ON time by loading the ccpr1l & ccpr1h. This ccp pin pulse has to be ANDed with the 50hz pulse

generated in the ISR. Then As the duty cycle changes from 0 to 100% in the ccp pin the 50hz pulse in ISR(RB0 & RB1) will vary from 0 to 50%.

A graphical representation will make things better to understand. Try if u can figure out from the above information.

 

Regards

Raghunathan.P

Edited by ra68gi

Share this post


Link to post
Share on other sites
Shree,

The PWM output at the ccp pin is designed for 100hz and the two out of phase pulse generated in the ISR will have half the freq of the ccp pin ie.50hz.

Dear sir, Please allow me to differ with you here. I think its the time which becomes half of the total ccp. So the freq would be double. Please correct me if I am wrong as I am a novoice.

 

I still think that the CCPR1L's value must be half of the value of period register value in order to get a 50% duty cycle. Am I wrong? Further more I was just wondering whether the ECCP o/p keeps on running in background, allowing me to do any other jobs with my pic (like continously monitering the adc channel, making some ports high or low etc?)

Thanks for your efforts and support

Regards

Shree

Share this post


Link to post
Share on other sites
Shree,

The PWM output at the ccp pin is designed for 100hz and the two out of phase pulse generated in the ISR will have half the freq of the ccp pin ie.50hz.

Dear sir, Please allow me to differ with you here. I think its the time which becomes half of the total ccp. So the freq would be double. Please correct me if I am wrong as I am a novoice.

 

I still think that the CCPR1L's value must be half of the value of period register value in order to get a 50% duty cycle. Am I wrong? Further more I was just wondering whether the ECCP o/p keeps on running in background, allowing me to do any other jobs with my pic (like continously monitering the adc channel, making some ports high or low etc?)

Thanks for your efforts and support

Regards

Shree

Some times things defy our reasoning so I suggest u program a device & see the wave forms on an oscilloscope.

Regards

Raghunathan.P

Share this post


Link to post
Share on other sites
Some times things defy our reasoning so I suggest u program a device & see the wave forms on an oscilloscope.

Regards

Raghunathan.P

Hello,

I think I figured it out! Actually the value of CCPR1L is only 8 MSBs of the 10Bit register of the period hence whatever might be the total value would be shifted right 2 places, which makes it value divide by 4. So if we have PR2+1 is 64 the CCPR1L value would indeed be 32 and thats what I was reasoning! By the way its working now! Thanks a million for being for me all the time and trying to figure it out for me.

 

Regards

Shree

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×