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 support@ccsinfo.com

PWM resolution

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



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

PWM resolution
PostPosted: Thu Dec 23, 2010 11:24 pm     Reply with quote

Following is the pwm routine of my code:
Code:

INTS_PER_SECOND = 200;

#int_timer0                         
void servo_isr() {                 

      PWM_count = --PWM_count;
     
      if (PWM_count>=80 && PWM_count<=analog)
      {
         output_bit( PIN_B1, 1);
      }
      else
      {
         output_bit( PIN_B1, 0);
      }
    if(--int_count==0) {           
     ++seconds;
      output_toggle(PIN_B0);
      int_count=INTS_PER_SECOND;
      PWM_count=INTS_PER_SECOND;
    }
}

This program gives a PWM output with the change of analog signal on AN0 pin of microcontroller.
It is working but with steps.
I want to increase the resolution of my steps, how could I do this?
Actually PWM_count is an 8bit integer and change the PWM at PIN B0 on change of discrete value that is 1.
But the analog value which comes from PIC analog pnp has a floating value and can have resolution of 0.1 or 0.2.
SO the question is simple, that is, I want to change PWM on PIN B0 with analog input at AN0 with resolution of 0.1 or 0.2.
Kindly help me with this problem.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Dec 25, 2010 5:18 pm     Reply with quote

I assume you mean that you want the PWM duty cycle to have 500
or 1000 steps, going from 0% duty cycle to 100%. Is that correct ?

What PWM frequency do you need ?

What PIC are you using ?

What is the oscillator frequency of the PIC ?
MAKInnovation



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

PostPosted: Wed Dec 29, 2010 1:24 am     Reply with quote

Actually I am driving a servo motor with timer0.
I have generated 20ms of waveform and looking it on oscilloscope.
You must know that the servo operates with 1ms to 2ms pwm.

Well timer 0 overflow with INTS_PER_SECOND = 400

and PWM can then be generated with some 30 steps for 1ms output.
as shown in my last code.

timer initialization value is:
setup_timer_0( RTCC_INTERNAL| RTCC_DIV_1 | RTCC_8_BIT);
which make the value of 51.2us with 20MH crystal.

I am using PIC16f877.

Suggest me with the suitable PIC, timer and coding method for driving the servo with at least more than 200 steps. i.e. almost analog in nature.
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