/******************************************************************************
ZE_SineConverter.c mains-locked 50Hz to 60Hz converting sinewave Inverter
Open-source - 9th Dec 2009 - www.RomanBlack.com/one_sec.htm
PIC 12F675, 8MHz xtal (see below).
This generates dual push-pull sinewave outputs at 60Hz, which is
freq locked to a 50Hz mains input. It acts as a 50Hz to 60Hz converter
that can drive a transformer to make a mains freq converter.
GP0 - this is 60Hz push-pull outputA (hi = FET on)
GP1 - this is 60Hz push-pull outputB (hi = FET on)
GP2 - is the \ edge detect for 50Hz mains input
_BODEN_OFF _MCLRE_OFF _PWRTE_ON _WDT_OFF _HSOSC
******************************************************************************/
// edit PERIOD to give the freq; PERIOD = (xtal / 4 / (freq*24))
// Note! we need 24 period events per mains cycle, so use (freq * 24)
#define PERIOD 1667 // 8Mhz xtal (don't edit this)
#define PERHI (PERIOD / 256) // don't edit this!
#define PERLO (PERIOD - (PERHI*256)) // don't edit this!
unsigned char vpulse; // to sequence the 24 virtual pulses
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()
{
//-----------------------------------------------------
// This is a TMR1 overflow interrupt for 23 of 24 cases.
// on 1 of 24 cases it acts as a GP2 interrupt on \ edge.
// This is used to generate exactly 24 virtual pulses,
// synchronised to the 50Hz mains input (GP2 \ edge).
//-----------------------------------------------------
if(!vpulse) // if it is last vpulse0
{
// just leave TMR1 free running, this allows easy first sync!
vpulse = 23;
}
else // else is vpulse1-23
{
TMR1L = (256 - (PERLO - 3 - 16)); // load TMR1 for 1 vpulse period
TMR1H = (256 - (PERHI + 1));
vpulse--; // sequence the next virtual pulse
INTCON.INTF = 0; // clear GP2 \ edge int flag
}
step++; // sequence the next 60Hz PWM 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 = 0b00000100; // GP2 input, rest outputs
//-----------------------------------------------------
// timer setup etc
OPTION_REG = 0b00001000; // GP2 \ int edge
T1CON = 0b00000001; // TMR1 on, 1:1 prescale
INTCON = 0b11000000; // GIE on, PEIE on
PIE1 = 0b00000001; // TMR1 int ON
INTCON.INTE = 1; // GP2 \ edge 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;
}
}
//-----------------------------------------------------------------------------