CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

understanding PWM 18F2520

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kashif12



Joined: 24 Feb 2011
Posts: 8

View user's profile Send private message

understanding PWM 18F2520
PostPosted: Sun Feb 27, 2011 5:49 am     Reply with quote

Greetings world,
I need help to understand PWM generator in 18F2520.
Sorry if my questions are very basic.
I want to generate PWM signal on ccp1 (duty cycle 52.12 to 59.98) at 300khz depending on the input voltage (0-5V) converted by ADC in range (0-1023).
Now as I am using internal oscillator which can have max clock=8MHz right?

I am using following code:
Compiler V.4
Code:

#include <18F2520.h>
#device adc=10
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000)
//what will be the effect of clock on ADC and PWM?

//================================
void main()
{
int8 value;

setup_ccp1(CCP_PWM);

setup_timer_2(T2_DIV_BY_1, 255, 1); 
/*
>>mode?: i dont understand what is T2_DIV_BY_1
>> period?: will ensure duty cycle can vary from 0-1023 i.e. (0 percent to 100 percent) right?
how can i restrict it to 50.22 to 59.98?
 
postscale?: is a number 1-16 that determines how many timer overflows before an interrupt: (1 means once, 2 means twice, and so on).
what is this overflow?

*/

setup_port_a(AN0);
setup_adc(ADC_CLOCK_DIV_1);
//does mode value means here convert faster if div_1,slower if div_4 even slower if div_16?
///i mean is it increasing sensitivity?
set_adc_channel(0);
delay_us(20);

while(1)
  {
   value = read_adc();

   set_pwm1_duty(value);
//if value is 512 or 1023 does this mean duty cycle will be 50% or 100%?
//how can i make duty cycle in 50.29?
//
  }

}

_________________
Mr Operating Systems
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 9:45 am     Reply with quote

First, what you post, is not using the internal oscillator. XT, is the external crystal oscillator.

Second. No, you are not limited to 8MHz, with the internal oscillator. Look at section 2.6.4 of the data sheet. You can go up to 32MHz with the PLL.

Now, you cannot 'restrict the range to 50.22 to 59.98. This is down to _you_ You will need to write your code, to restrict the range of values it feeds into the PWM setting.

However, you also have a potential problem about speeds. You want a 300Khz output frequency. This is just 106 cycles of the master clock (assuming you are running at 32Mhz). The PWM, _counts_ in master processor clock pulses, or a subdivided version of these (This is the T2_DIV_BY_1 - you can have the master clock, or the clock/4, or the clock/16). To get close to 300KHz, from a 32MHz master clock, needs:

setup_timer_2(T2_DIV_BY_1, 26, 1);

and allowable values for the width, will be just 0 to 107.

Now, another problem. You have 'value' selected as an int8, but are using it to hold a 10bit value from the ADC....

Then the ADC clock. Read the data sheet. There is a _minimum_ clock time that must be met for the ADC to work. Table 19-1, gives the allowable selections. For a 32Mhz master clock, you need clock/32.

With the '26' selected above, the output frequency will be:

32000000 / (4*27) = 296296Hz.

The pulse width counts in single cycles of the incoming clock (as opposed to the processor cycles - /4 for the main timing). So you want an on time of 1.674uSec to 1.999uSec. So, 53.5 to 64 cycles of the clock for the 'on time' Since you can't do half cycles, you will have to choose between 53 to 64, or 54 to 64 cycles. These are the counts that will need to be fed into the pwm_duty function. Just ten ot eleven possible values.....

The postscale overflow, does nothing, unless you are using the timer interrupt for something. At the speed you want to run, there is not time for this anyway.....

So you would have to take the value from the adc _in an int16_ divide it by say 93, and add 53, to give the nearest 'miss' to the required range. Resolution will be poor though.

Best Wishes
kashif12



Joined: 24 Feb 2011
Posts: 8

View user's profile Send private message

thanks
PostPosted: Mon Feb 28, 2011 10:23 am     Reply with quote

Bundle of thanks Ttelmah.
I will go through data sheet and modify my code.
_________________
Mr Operating Systems
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group