|
|
View previous topic :: View next topic |
Author |
Message |
crayon_crayon
Joined: 21 Apr 2007 Posts: 2
|
Dual PWM problem over CCP1 & CCP2 |
Posted: Sun Apr 22, 2007 9:21 am |
|
|
hi all,
I want to generate two pwm signals over ccp1 and ccp2 channels to simulate phase difference. I need to use a potentiometer to change phase difference and i am newbie to ccs c I use a dip switch connected to RA0 and RA1 to prepare a peak selection. It will be the third output of 16f877a. As brief, i intend to generate two pwm signals those have phase difference over ccp1 & ccp2, and a control peak per 256/512/1024 pulses of pwm's. I use dip switch to determine peak ratio as if 00>>RC3 generates a peak once 256 pwm peaks, 01>> RC3=1 once 512 and so on. here is the code i wrote :
Code: |
#include <16f877a.h>
#device adc=10
#fuses HS, NOWDT, NOPROTECT, NOPUT
#use Delay(clock=8000000)
void init(){
int re0, re1, re2;
int ra0,ra1;
int16 count,freq,phase;
set_tris_a(1);
set_tris_e(1);
set_tris_d(0);
re0=input(pin_e0);
re1=input(pin_e1);
re2=input(pin_e2);
if((re0==0) && (re1==0)) // Dip switch control routine
{
count=256;
output_d(0x10);
}
else if ((re0==1) && (re1==0))
{
count=512;
output_d(0x20);
}
else if ((re0==0) && (re1==1))
{
count=1024;
output_d(0x40);
}
else if ((re0==1) && (re1==1))
{
count=2048;
output_d(0x80);
}
}
void main()
{
int count,a,b,c;
set_tris_c(1);
output_d(0);
setup_ccp1(ccp_pwm);
setup_ccp2(ccp_delay);
while(1)
{
init();
output_low(PIN_C3);
for(a=0; a<=count; ++a)
{
setup_timer_2(T2_div_by_1,100,1);
set_pwm1_duty(50);
delay_ms(10);
set_pwm2_duty(50);
}
output_high(PIN_C3);
}
}
|
As u see above, the init() must define the third peak's period but it doesn't do. There isn't any change when i changed the position of dip switch. on the other hand how can i obtain any phase difference between ccp1 and ccp2 outputs? I couldn't managed it out. I tried to have ccp2 output to start as delayed according to ccp1 output but it also failed. Is there anyone to help about this topic. Thank you all |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 22, 2007 2:42 pm |
|
|
Quote: |
How can I obtain any phase difference between ccp1 and ccp2 outputs ? |
You can't do it in PWM mode. Both CCP1 and CCP2 run at the same
frequency. The leading edges of both CCP1 and CCP2 outputs will
always occur at the same time. You can change the duty cycle of
each channel independently, so you can have a different phase for
the falling edges. |
|
|
crayon_crayon
Joined: 21 Apr 2007 Posts: 2
|
|
Posted: Mon Apr 23, 2007 12:27 pm |
|
|
thank you pcm programmer,
is there any way to generate phase difference by using a pot for two signal? or do you have any idea about the code i posted recently is right? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 23, 2007 2:46 pm |
|
|
One possible way is to use the two CCP modules in Compare mode.
Then you can change the phase of the two waveforms by changing
the start time of the 2nd waveform (on CCP2).
I haven't used Compare mode before. I've just used standard PWM
mode in a few projects. But I found a thread on the Microchip forum
that has sample code to setup CCP1 in compare mode. I modified
that code and added code for CCP2 as well. I then found a way to
demonstrate the phase shifting of the CCP2 waveform with respect
to the CCP1 waveform. If you run this program and look at the two
CCP outputs with a scope, you will see the phase shifting. Put CCP1
on channel 1 of your scope and trigger on it. Put CCP2 on channel 2.
Here's the link to the original code on the Microchip forum.
http://forum.microchip.com/printable.aspx?m=194482
The Microchip website is down at the moment (at least for me), but
that link has worked in the past.
I don't have any more time to play around with this code. It may or
may not be suitable for more development. There are problems with
using Compare mode in this way, for duty cycle values that are close
to 0% or 100%. These issues are discussed in the link given above.
Code: |
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#ifdef __PCM__
#byte CCP1CON = 0x17
#byte CCP2CON = 0x1D
#else
#byte CCP1CON = 0xFBD
#byte CCP2CON = 0xFBA
#endif
#bit CCP1M0 = CCP1CON.0
#bit CCP2M0 = CCP2CON.0
int16 phase_shift = 0;
#define CCP1_PIN PIN_C2
#define CCP2_PIN PIN_C1
#define PWM_PERIOD 1000L
#define PULSE_ON_TIME 250L
#define PULSE_OFF_TIME (PWM_PERIOD - PULSE_ON_TIME)
#define CCP1 CCP_1
#define CCP2 CCP_2
#define is_ccp1_set() (CCP1M0 == 0)
#define is_ccp2_set() (CCP2M0 == 0)
//-----------------------------------
#int_ccp1
void ccp1_isr(void)
{
if(is_ccp1_set())
{
setup_ccp1(CCP_COMPARE_CLR_ON_MATCH);
CCP1 = CCP1 + PULSE_ON_TIME;
}
else
{
setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
CCP1 = CCP1 + PULSE_OFF_TIME;
}
}
//-----------------------------------
#int_ccp2
void ccp2_isr(void)
{
if(is_ccp2_set())
{
setup_ccp2(CCP_COMPARE_CLR_ON_MATCH);
CCP2 = CCP2 + PULSE_ON_TIME;
}
else
{
setup_ccp2(CCP_COMPARE_SET_ON_MATCH);
CCP2 = CCP2 + PULSE_OFF_TIME;
}
}
//==========================================
void main()
{
setup_timer_1(T1_DIV_BY_1 | T1_INTERNAL);
set_timer1(0);
setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
setup_ccp2(CCP_COMPARE_SET_ON_MATCH);
CCP1 = PULSE_OFF_TIME;
CCP2 = PULSE_OFF_TIME;
output_low(CCP1_PIN);
output_low(CCP2_PIN);
enable_interrupts(INT_CCP1);
enable_interrupts(INT_CCP2);
enable_interrupts(GLOBAL);
phase_shift = 1; // Phase shift in usec
// Slowly change the phase of the CCP2 waveform
// with reference to the CCP1 waveform.
while(1)
{
delay_ms(10);
CCP2 = CCP2 + phase_shift;
}
} |
|
|
|
|
|
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
|