/******************************************************************************
ZJ_SineInverter.c xtal-locked push-pull sinewave Inverter driver
Open-source - 8th Dec 2009 - www.RomanBlack.com/one_sec.htm
PIC 12F675, xtal (see below).
This manually generates dual inverted sinewave PWM outputs.
PWM frequency varies from 25kHz to 47kHz depending on the step.
It will drive push-pull FETs to make a mains inverter;
10MHz xtal; 50Hz output (same code is used for both)
12MHz xtal; 60Hz output
GP0 - this is push-pull outputA (hi = FET on)
GP1 - this is push-pull outputB (hi = FET on)
_BODEN_OFF _MCLRE_OFF _PWRTE_ON _WDT_OFF _HSOSC
******************************************************************************/
// edit PERIOD to give the freq; PERIOD = (xtal / 4 / (freq*20))
// Note! we need 20 period events per mains cycle, so use (freq * 20)
#define PERIOD 2500 // 10Mhz xtal = 50Hz, 12MHz xtal = 60Hz. (don't edit)
#define PERHI (PERIOD / 256) // don't edit this!
#define PERLO (PERIOD - (PERHI*256)) // don't edit this!
unsigned char step; // sequences each of the 20 PWM steps
#define PHASEA 0b00000001; // push-pull outputA on
#define PHASEB 0b00000010; // push-pull outputB on
//=============================================================================
void interrupt()
{
// TMR1 interrupt. This is a very simple zero-error TMR1 correction.
// It generates an interrupt every 2500 PIC instructions.
// (this code was hardware tested to exact cycle accuracy)
TMR1L -= (PERLO - 2); // fix TMR1, retain error for next period
TMR1H -= (PERHI + 1);
step++;
PIR1.TMR1IF = 0;
}
//=============================================================================
void Delay10(void)
{
// gives a total delay of 10 PIC instructions
asm goto $+1; // 2 insts each
asm goto $+1;
asm goto $+1;
}
//=============================================================================
void Delay20(void)
{
// gives a total delay of 20 PIC instructions
asm goto $+1; // 2 insts each
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
}
//=============================================================================
void main ()
{
//-----------------------------------------------------
// PIC 12F675 setup ports
ANSEL = 0; // ADC off
CMCON = 0x07; // comparators off
GPIO = 0b00000000; // clear GPIO
TRISIO = 0b00000000; // All outputs
//-----------------------------------------------------
// timer setup etc
OPTION_REG = 0b00001000; // TMR0 on, 1:1 prescale
T1CON = 0b00000001; // TMR1 on, 1:1 prescale
INTCON = 0b11000000; // GIE on, PEIE on
PIE1 = 0b00000001; // TMR1 int ON
//-----------------------------------------------------
// main run loop here
while(1)
{
//---------------------------------
// 50% PWM
sinestep0:
step = 0;
sinestep0b:
GPIO = PHASEA;
if(step == 1) goto sinestep1;
Delay20();
GPIO = PHASEB;
Delay20();
asm goto $+1;
asm goto $+1;
goto sinestep0b;
//---------------------------------
// 64% PWM
sinestep1:
GPIO = PHASEA;
if(step == 2) goto sinestep2;
Delay20();
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEB;
Delay20();
goto sinestep1;
//---------------------------------
// 78% PWM
sinestep2:
GPIO = PHASEA;
if(step == 3) goto sinestep3;
Delay20();
Delay10();
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEB;
Delay10();
goto sinestep2;
//---------------------------------
// 89% PWM
sinestep3:
GPIO = PHASEA;
if(step == 4) goto sinestep4;
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEB;
asm goto $+1;
asm goto $+1;
goto sinestep3;
//---------------------------------
// 96% PWM
sinestep4:
GPIO = PHASEA;
if(step == 5) goto sinestep5;
Delay20();
Delay20();
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEB;
asm goto $+1;
goto sinestep4;
//---------------------------------
// 100% PWM
sinestep5:
GPIO = PHASEA;
if(step == 6) goto sinestep6;
goto sinestep5;
//---------------------------------
// 96% PWM
sinestep6:
GPIO = PHASEA;
if(step == 7) goto sinestep7;
Delay20();
Delay20();
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEB;
asm goto $+1;
goto sinestep6;
//---------------------------------
// 89% PWM
sinestep7:
GPIO = PHASEA;
if(step == 8) goto sinestep8;
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEB;
asm goto $+1;
asm goto $+1;
goto sinestep7;
//---------------------------------
// 78% PWM
sinestep8:
GPIO = PHASEA;
if(step == 9) goto sinestep9;
Delay20();
Delay10();
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEB;
Delay10();
goto sinestep8;
//---------------------------------
// 64% PWM
sinestep9:
GPIO = PHASEA;
if(step == 10) goto sinestep10;
Delay20();
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEB;
Delay20();
goto sinestep9;
//---------------------------------
// 50% PWM
sinestep10:
GPIO = PHASEA;
if(step == 11) goto sinestep11;
Delay20();
GPIO = PHASEB;
Delay20();
asm goto $+1;
asm goto $+1;
goto sinestep10;
//---------------------------------
// 64% PWM inv
sinestep11:
GPIO = PHASEB;
if(step == 12) goto sinestep12;
Delay20();
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEA;
Delay20();
goto sinestep11;
//---------------------------------
// 78% PWM inv
sinestep12:
GPIO = PHASEB;
if(step == 13) goto sinestep13;
Delay20();
Delay10();
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEA;
Delay10();
goto sinestep12;
//---------------------------------
// 89% PWM inv
sinestep13:
GPIO = PHASEB;
if(step == 14) goto sinestep14;
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEA;
asm goto $+1;
asm goto $+1;
goto sinestep13;
//---------------------------------
// 96% PWM inv
sinestep14:
GPIO = PHASEB;
if(step == 15) goto sinestep15;
Delay20();
Delay20();
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEA;
asm goto $+1;
goto sinestep14;
//---------------------------------
// 100% PWM inv
sinestep15:
GPIO = PHASEB;
if(step == 16) goto sinestep16;
goto sinestep15;
//---------------------------------
// 96% PWM inv
sinestep16:
GPIO = PHASEB;
if(step == 17) goto sinestep17;
Delay20();
Delay20();
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEA;
asm goto $+1;
goto sinestep16;
//---------------------------------
// 89% PWM inv
sinestep17:
GPIO = PHASEB;
if(step == 18) goto sinestep18;
Delay20();
Delay20();
asm goto $+1;
asm goto $+1;
GPIO = PHASEA;
asm goto $+1;
asm goto $+1;
goto sinestep17;
//---------------------------------
// 78% PWM inv
sinestep18:
GPIO = PHASEB;
if(step == 19) goto sinestep19;
Delay20();
Delay10();
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEA;
Delay10();
goto sinestep18;
//---------------------------------
// 64% PWM inv
sinestep19:
GPIO = PHASEB;
if(step == 20) goto sinestep0;
Delay20();
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm goto $+1;
asm nop;
GPIO = PHASEA;
Delay20();
goto sinestep19;
}
}
//-----------------------------------------------------------------------------