Artlav
Full Member level 2
- Joined
- Nov 26, 2010
- Messages
- 144
- Helped
- 2
- Reputation
- 4
- Reaction score
- 2
- Trophy points
- 1,298
- Activity points
- 2,723
Greetings.
Trying to make a sine wave inverter.
Sinusoidal PWM, an attiny85 driving an H-bridge with two IR2110 at 31KHz (two pins, one for \, other for /), filtered by two-pole LC filter (1.2mH+1µF, 4.7mH+0.47µF).
Schematic: http://orbides.1gb.ru/img/inv.png
Problem is, the output wave is distorted in a peculiar fashion:
http://i.imgur.com/nmGk9QS.jpg
(or http://orbides.1gb.ru/img/sine_bad.png )
The distortions do not depend on the way i generate SPWM, on frequency of either PWM or the generated AC, on filter or load.
Less or more samples in sine table makes the shape more or less fuzzy, but does not alter it's nature.
What could be causing such distortions?
Attiny code, variant one (both variants produce exactly the same waveform):
Variant two:
Trying to make a sine wave inverter.
Sinusoidal PWM, an attiny85 driving an H-bridge with two IR2110 at 31KHz (two pins, one for \, other for /), filtered by two-pole LC filter (1.2mH+1µF, 4.7mH+0.47µF).
Schematic: http://orbides.1gb.ru/img/inv.png
Problem is, the output wave is distorted in a peculiar fashion:
http://i.imgur.com/nmGk9QS.jpg
(or http://orbides.1gb.ru/img/sine_bad.png )
The distortions do not depend on the way i generate SPWM, on frequency of either PWM or the generated AC, on filter or load.
Less or more samples in sine table makes the shape more or less fuzzy, but does not alter it's nature.
What could be causing such distortions?
Attiny code, variant one (both variants produce exactly the same waveform):
Code:
//#########################################################################//
#define F_CPU 8000000UL
//#########################################################################//
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <math.h>
//#########################################################################//
#define set_bit(port,bit) port|=(1<<bit)
#define clear_bit(port,bit) port&=~(1<<bit)
#define byte unsigned char
//#########################################################################//
#define freq 50UL
#define table_count 100UL
#define prescaler 4UL
#define tim_delay F_CPU/(prescaler*freq*table_count*2UL)
#define PI 3.141592
//#########################################################################//
byte sinetable[table_count];
volatile int cnt=0;
volatile byte side=0;
//#########################################################################//
ISR(TIMER1_COMPA_vect)
{
byte x;
cnt++;
if(cnt>=table_count){
//One half-wave, then the other
side=1-side;
if(side==0){clear_bit(TCCR0A,COM0A1);set_bit(TCCR0A,COM0B1);}
if(side==1){clear_bit(TCCR0A,COM0B1);set_bit(TCCR0A,COM0A1);}
cnt=0;
//Deglitch start of the half-wave
TCNT0=0;
}
x=sinetable[cnt];
OCR0A=x;
OCR0B=x;
}
//#########################################################################//
int main(void)
{
clock_prescale_set(0);
//PB0 and PB1 are \ and / of H-bridge
DDRB=0x03;
PORTB=0x00;
//It takes a quarter of a second to fill in the x100 sinetable on board.
//I don't care, if you do - use a precomputed table.
for(int i=0;i<table_count;i++){
sinetable[i]=floor(255.0*sin(((float)i/(float)table_count)*PI));
}
//31.25KHz SPWM
TCCR0A=(1<<WGM00)|(1<<WGM01);
TCCR0B=(1<<CS00);
// /4 prescaler, frequency generation update timer
TCCR1=(1<<CTC1)|(1<<CS11)|(1<<CS10);
GTCCR=(1<<PSR1);
OCR1C=tim_delay;
OCR1A=tim_delay;
TIMSK=(1<<OCIE1A);
set_bit(TCCR0A,COM0A1);
sei();
while(1){}
}
//#########################################################################//
Variant two:
Code:
//#########################################################################//
#define F_CPU 8000000UL
//#########################################################################//
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/power.h>
//#########################################################################//
#define set_bit(port,bit) port|=(1<<bit)
#define clear_bit(port,bit) port&=~(1<<bit)
#define byte unsigned char
//#########################################################################//
#define table_count 100
#define freq 50
#define one_delay 1000000/(freq*table_count*2)
byte PROGMEM sinetable[]=
{
0, 8, 16, 24, 31, 39, 47, 55, 62, 70, 77, 85, 92, 99, 106, 113, 120, 127,
134, 141, 147, 153, 159, 165, 171, 177, 182, 188, 193, 198, 202, 207, 211,
215, 219, 223, 226, 229, 232, 235, 238, 240, 242, 244, 246, 247, 248, 249,
250, 250, 250, 250, 250, 249, 248, 247, 246, 244, 242, 240, 238, 235, 232,
229, 226, 223, 219, 215, 211, 207, 202, 198, 193, 188, 182, 177, 171, 165,
159, 153, 147, 141, 134, 127, 120, 113, 106, 99, 92, 85, 77, 70, 62, 55,
47, 39, 31, 24, 16, 8
};
//########################################################################//
int main(void)
{
byte i;
clock_prescale_set(0);
DDRB=0x03;
PORTB=0x00;
//Fast PWM, 32KHz
TCCR0A=(1<<WGM00)|(1<<WGM01);
TCCR0B=(1<<CS00);
while(1){
//Positive half-wave
set_bit(TCCR0A,COM0A1);
TCNT0=0;
for(i=0;i<table_count;i++){
OCR0A=pgm_read_byte(&sinetable[i]);
_delay_us(one_delay);
}
clear_bit(TCCR0A,COM0A1);
//Negative half-wave
set_bit(TCCR0A,COM0B1);
TCNT0=0;
for(i=0;i<table_count;i++){
OCR0B=pgm_read_byte(&sinetable[i]);
_delay_us(one_delay);
}
clear_bit(TCCR0A,COM0B1);
}
}
//#########################################################################//
Last edited: