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

PWM resolution

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



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 30, 2010 4:24 pm     Reply with quote

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

}
 
MAKInnovation



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

PostPosted: Sat Jan 01, 2011 6:36 am     Reply with quote

Thank you again for your help
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