PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 30, 2010 4:24 pm |
|
|
Here is a sample program that uses the CCP compare mode to generate
the servo pulse. It has over 600 steps to go from a 1ms pulse duration
to 2ms duration. If you run this program and look at pin B0 with an
oscilloscope, you will see the pulse width slowly increasing from 1 to 2 ms,
and then do it again, continuously.
Code: |
#include <16F877.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#define SERVO_PIN PIN_B0
// These pulse duration values are for a 20 MHz PIC oscillator
// frequency and a Timer1 divisor of 8.
#define PWM_PERIOD 12500L // Gives 20ms PWM period (50 Hz)
#define PULSE_1MS 625L // Gives 1ms high level pulse
#define PULSE_2MS 1250L // Gives 2ms high level pulse
int16 pulse_high_duration;
int8 pulse_done_flag;
//-----------------------------------
#int_ccp1
void ccp1_isr(void)
{
static int8 set_servo_pin_high = TRUE;
// If servo pin low level pulse time is finished,
// then do the high portion of the signal.
if(set_servo_pin_high)
{
output_high(SERVO_PIN);
set_servo_pin_high = FALSE;
CCP_1 += pulse_high_duration;
}
else // If high portion of signal is done, do the low part.
{
output_low(SERVO_PIN);
set_servo_pin_high = TRUE;
CCP_1 += (PWM_PERIOD - pulse_high_duration);
pulse_done_flag = TRUE;
}
}
//==========================================
void main()
{
int16 i;
setup_timer_1(T1_DIV_BY_8 | T1_INTERNAL);
set_timer1(0);
// Setup CCP to generate CCP1 interrupt when Timer1
// matches the value in the CCP1 registers.
setup_ccp1(CCP_COMPARE_INT);
output_low(SERVO_PIN);
// Initialize the variables and CCP1 to give a 1 ms servo pulse.
pulse_high_duration = PULSE_1MS;
CCP_1 = PWM_PERIOD - pulse_high_duration; // Pulse Off time
// This flag tells the main loop code (below) when it's OK
// to change the pulse_high_duration variable.
pulse_done_flag = FALSE;
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(1)
{
// Slowly increase the pulse from 1ms to 2ms.
for(i = PULSE_1MS; i < PULSE_2MS; i++)
{
while(!pulse_done_flag); // Wait until pulse is done
pulse_done_flag = FALSE;
disable_interrupts(GLOBAL);
pulse_high_duration = i;
enable_interrupts(GLOBAL);
}
}
}
|
|
|