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 support@ccsinfo.com

PWM_help please

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



Joined: 07 Mar 2009
Posts: 14

View user's profile Send private message

PWM_help please
PostPosted: Wed Mar 18, 2009 8:18 pm     Reply with quote

hi all,

I try to generate pwm to pulse my led, but my the pwm does not work as I want. Please help me... I have simulate it in proteus but the duty only 100us not 200us as needed.

pwm period = 1250Hz = 800us
desired duty cyles 25% = 200us
PIC16F877A, XTAL=20Mhz
Code:

void main()
{
   float duty;
   long value_adc;
   int adc_lsb, adc_msb;
   unsigned long i;
   
   //initialize
   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_DIV_32);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   setup_ccp1(CCP_PWM);
   
   setup_timer_2(T2_DIV_BY_16, 249,1);
  duty = 62;
  set_pwm1_duty(duty);
 
   
 do{
     
      set_adc_channel(0); 
       
      for(i=0;i<10000;i++){
     
      value_adc = read_adc();
   
      adc_lsb = value_adc;
      adc_msb = (value_adc<<6)>>14;
   
      printf("%Lu,%2X%2X \r\n",i,adc_msb,adc_lsb);

  //  delay_ms(20);
      }
   }while(1);
}

btw do I need delay after adc? and will delay disturb my PWM duty?

please help
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 18, 2009 9:24 pm     Reply with quote

Quote:
float duty;
duty = 62;
set_pwm1_duty(duty);

You have declared the duty cycle as a 'float'.

The CCS manual says this:
Quote:
Syntax: set_pwm1_duty (value)

Parameters: value may be an 8 or 16 bit constant or variable.
takumi



Joined: 07 Mar 2009
Posts: 14

View user's profile Send private message

PostPosted: Wed Mar 18, 2009 10:10 pm     Reply with quote

PCM programmer wrote:
Quote:
float duty;
duty = 62;
set_pwm1_duty(duty);

You have declared the duty cycle as a 'float'.

The CCS manual says this:
Quote:
Syntax: set_pwm1_duty (value)

Parameters: value may be an 8 or 16 bit constant or variable.


thanks I have change it and it works :) ...

btw how about the delay after send adc? will it effect my pwm?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 18, 2009 10:18 pm     Reply with quote

The pwm hardware module runs independently of any delays in your code. It's not affected.
takumi



Joined: 07 Mar 2009
Posts: 14

View user's profile Send private message

PostPosted: Thu Mar 19, 2009 6:09 am     Reply with quote

how about this

pwm1 i already create the pwm 200us(on)600us(off)

is it posible to create pwm2 that 400us(off)200us(on)200us(off)?

setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);

setup_timer_2(T2_DIV_BY_16, 249,1);
set_pwm1_duty(64);

delay_us(400); <will this delay effect my a2d?

set_pwm2_duty(64);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 19, 2009 11:07 am     Reply with quote

Quote:
pwm1 i already create the pwm 200us(on)600us(off)
is it posible to create pwm2 that 400us(off)200us(on)200us(off)?

There is no phase shift ability between PWM channels 1 and 2.

Quote:
delay_us(400); <will this delay effect my a2d?

The A/D is a separate hardware module. It can acquire and capture
the A/D signal in a few microseconds. A delay_us(400) statement farther
along in your program after the read_adc() statement does not affect
the A/D.
takumi



Joined: 07 Mar 2009
Posts: 14

View user's profile Send private message

PostPosted: Fri Mar 20, 2009 12:54 pm     Reply with quote

I have created a pwm as below:
Code:
void pwm(){
   output_high(pin_d2);
   output_low(pin_b4);
      delay_us(70);         
     
   output_low(pin_d2);
   output_low(pin_b4);
   delay_us(430);             
   
   output_low(pin_d2);
   output_high(pin_b4);
   delay_us(70);               
   
   output_low(pin_d2);
   output_low(pin_b4);
   delay_us(430); 
}

and then run it along with my adc_read();
Code:

void main(){

set_adc_channel(0);
delay_us(20);

while(1){
    for(i=0;i<1000;i++){
        pwm();
   
        value_adc = read_adc();
   
        adc_lsb = value_adc;
        adc_msb = (value_adc<<6)>>14;
   
         printf("%Lu,%2X%2X \r\n",i,adc_msb,adc_lsb);
        delay_us(200);
       }
   }

I found that the delay_us(200) < affect my pwm. Is there any possible way to create a difference phase of pwm that will on while mcu on as CCP1?

Btw since I used 20MHz clock and my adc tdiv = 32,
how would be my best delay between reading the adc.

I have read from the PIC16f877A datasheet that TAD = (1/Clock)*32=1.6us

and for 10bit req 12TAD = 1.6ux12 = 19.2us
and there is TACQ = 19.72us

Would it be 12TAD + TACQ = 38.92us ~~ 40us is the best delay between my reading?

how about the the buffer of tx/rx to when i printf to it....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 20, 2009 1:16 pm     Reply with quote

Of course it affects your pwm. In your original question, you were
using the hardware PWM module. Now in your latest code you are
using software PWM done by delay statements. Any delays
in your main loop will add to the delays in your software PWM.
takumi



Joined: 07 Mar 2009
Posts: 14

View user's profile Send private message

PostPosted: Sun Mar 22, 2009 11:18 pm     Reply with quote

hi all,

PIC16f877A, 20MHz
Need help "please" since hardware pwm cannot be use in my application.

I used software pwm but not get the result as I want.
I want to have a pwm dual pulse at freq=40KHz and duty cycle 50%
that mean 12.5us on and 12.5us off 12.5us on and 12.5us off and then
delay 10ms before it start pulse again.
Code:

for(;;){
//first period
output_high(pin_b1);
delay_us(12.5);
output_low(pin_b1);
delay_us(12.5);

//second period
output_high(pin_b1);
delay_us(12.5);
output_low(pin_b1);
delay_us(12.5);

delay_ms(10);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 22, 2009 11:49 pm     Reply with quote

Quote:
PIC16f877A, 20MHz

output_high(pin_b1);
delay_us(12.5);
output_low(pin_b1);
delay_us(12.5);

Download the CCS manual.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look in the section on delay_us():
Quote:
delay_us( )
Syntax: delay_us (time)
Parameters: time - a variable 0-65535(int16) or a constant 0-65535

You can't use "12.5" for the delay time. It can be 11, 12 or 13. If you
want to use smaller time periods (less than 1 us), then add a line for
delay_cycles(). Also, the output_low() statement will take 4 cycles (if
you are using standard i/o mode). At 20 MHz, there are 5 cycles in 1 us.
Use this information to calculate the correct delay times.
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