|
|
View previous topic :: View next topic |
Author |
Message |
hongtao
Joined: 09 Mar 2006 Posts: 4 Location: Shanghai China
|
pwm on 16F877A, how to change the duty cycle |
Posted: Sat Mar 11, 2006 8:59 pm |
|
|
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
|
|
Posted: Sat Mar 11, 2006 9:21 pm |
|
|
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
|
|
Posted: Sat Mar 11, 2006 9:33 pm |
|
|
Thank you, PCM programmer. I correct it. Can you give some suggestion? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 11, 2006 11:01 pm |
|
|
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
|
|
Posted: Sun Mar 12, 2006 12:47 am |
|
|
Thanks for your detailed reply. 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?
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
|
|
Posted: Sun Mar 12, 2006 1:26 am |
|
|
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
|
|
Posted: Wed Mar 15, 2006 5:26 am |
|
|
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.
谢谢!! |
|
|
|
|
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
|