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

Dual PWM problem over CCP1 & CCP2

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



Joined: 21 Apr 2007
Posts: 2

View user's profile Send private message

Dual PWM problem over CCP1 & CCP2
PostPosted: Sun Apr 22, 2007 9:21 am     Reply with quote

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 Sad 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

View user's profile Send private message

PostPosted: Sun Apr 22, 2007 2:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 23, 2007 12:27 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 23, 2007 2:46 pm     Reply with quote

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;
  }

}
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