spwm technicues

Hi,im studing the spwm technicues in low frequency inverters.I found an almost complete code on the internet.The code runs the classic spwm as we know.That i want is to generate the inverting switching signal to run for each output when the other pin runs the normal signal.Im studing it for days and i can not reverse the function of the look up table in other half of (sine wave) period beacuse it confuse me the way the look up table is made.I can share picture the signals,or the complete code,for help me..Thank you

Yes, sharing code is a good idea. Use code tags.

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

HERE IS THE COMPLETE CODE

#include <avr/io.h>
#include <avr/interrupt.h>

#define LookupEntries (512)

static int microMHz = 16; // clock frequency in MHz
static int freq, amp = 1024;// Sinusoidal frequency
static long int period; // Period of PWM in clock cycles. 1600 gives 10KHz.
static unsigned int lookUp[LookupEntries];
static char theTCCR1A = 0b10110010;//varible for TCCR1A
static unsigned long int phaseinc, switchFreq;
static double phaseincMult;

int setFreq(int freq); //set in Hertz
int setSwitchFreq(int sfreq); //set in Hertz
int setAmp(float _amp); //set in % (0 - 100)
void makeLookUp(void);
void registerInit(void);

void setup(){
Serial.begin(9600);
makeLookUp();
setSwitchFreq(30000);
setFreq(50);
setAmp(100);
registerInit();
}

void loop(){
/*
The code in the loop reads analog values from pins A1 and A2 so that potentiometers can be connected.
These values are used to vary the amplitude and frequency of the sine wave.
The switching frequency also toggles between 5 and 15Khz.
*/
static int ampVal, freqVal, anologVal;

anologVal = analogRead(A0);
if(anologVal > freqVal1.01 || anologVal < freqVal0.99){
freqVal = anologVal;
setFreq(map(freqVal, 0, 1023, 50, 0));
Serial.println("phaseinc");
Serial.print(phaseinc>>23);
Serial.print(".");
Serial.print(phaseinc&0x007FFFFF);
Serial.print("\n");
}

anologVal = analogRead(A1);
if(anologVal > ampVal1.01 || anologVal < ampVal0.99){
ampVal = anologVal;
setAmp(map(ampVal, 0, 1023, 0, 100));
Serial.println("amplitude");
Serial.println(amp);
}

}

ISR(TIMER1_OVF_vect){
static unsigned long int phase, lastphase;
static char delay1, trig = LOW;

phase += phaseinc;

if(delay1 == 1){
theTCCR1A ^= 0b10100000;// Toggle connect and disconnect of compare output A and B.
TCCR1A = theTCCR1A;
delay1 = 0;
}
else if((phase>>31 != lastphase>>31) && !(phase>>31)){
delay1++;
trig = !trig;
digitalWrite(13,trig);
}

lastphase = phase;
OCR1A = OCR1B = ((lookUp[phase >> 23]*period) >> 12)*amp >> 10;
}

int setFreq(int _freq){
if(_freq < 50 || _freq > 50){ // returns -1 if the frequency value is invalid
return 0;
} else {
freq = _freq;
phaseinc = (unsigned long int) phaseincMult*_freq;
return 1;
}
}

int setSwitchFreq(int sfreq){
double temp;

if(sfreq <= 0 || sfreq > 30000){
return 0;
} else {
switchFreq = sfreq;
period = microMHz1e6/sfreq;
//sindevisions
decimalbits/1MHz =
//10242^23/1e6 = 8,589.934592
phaseincMult = (double) period
8589.934592/microMHz;
phaseinc = (unsigned long int) phaseincMult*freq;
ICR1 = period;
}
}

int setAmp(float _amp)
{
if(_amp < 0 || _amp > 100){
return 0;
} else {
amp = map(_amp,0,100,0,1024);
return 1;
}
}

void makeLookUp(void){
double temp;

cli(); //disable global interupts while lookup table is made
TCCR1A = 0b00000010; //disconnect compare A and B while lookup table is generated

for(int i =0; i < LookupEntries; i++){ // Generating the look up table.
temp = sin(i*M_PI/LookupEntries)*4096;
lookUp *= (int)(temp+0.5); // Round to integer. *

  • }*

  • TCCR1A = theTCCR1A; // reconnect compare outputs*

  • sei(); //re-enable interupts now that table has been made*
    }
    void registerInit(void){

  • // Register initilisation, see datasheet for more detail.*

  • TCCR1A = theTCCR1A; // 0b10000010;*

_ /*10 clear on match, set at BOTTOM for compA._

  • 00 compB disconected initially, toggled later to clear on match, set at BOTTOM.*
  • 00*
  • 10 WGM1 1:0 for waveform 15.*
    _ */_
  • TCCR1B = 0b00011001;*
    _ /*000_
  • 11 WGM1 3:2 for waveform 15.*
  • 001 no prescale on the counter.*
    _ */_
  • TIMSK1 = 0b00000001;*
    _ /*0000000_
  • 1 TOV1 Flag interrupt enable.*
    _ */_
  • sei(); // Enable global interrupts.*
  • // Set outputs pins.*
  • DDRB = 0b00000110; // Set PB1 and PB2 as outputs.*
  • pinMode(13, OUTPUT); // Set trigger pin to output*
    }``

Please edit your post to use code tags as requested.

1 Like