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