Hi friends i am working on sine wave off line ups.I have written the code i am sine wave at no load as i am loading the inverter its shape is changing to square wave at 60 W bulb load initially its shape is changed to "D-shape" as i am loading the inverter it is complety going to square wave.I dont know what is the cause. can anyone help me to solve this problem and maintain sinewave at any load.....
Here i am posting the code and also output sensing circuit may it is usefull for you to analysis.
#include <pic.h>
#define ki 57
#define kp 32
int out_voltage=0x00,out_voltage_1=00; // A/D converter value
int ref_voltage=0; // ref volatge based on feedback
int x=0;
int xold=0;
// PI Compensator values
long y=0;
long yold=0;
int Duty_cycle=0;
long z=0,z1=0;
unsigned char sine_table_count=0,low_batt_flag=0; // Index into the sinewave reference table
unsigned char Half_cycle_count=0,duty_count=0,duty_divide=5; // Determines the halfcycle
char PortB_reg=0,PortB_reg_prev=0;
unsigned int sine_value=0x00; // Sine table value
unsigned int d1,low_batt_cnt=0;
// This table yields VRMS input
bank1 unsigned int const sine_table[33]={39,77,114,151,186,219,250,279,305,328,347,364,377,386,392,394,392,386,
377,364,347,328,305,279,250,219,186,151,114,77,39,15};
void main(void)
{
/* setup stuff */
TRISA= 0x2F; // PORTA pins as input pins
TRISC = 0x00; // PORT C pins as output pins
PORTC=0x00;
TRISB=0x73; //pin 2 and 3 as outputs and others as inputs.
PORTB=0;
RB3=1;
ANSELH=0x7C; //inputs configured as a analog and digital inputs.
IOCB=0x40; //Pin-6 configured to port change interrupt.
RBIE=1;//enables port change interrupt
ADIF=0; // clearing A/D interrupt flag
ADIE=1; // Enable A/D interrupt
ADCON0 = 0x91; //A/D setup. set pin2 (AN0) as Analog input for volatge feedbak
ADCON1 = 0xC0;
TMR0=62; //0x3D; //0x3D;//0x5B; // TMR0 setup
PSA=0;
PS2=0;
PS1=0; //0;
PS0=1; //1;
T0CS = 0; // Timer increments on instruction clock
T0IE = 1; // Enable interrupt on TMR0 overflow
PEIE=1; //enalbe pheripheral interrupt
GIE = 1; // Global interrupt enable
GODONE = 1;
while(1) // Loop forever
{}
}
static void interrupt isr(void) // Here be interrupt function - the name is unimportant.
{
if(ADIF)
{
ADIF=0;
out_voltage=0;
out_voltage = ADRESH<<8;
out_voltage = out_voltage + ADRESL;
ADCON0 = 0x91;
ADCON1 = 0xC0;
GODONE = 1;
}
if(RBIF)
{
PortB_reg=PORTB;
PortB_reg_prev=(PortB_reg_prev)^(PortB_reg);
if(PortB_reg_prev&0b01000000)
{
if(RB6==0)
{
low_batt_flag=1;
}
if(RB6==1)
{
low_batt_flag=0;
T0CS=0;
RB2=0;
TMR2ON=1;
}
}
PortB_reg_prev=PortB_reg;
RBIE=1;
RBIF=0;
}
if(T0IF) // Clear interrupt flag, ready for next
{
T0IF = 0;
T0CS = 0; // set up timer0
TMR0=62; //0x3D; //0x5B;
PSA=0;
PS2=0;
PS1=0;
PS0=1;
sine_value= sine_table[sine_table_count];
ref_voltage= sine_value;
PR2 = 0x80; //0xA6 0x80 0x80 0x93 0xC0; // period=d2
T2CON = 0x04; // enablint timer 2 and prescaler value =1:1
if (duty_divide>=0)
{
if(duty_divide>0)
{
if(Half_cycle_count)
{ // positive half cycle
d1=sine_value>>duty_divide;
CCPR2L = d1>>2;
CCP2CON = ((d1&&0x03)<<4)+0x0C;
CCP1CON = 0x00;
}
else
{ // Negative half cycle
d1=sine_value>>duty_divide;
CCPR1L = d1>>2;
CCP1CON = ((d1&&0x03)<<4)+0x0C;
CCP2CON = 0x00;
}
}
else if(duty_divide==0)
{
out_voltage_1=out_voltage-500;
if (Half_cycle_count)
{
out_voltage_1=~out_voltage_1;
out_voltage_1=out_voltage_1+1;
}
x =out_voltage_1-ref_voltage;
z1=ki*x;
z=z1>>10;
y=yold-(kp*(x-xold))-z;
Duty_cycle=y>>6;
if(Duty_cycle<0)
{
Duty_cycle=~Duty_cycle;
Duty_cycle=Duty_cycle+1;
}
if(Duty_cycle>1023)
Duty_cycle=1023;
xold=x;
yold=y;
if(Half_cycle_count)
{ // positive half cycle
CCPR2L = Duty_cycle>>2;
CCP2CON = ((Duty_cycle&&0x03)<<4)+0x0C;
CCP1CON = 0x00;
}
else
{ // Negative half cycle
CCPR1L =Duty_cycle>>2;
CCP1CON = ((Duty_cycle&&0x03)<<4)+0x0C;
CCP2CON = 0x00;
}
}
}
sine_table_count++;
if(sine_table_count>=33)
{
sine_table_count=0x00;
if(Half_cycle_count)
{
Half_cycle_count=0;
duty_count++;
if (duty_count>2)
{
duty_count=0;
if(duty_divide>0)
duty_divide--;
else if(duty_divide==0)
duty_divide=0;
}
}
else
Half_cycle_count=1;
}
if(low_batt_flag==1)
{
low_batt_cnt++;
if(low_batt_cnt==9615)
RB2=1;
if(low_batt_cnt==19231)
RB2=0;
if(low_batt_cnt==28845)
RB2=1;
if(low_batt_cnt==38460)
{
RB2=0;
low_batt_cnt=0;
CCP1CON = 0x00;
CCP2CON = 0x00;
TMR2ON=0;
T0CS=1;
}
}
}
}