過零檢測及單片機調(diào)壓
首先用PWM(脈寬調(diào)制)方法用于可控硅控制是有條件的,即調(diào)制頻率不能大于市電頻率(50Hz),也就是周期不能小于20mS,否則就不能達到調(diào)制作用,調(diào)制頻率超過市電頻率時,可控硅即處于連續(xù)導(dǎo)通狀態(tài)而不能達到調(diào)壓目的。只有調(diào)制頻率低于市電頻率才能起到調(diào)壓目的,即限制市電的周波通過可控硅的數(shù)量而起到調(diào)壓的目的。因此用該種方法調(diào)制的電壓周波數(shù)一定是小于50HZ,超過了人眼視覺暫留效應(yīng),此就是用于調(diào)光產(chǎn)生閃爍的原因。該調(diào)壓方法用在調(diào)功或?qū)γ}動電壓不敏感的用途上尚可。如果采用可控硅調(diào)壓用在調(diào)光上,須采用移相的調(diào)制方法,可使光連續(xù)可調(diào)。采用移相方法就需過零檢測作為移相基點。過零檢測其實并不難,如果要求調(diào)壓比不是很高采用簡單的方法即可奏效;用一只三極管即可。用單片機進行移相調(diào)壓控制可以做得很精。
/********************************************************************************/
#i nclude
__CONFIG (CPD&PROTECT&BOREN&MCLRDIS&PWRTEN&WDTEN&INTIO);
/********************************************************************************/
//
void init (void);
/********************************************************************************/
//
bit fg_pw,fg_vs,fg_zq;
volatile unsigned char fg_count;
volatile unsigned int time1_temp,buff;
/********************************************************************************/
#define powon GPIO|=0B00110000
#define powoff GPIO&=0B00001111
#define vpp GPIO2
#define feedback GPIO0
/********************************************************************************/
void init (void)
{ CLRWDT();
TRISIO=0B11001111;
WPU=1;
IOCB=4; //使能過零信號中斷
VRCON=0;
PIE1=1;
OPTION=0;
INTCON&=7;
INTCON|=0B10001000;
CMCON=7;
T1CON&=1;
T1CON|=0x10;
}
/*********************************************************************************/
void interrupt isr_power (void)
{ GPIO=GPIO;
if (TMR1IF&&TMR1ON)
{ TMR1IF=0;
if (fg_pw)
{ if (!fg_vs)
{powon;fg_vs=1;TMR1L=112;TMR1H=0xfe;} //觸發(fā)寬度400US(256+144)
else
{fg_vs=0;
powoff; //關(guān)閉
TMR1ON=0;
}
}
else {powoff;fg_count=0;}
}
if (GPIF)
{ GPIF=0;
if (fg_pw)
{fg_zq=1;
TMR1H=(time1_temp>>8);
TMR1L=(time1_temp&0xff);
//if (vpp==0) TMR1H-=3; //上下沿檢測,下沿時間補償(3*256)US
TMR1ON=1;
}
else
{ if (vpp) {TMR1ON=1;TMR1L=TMR1H=0;} //l-->h
else
{time1_temp=(TMR1H<<8|TMR1L); //h-->l
TMR1ON=0;
TMR1L=TMR1H=0;
time1_temp=~time1_temp; //同步信號周期檢測(時間)
time1_temp+=1000; //一個半周時間中縮短1MS開始觸發(fā)
buff=time1_temp;
if (++fg_count>=4) fg_pw=1;//連續(xù)周期檢測4次
}
}
}
}
/************************************************************************************/
void main (void)
{ unsigned int i;
TMR0=0;
init();
while (1)
{ if (fg_pw&&fg_zq)
{ fg_zq=0;
if (feedback) {if(time1_temp<0xffff-1000) time1_temp+=20;}//功率(電壓)上限
else
{if (time1_temp>buff)time1_temp-=20;} //功率(電壓)下限
for (i=1000;i!=0;i--) {;}
init();
}
}
}