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

pwm on 16F877A, how to change the duty cycle

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



Joined: 09 Mar 2006
Posts: 4
Location: Shanghai China

View user's profile Send private message Send e-mail

pwm on 16F877A, how to change the duty cycle
PostPosted: Sat Mar 11, 2006 8:59 pm     Reply with quote

HI
I am trying to use the PWMs to run 2 separate motors. I am using CCP1 and CCP2.I find many posts about pwm,I know how to generate Pwm,but I don't know how to change the the duty cycle automatically,when the voltage of PIN_C(PIN_C4,PIN_C5....) become high, decrease the duty cycle,when voltage become low the duty cycle become normal again.In a word,I want to know how to control duty cycle(speed of motors).

I am doing my graduation project, waiting for your reply in Shanghai.

Thank you !!
Quote:


#include <16F877A.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)

main()
{
int16 duty_cycle1=100;
int16 duty_cycle2=200;

output_low(PIN_C1); // Set CCP2 output low
output_low(PIN_C2); // Set CCP1 output low

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_ccp2(CCP_PWM); // Configure CCP2 as a PWM

setup_timer_2(T2_DIV_BY_16, 255, 1);
set_pwm1_duty(duty_cycle1);
set_pwm2_duty(duty_cycle2);
while(1);
}



How to change duty_cycle1 and duty_cycle2?


Last edited by hongtao on Sat Mar 11, 2006 9:53 pm; edited 2 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Mar 11, 2006 9:21 pm     Reply with quote

Quote:
The code come from
http://www.ccsinfo.com/forum/viewtopic.php?t=17729&highlight=pwm

That thread contains newbie code which has some problems, but it
also contains "pro" code which doesn't have those problems.
You should not use newbie code as your example. You should use
the other code.
hongtao



Joined: 09 Mar 2006
Posts: 4
Location: Shanghai China

View user's profile Send private message Send e-mail

PostPosted: Sat Mar 11, 2006 9:33 pm     Reply with quote

Thank you, PCM programmer. I correct it. Can you give some suggestion?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Mar 11, 2006 11:01 pm     Reply with quote

Quote:

I don't know how to change the the duty cycle automatically,when the
voltage of PIN_C(PIN_C4,PIN_C5....) become high, decrease the duty
cycle,when voltage become low the duty cycle become normal again.
In a word,I want to know how to control duty cycle(speed of motors).


CCS has an example file called EX_PWM.C. In that file, they
show to use the A/D converter with a trimpot to change the PWM
duty cycle. As you turn the trimpot knob in one direction, the duty
cycle is increased, and as you turn it in the other direction it decreases.
The EX_PWM.C file is in this folder: c:\Program Files\Picc\Examples

In your question, you imply that you want to check several i/o pins
to determine the motor speed (because you have "...."). Is this really
what you want to do, or is the EX_PWM.C example a better way for you ?
hongtao



Joined: 09 Mar 2006
Posts: 4
Location: Shanghai China

View user's profile Send private message Send e-mail

PostPosted: Sun Mar 12, 2006 12:47 am     Reply with quote

Thanks for your detailed reply. Smile the EX_PWM.C example is a better way for me,that is what I want.Before I logging in the forum,I tried to understand the EX_PWM.c,but I failed,so I want to find simple example to control it.Can you explain it? can you write a simple version?Question
Quote:

#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)

#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)
#endif


void main() {
char selection;
byte value;


printf("\r\nFrequency:\r\n");
printf(" 1) 19.5 khz\r\n");
printf(" 2) 4.9 khz\r\n");
printf(" 3) 1.2 khz\r\n");

do {
selection=getc();
} while((selection<'1')||(selection>'3'));


setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM

// The cycle time will be (1/clock)*4*t2div*(period+1)
// In this program clock=10000000 and period=127 (below)
// For the three possible selections the cycle time is:
// (1/10000000)*4*1*128 = 51.2 us or 19.5 khz
// (1/10000000)*4*4*128 = 204.8 us or 4.9 khz
// (1/10000000)*4*16*128= 819.2 us or 1.2 khz

switch(selection) {
case '1' : setup_timer_2(T2_DIV_BY_1, 127, 1);
break;
case '2' : setup_timer_2(T2_DIV_BY_4, 127, 1);
break;
case '3' : setup_timer_2(T2_DIV_BY_16, 127, 1);
break;
}



setup_port_a(ALL_ANALOG);
setup_adc(adc_clock_internal);
set_adc_channel( 0 );
printf("%c\r\n",selection);

while( TRUE ) {
value=read_adc();

printf("%2X\r",value);

set_pwm1_duty(value); // This sets the time the pulse is
// high each cycle. We use the A/D
// input to make a easy demo.
// the high time will be:
// if value is LONG INT:
// value*(1/clock)*t2div
// if value is INT:
// value*4*(1/clock)*t2div
// for example a value of 30 and t2div
// of 1 the high time is 12us
// WARNING: A value too high or low will
// prevent the output from
// changing.
}

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 12, 2006 1:26 am     Reply with quote

One way to simplify it is to just cut out the options and the RS-232 stuff:
Code:

#include <16F877.h>
#device adc=8
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)

void main()
{
int8 value;
   
setup_ccp1(CCP_PWM);

setup_timer_2(T2_DIV_BY_4, 127, 1);

setup_port_a(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);

while(1)
  {
   value = read_adc();

   set_pwm1_duty(value);
  }

}
hongtao



Joined: 09 Mar 2006
Posts: 4
Location: Shanghai China

View user's profile Send private message Send e-mail

PostPosted: Wed Mar 15, 2006 5:26 am     Reply with quote

Hi

PCM programmer, thanks. It works. I can use it in my program.I find so

many post about PWM, after finishing my graduation project, I will write a

post to make a summary or a index, may be it will be easy to check.

谢谢!!
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