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 Not working Correctly

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



Joined: 23 Jan 2004
Posts: 4
Location: Silverstone UK

View user's profile Send private message Send e-mail

PWM Not working Correctly
PostPosted: Fri Oct 02, 2009 9:12 am     Reply with quote

I am having a few problems getting the right PWM duty cycle. Frequency is being calculated OK.

Compiler version is 4.013

PIC is 18F4550 with 10-bit PWM resolution.

I want 0-30% duty cycle, but I don't get that. It also changes each time I adjust the TMR2 Offset value to change the frequency (to get optimum MOSFET switching time).

I have included my code - I suspect user error [me] as I am not an expert, however this is an F1 Application, so any help would be appreciated.

Code:
#include <18F4550.h>

//~~~ 48MHZ OSCILLATOR CONFIGS ~~~//
//#fuses EC,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL12,CPUDIV1,VREGEN,NOMCLR//Oscillator is EC 48MHz
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOMCLR//Oscillator is HS 20MHz
//#fuses INTRC,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL2,CPUDIV1,VREGEN,NOMCLR//Oscillator is Internal 8MHz

#device ADC=10;

#use delay(clock=48000000)

#use fast_io(A)

//Defines - Buttons and LED's
#define TOGGLE      output_toggle(PIN_C1);   //LED to indicate function
#define LED_OFF      output_low(PIN_C1);

// Global Variables defines here
unsigned int16 ms1,ms2;            //Millisecond timer values (1, 2 & 3)

// Timer 3 is the main interrupt - driven from the system oscillator it will
// Generate an interrupt every 0.2mS

#int_timer3
void isr_timer3(void) {
   set_timer3(63135);//to get a 200uS pulse = 65535 - 0.0001*[48e6/(4x2)] =65535-2400= 64335
   ms1++;   //ms1 is used for main PWM control loop
   ms2++;   //ms2 is used for house keeping (flashing LED)

}

void main(void)
{
   unsigned int16 ADCVal,PWMVal,Enable;
   unsigned int1   ON;

   //Initialization Here
   setup_timer_3(T3_INTERNAL | T3_DIV_BY_2);//Use to generate a 200uS Tick
   enable_interrupts(INT_TIMER3);
    enable_interrupts(GLOBAL);             //enable all interrupts (Else timer3 wont happen)
   setup_adc(ADC_CLOCK_DIV_64);         //Use the Internal Clock ADC_CLOCK_INTERNAL)
   setup_adc_ports(AN0_TO_AN4 | VREF_VREF);//VREF_VREF   //Configure for Analog
   set_adc_channel(0);                  //Select the first channel AN0
   set_tris_a(0xff);                  //Ensure all of port A is input
   set_tris_c(0b11111111);               //Set PWM Pin directions - all inouts so as not to blow MOSFETS
   set_tris_d(0b11111111);               //Port D PWM Pin directions - all input so as not to blow MOSFETS
   port_b_pullups(TRUE);
     setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
   setup_timer_2(T2_DIV_BY_16, 74, 1);   // [24KHz is 127 div4], so [15KHz is 199 div4], [10KHz is is 75 div 16]
    set_pwm1_duty(0); 

   ADCVal=0;
   PWMVal=0;//PWM Duty cycle

   set_tris_c(0b11111001);               //Port C PWM Pin directions
   set_tris_d(0b00011111);               //Port D PWM Pin directions
     setup_ccp1(CCP_PWM_FULL_BRIDGE_REV | CCP_PWM_H_H);// Configure the PWM Module - QUAD (H-Bridge)


      while (TRUE)
      {
      if(ms1>=10)         //1 tick is 200uS so 10 is 500Hz
      {
         ms1=0;
         set_adc_channel(0);
         delay_us(10);
         ADCVal=Read_ADC();
         delay_us(5);
         set_adc_channel(4);
         delay_us(10);
         Enable=Read_ADC();

         //Implement this before plugging into the VC
         if(Enable<491 || Enable>532)//Between 2.4, and 2.6 volts to enable on AN4
         {
            set_pwm1_duty(0);//Motor off
            ON=0;
         }
         //This will make the motor go forwards or backwards
         //Implement this before plugging into the VC
         if(Enable>491 && Enable<532)//Between 2.4, and 2.6 volts to enable on AN4
         {
            ON=1;
   
               //Go Forwards
            if(ADCVal>=512)//More than 2.5V so go forwards
            {
               setup_ccp1(CCP_PWM_FULL_BRIDGE | CCP_PWM_H_H);
               PWMVal=(ADCVal-512)*0.18;//*0.3;//Restrict to 30%//was 0.48 for 15KHz
               set_pwm1_duty(PWMVal);
            }
               //Go Backwards
            if(ADCVal<512)//Less than 2.5V so go backwards
            {
               setup_ccp1(CCP_PWM_FULL_BRIDGE_REV | CCP_PWM_H_H);
               PWMVal=(511-ADCVal)*0.18;//*0.3;//Restrict to 30% Maximum was 511
               set_pwm1_duty(PWMVal); 
            }
         }

      }

      //Housekeeping Items
      if(ms2>=250)
      {   
         if(ON)TOGGLE;
         if(!ON)LED_OFF;
         ms2=0;
      }

   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 02, 2009 2:08 pm     Reply with quote

Quote:
I want 0-30% duty cycle, but I don't get that

Get rid of about 90% of your code and try a simple test program,
as shown in this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=29565&start=1
Try adjusting the value in set_pwm1_duty() to get a 30% duty cycle on
your oscilloscope.

Quote:

It also changes each time I adjust the TMR2 Offset value to change the
frequency.

That's normal. The Timer2 settings control the period of the PWM signal.
The middle value of the setup_timer_2() function (PR2) sets the upper
limit for the duty cycle value. (If the duty cycle number is greater than
the PR2 number, you will get 100% duty cycle). So if you change the PR2
value, but leave the duty cycle number the same, the percentage will
change. If you change the PR2 value, you also have to change the duty
cycle value, if you want to keep the 30% duty cycle.
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