PWM duty cycle problem in pic 16f877a (hightech c coding) problem.kinldy help

Status
Not open for further replies.

mugheesnawaz

Member level 1
Joined
May 1, 2013
Messages
39
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
1,605
i am using a code which takes frequency and dutycycle and give the pulse.frequency works fine (accurate) but duty doesnt always give correct output. i.e if a enter 50 as duty cycle then it will give accurate duty cycle and when i choose 80,it will give 80% duty but when i want 10,20 or 25 then it gives wrong duty but accurate frequency.pwm is the part which i cant figure so far.i know the equations but when i write them it gives errors.i am attaching the code,kindly have a look at it.i will be very thankful.the trouble lies in PWM_Set_Duty function which i am unable to figure out.
Code:
#include <pic.h>
#include <htc.h>
#define _XTAL_FREQ 20000000 
void PWM_Init(float frequency,unsigned char timer_prescalar);
void PWM_Set_Duty(unsigned char duty_cycle,unsigned char timer_presclar);
void PWM_Stop();

unsigned char i=0;
unsigned char flag = 0;
unsigned int value;
void main()
{
unsigned short duty1=20;
unsigned char TimerPrescalar=4;
PWM_Init(25000,TimerPrescalar);
PWM_Set_Duty(20,TimerPrescalar);
while(1)
{
}
}

void PWM_Init(float frequency,unsigned char timer_prescalar)
{

float temp;
TRISC2 = 0;

temp = _XTAL_FREQ/frequency;
temp = temp/4;
temp = temp/timer_prescalar;
PR2 = (unsigned char)(temp);
PR2 = PR2-1;
CCPR1L = 0x00;
CCP1CON = 0x0C; //Set Zero Percent Duty Cycle Initially
TRISC2 = 0; 
if(timer_prescalar == 1)
{
T2CON = 0b00000100; 
}
else if(timer_prescalar == 4)
{
T2CON = 0b00000101; 
}
else if(timer_prescalar == 16)
{
T2CON = 0b00000111; 
}
}
void PWM_Set_Duty(unsigned char duty_cycle,unsigned char timer_prescalar)
{
unsigned int register_value;
float frequency;

frequency = (_XTAL_FREQ/4);
frequency = (frequency/timer_prescalar);
frequency = (frequency/(PR2+1)); //Frequency of PWM Signal

frequency = (frequency*100)/(duty_cycle);

register_value = (_XTAL_FREQ)/(unsigned int)frequency;
register_value = (register_value/timer_prescalar);

CCPR1L = (register_value>>2);
register_value = register_value & 0x03;
CCP1CON = CCP1CON | (register_value<<4);
}
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…