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