--------------------------------------------------
#include "iom32v.h"
#define WDR() asm("WDR")
#define NOP() asm("NOP")
unsigned char dcovervoltage_flag=0,acovervoltage_flag=0,dcundervoltage_flag=0,acundervoltage_flag=0;
//直流過(guò)壓標(biāo)志 交流過(guò)壓標(biāo)志 直流欠壓標(biāo)志 交流欠壓標(biāo)志
unsigned char dcreovervoltage_flag=0,acreovervoltage_flag=0,dcreundervoltage_flag=0,acreundervoltage_flag=0;
//直流過(guò)壓恢復(fù)標(biāo)志 交流過(guò)壓恢復(fù)標(biāo)志 直流欠壓恢復(fù)標(biāo)志 交流欠壓恢復(fù)標(biāo)志
static unsigned char overcurrent[2]={0,0};
//---------------------------------------------------------
//---------------------------------------------------------
/*使能看門(mén)狗*/
void WDT_enable(void)
{
WDTCR|=0x08; //Allow change,WDT enable
WDTCR|=0x0F; //Set reset time,2.1S.
}
//---------------------------------------------------------
//---------------------------------------------------------
/*自定義延時(shí)程序*/
void delay(void)
{
unsigned char i;
for(i=2;i>0;i--);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*初始化模擬比較器*/
void initialization_ac()
{
SFIOR|=0x08; //使能模擬比較器多工輸入
ACSR&=0x3F; //使能模擬比較器,利用外部基準(zhǔn),關(guān)閉中斷
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流過(guò)壓檢測(cè)程序*/
unsigned char dc_overvoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8; //選擇通道0,直流過(guò)壓檢測(cè)
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果
ACSR=0x10;
if(ACSR==0x00) //條件成立,直流過(guò)壓
{
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
PORTD&=0xF7; // PD3輸出低電平
PORTD|=0x10; //PD4輸出高電平,說(shuō)明直流輸入異常
value=1;
}
else //直流沒(méi)有過(guò)壓
{
PORTD|=0x08; // PD3輸出高電平,輸入正常
PORTD&=0xEF; //PD4輸出低電平,輸入正常
value=0;
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流過(guò)壓恢復(fù)檢測(cè)程序*/
void dc_reovervoltage(void)
{
if(dcovervoltage_flag==1) //條件成立,說(shuō)明過(guò)壓,需要檢測(cè)恢復(fù)
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8; //選擇通道1,直流過(guò)壓恢復(fù)檢測(cè)
ADMUX|=0x01;
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果。
ACSR=0x10;
if(ACSR==0x20) //條件成立,說(shuō)明過(guò)壓恢復(fù)
{
PORTD|=0x08; // PD3輸出高電平,輸入正常
PORTD&=0xEF; //PD4輸出低電平,輸入正常
dcovervoltage_flag=0;
}
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流欠壓檢測(cè)程序*/
unsigned char dc_undervoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8; //選擇通道2,直流欠壓檢測(cè)
ADMUX|=0x02;
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果
ACSR=0x10;
if(ACSR==0x20) //條件成立,直流欠壓
{
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
PORTD&=0xF7; // PD3輸出低電平
PORTD|=0x10; //PD4輸出高電平,說(shuō)明直流輸入異常
value=1;
}
else //直流沒(méi)有欠壓
{
PORTD|=0x08; // PD3輸出高電平,輸入正常
PORTD&=0xEF; //PD4輸出低電平,輸入正常
value=0;
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流欠壓恢復(fù)檢測(cè)程序*/
void dc_reundervoltage(void)
{
if(dcundervoltage_flag==1) //條件成立,說(shuō)明過(guò)壓,需要檢測(cè)恢復(fù)
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8; //選擇通道3,直流欠壓恢復(fù)檢測(cè)
ADMUX|=0x03;
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果。
ACSR=0x10;
if(ACSR==0x00) //條件成立,說(shuō)明欠壓恢復(fù)
{
PORTD|=0x08; // PD3輸出高電平,輸入正常
PORTD&=0xEF; //PD4輸出低電平,輸入正常
dcundervoltage_flag =0;
}
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流過(guò)壓檢測(cè)程序*/
unsigned char ac_overvoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8;
ADMUX|=0x04; //選擇通道4,交流過(guò)壓檢測(cè)
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x00) //條件成立,交流過(guò)壓
{
PORTD|=0x40; // PD6輸出設(shè)置為1,禁止AC/DC輸出
PORTD|=0x02; //PD1輸出高電平,說(shuō)明交流輸入異常
PORTD&=0xFE; // PD0輸出低電平
value=1;
}
else //交流沒(méi)有過(guò)壓
{
PORTD|=0x01; // PD0輸出高電平,輸入正常
PORTD&=0xFD; // PD1輸出低電平,輸入正常
value=0;
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流過(guò)壓恢復(fù)檢測(cè)程序*/
void ac_reovervoltage(void)
{
if(acovervoltage_flag==1) //條件成立,說(shuō)明過(guò)壓,需要檢測(cè)恢復(fù)
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8;
ADMUX|=0x05; //選擇通道5,交流過(guò)壓恢復(fù)檢測(cè)
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果。
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x20) //條件成立,說(shuō)明過(guò)壓恢復(fù)
{
PORTD|=0x01; // PD0輸出高電平,輸入正常
PORTD&=0xFD; // PD1輸出低電平,輸入正常
acovervoltage_flag=0;
}
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流欠壓檢測(cè)程序*/
unsigned char ac_undervoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8;
ADMUX|=0x06; //選擇通道6,交流欠壓檢測(cè)
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x20) //條件成立,交流欠壓
{
PORTD|=0x40; // PD6輸出設(shè)置為1,禁止AC/DC輸出
PORTD|=0x02; //PD1輸出高電平,說(shuō)明交流輸入異常
PORTD&=0xFE; // PD0輸出低電平
value=1;
}
else //交流沒(méi)有欠壓
{
PORTD|=0x01; // PD0輸出高電平,輸入正常
PORTD&=0xFD; // PD1輸出低電平,輸入正常
value=0;
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流欠壓恢復(fù)檢測(cè)程序*/
void ac_reundervoltage(void)
{
if(acundervoltage_flag==1) //條件成立,說(shuō)明過(guò)壓,需要檢測(cè)恢復(fù)
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)為0時(shí),打開(kāi)多路復(fù)用器,ADC多路復(fù)用器為模擬比較器選擇負(fù)極輸入
ADMUX&=0xF8; //選擇通道7,交流欠壓恢復(fù)檢測(cè)
ADMUX|=0x07;
delay(); //轉(zhuǎn)換延遲,等待轉(zhuǎn)化結(jié)果。
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x00) //條件成立,說(shuō)明欠壓恢復(fù)
{
PORTD|=0x01; // PD0輸出高電平,輸入正常
PORTD&=0xFD; // PD1輸出低電平,輸入正常
acundervoltage_flag=0;
}
ADCSRA|=0x80; //關(guān)閉多路復(fù)用器,模擬比較器選擇負(fù)極輸入
}
}
//---------------------------------------------------------
//---------------------------------------------------------
/*過(guò)流檢測(cè)程序*/
void check_overcurrent(void)
{
ADCSRA|=0x80;
delay();
delay();
delay();
delay();
delay();
ACSR=0x10;
delay();
delay();
delay();
if(ACSR==0x00)
{
if((PIND&0x80)==0x80)
{
overcurrent[0]=1; //交流輸出過(guò)流
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
}
if((PINB&0x02)==0x02)
{
overcurrent[1]=1;
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
}
}
}
//---------------------------------------------------------
//---------------------------------------------------------
void state_checkinput_dc(void)
{
if(dcreundervoltage_flag==0)
{
if(dcreovervoltage_flag==0)
{
dcovervoltage_flag=dc_overvoltage();
if(dcovervoltage_flag==1)
{
dc_reovervoltage();
WDR();
dcreovervoltage_flag=dcovervoltage_flag;
}
else
{
if(dcreundervoltage_flag==0)
{
dcundervoltage_flag=dc_undervoltage();
if(dcundervoltage_flag==1)
{
dc_reundervoltage();
WDR();
dcreundervoltage_flag=dcundervoltage_flag;
}
else
{
;
}
}
else
{
dc_reundervoltage();
dcreundervoltage_flag=dcundervoltage_flag;
}
}
}
else
{
dc_reovervoltage();
dcreovervoltage_flag=dcovervoltage_flag;
}
}
else
{
dc_reundervoltage();
dcreundervoltage_flag=dcundervoltage_flag;
}
}
//---------------------------------------------------------
//---------------------------------------------------------
void state_checkinput_ac(void)
{
if(acreundervoltage_flag==0)
{
if(acreovervoltage_flag==0)
{
acovervoltage_flag=ac_overvoltage();
if(acovervoltage_flag==1)
{
ac_reovervoltage();
WDR();
acreovervoltage_flag=acovervoltage_flag;
}
else
{
if(acreundervoltage_flag==0)
{
acundervoltage_flag=ac_undervoltage();
if(acundervoltage_flag==1)
{
ac_reundervoltage();
WDR();
acreundervoltage_flag=acundervoltage_flag;
}
else
{
;
}
}
else
{
ac_reundervoltage();
acreundervoltage_flag=acundervoltage_flag;
}
}
}
else
{
ac_reovervoltage();
acreovervoltage_flag=acovervoltage_flag;
}
}
else
{
ac_reundervoltage();
acreundervoltage_flag=acundervoltage_flag;
}
}
//---------------------------------------------------------
//---------------------------------------------------------
void main(void)
{
unsigned int i;
static unsigned int SoftStage=0;
DDRD|=0x7F; //PD0~PD6設(shè)置為輸出
PORTD&=0xE0; //PD0~PD4輸出設(shè)置為0,均無(wú)指示
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
DDRD&=0x7F; //PD7設(shè)置為輸入
PORTD|=0x80; //PD7上拉有效
DDRB&=0xCF; // PB4、PB5設(shè)置為輸入
PORTB|=0x30; // PB4、PB5上拉有效
DDRB&=0xFD; // PB1設(shè)置為輸入
PORTB|=0x02; // PB1上拉有效
initialization_ac(); //初始化模擬比較器
WDT_enable();
for(i=20000;i>0;i--)
{
delay();
WDR();
}
while(1)
{
while((PINB&0x30)==0x30) //無(wú)開(kāi)機(jī)信號(hào)
{
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
for(i=8000;i>0;i--)
{
delay();
WDR();
}
if((PINB&0x02)==0x02) //(PB1)有直流輸入
{
for(i=2;i>0;i--)
{
delay();
WDR();
}
state_checkinput_dc();
}
else //無(wú)直流輸入
{
PORTD&=0xE7; //PD3=0,PD4=0,清除直流顯示標(biāo)志
dcovervoltage_flag=0;
dcundervoltage_flag=0;
dcreundervoltage_flag=0;
dcreovervoltage_flag=0;
}
if((PIND&0x80)==0x80) //(PD7)有交流輸入
{
for(i=2;i>0;i--)
{
delay();
WDR();
}
state_checkinput_ac();
}
else //無(wú)交流輸入
{
PORTD&=0xFC; //PD0=0,PD1=0,清除交流顯示標(biāo)志
acovervoltage_flag=0;
acundervoltage_flag=0;
acreundervoltage_flag=0;
acreovervoltage_flag=0;
}
if(((dcundervoltage_flag||dcovervoltage_flag)||(acundervoltage_flag||acovervoltage_flag))==0)
{
PORTD&=0xFB; //PD2輸出設(shè)置為低電平,交直流輸入均為無(wú)故障
}
else
{
PORTD|=0x04; //PD2輸出設(shè)置為高電平,交直流輸入有一個(gè)有故障
}
}
/********************************************************************/
/********************************************************************/
while((PINB&0x30)!=0x30) //有開(kāi)機(jī)信號(hào),PB4、PB5不同時(shí)為1開(kāi)機(jī)
{
if(((PINB&0x02)==0x02)&&((PIND&0x80)!=0x80)) SoftStage=1;//當(dāng)前只有直流輸入
if(((PINB&0x02)!=0x02)&&((PIND&0x80)==0x80)) SoftStage=2;//當(dāng)前只有交流輸入
if(((PINB&0x02)==0x02)&&((PIND&0x80)==0x80)) SoftStage=3;//交直流都有輸入情況下
while(SoftStage==1)//當(dāng)前只有直流輸入
{
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
for(i=2;i>0;i--)
{
delay();
WDR();
}
if((PINB&0x02)==0x02) //如果有直流輸入,就判斷直流輸入
{
for(i=2;i>0;i--)
{
delay();
WDR();
}
PORTD&=0xFC; //PD0=0,PD1=0,清除交流顯示標(biāo)志
acovervoltage_flag=0;
acundervoltage_flag=0;
acreundervoltage_flag=0;
acreovervoltage_flag=0;
state_checkinput_dc();
}
else
{
PORTD&=0xE7; //清除直流顯示標(biāo)志
dcovervoltage_flag=0;
dcundervoltage_flag=0;
dcreundervoltage_flag=0;
dcreovervoltage_flag=0;
}
if((dcundervoltage_flag||dcovervoltage_flag)==0)
{
PORTD&=0xFB; //PD2輸出設(shè)置為低電平,交直流輸入均為無(wú)故障
}
else
{
PORTD|=0x04; //PD2輸出設(shè)置為高電平,交直流輸入有一個(gè)有故障
}
if(((dcundervoltage_flag||dcovervoltage_flag)||overcurrent[1])==0)
{
PORTD|=0x20; // PD5輸出設(shè)置為1,允許直流輸出
}
else
{
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
}
check_overcurrent();
WDR();
delay();
if(overcurrent[1]==1)
{
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
overcurrent[1]=1;
}
if(((PINB&0x02)==0x02)&&((PIND&0x80)==0x80)) SoftStage=3;//交直流都有輸入情況下
{
PORTD&=0xBF; //PD6輸出設(shè)置為0,允許AC/DC輸出
for(i=5000;i>0;i--) delay();
}
if((PINB&0x30)==0x30) break;
}
while(SoftStage==2)//當(dāng)前只有交流輸入
{
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
for(i=2;i>0;i--)
{
delay();
WDR();
}
if((PIND&0x80)==0x80) //如果有交流輸入,就判斷交流輸入
{
for(i=2;i>0;i--)
{
delay();
WDR();
}
PORTD&=0xE7; //PD3=0,PD4=0,清除直流顯示標(biāo)志
dcovervoltage_flag=0;
dcundervoltage_flag=0;
dcreundervoltage_flag=0;
dcreovervoltage_flag=0;
state_checkinput_ac();
}
else
{
PORTD&=0xFC; //清除交流顯示標(biāo)志
acovervoltage_flag=0;
acundervoltage_flag=0;
acreundervoltage_flag=0;
acreovervoltage_flag=0;
}
WDR();
if((acundervoltage_flag||acovervoltage_flag)==0)
{
PORTD&=0xFB; //PD2輸出設(shè)置為低電平,交直流輸入均為無(wú)故障
}
else
{
PORTD|=0x04; //PD2輸出設(shè)置為高電平,交直流輸入有一個(gè)有故障
}
if(((acundervoltage_flag||acovervoltage_flag)||overcurrent[0])==0)
{
PORTD&=0xBF;; //PD6輸出設(shè)置為0,允許AC/DC輸出
}
else
{
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
}
check_overcurrent();
WDR();
delay();
if(overcurrent[0]==1)
{
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
overcurrent[0]=0;
for(i=20000;i>0;i--)
{
delay();
WDR();
}
}
if(((PINB&0x02)==0x02)&&((PIND&0x80)==0x80)) SoftStage=3;//交直流都有輸入情況下
if((PINB&0x30)==0x30) break;
}
while(SoftStage==3)//當(dāng)前交直流一起輸入
{
PORTD&=0xDF; //PD5輸出設(shè)置為0,禁止直流輸出
for(i=2;i>0;i--)
{
delay();
WDR();
}
if((PINB&0x02)==0x02) //如果有直流輸入,就判斷直流輸入
{
for(i=2;i>0;i--)
{
delay();
WDR();
}
state_checkinput_dc();
}
else
{
PORTD&=0xE7; //清除直流顯示標(biāo)志
dcovervoltage_flag=0;
dcundervoltage_flag=0;
dcreundervoltage_flag=0;
dcreovervoltage_flag=0;
}
if((PIND&0x80)==0x80) //如果有交流輸入,就判斷交流輸入
{
for(i=2;i>0;i--)
{
delay();
WDR();
}
state_checkinput_ac();
}
else
{
PORTD&=0xFC; //清除交流顯示標(biāo)志
acovervoltage_flag=0;
acundervoltage_flag=0;
acreundervoltage_flag=0;
acreovervoltage_flag=0;
}
WDR();
if(((dcundervoltage_flag||dcovervoltage_flag)||(acundervoltage_flag||acovervoltage_flag))==0)
{
PORTD&=0xFB; //PD2輸出設(shè)置為低電平,交直流輸入均為無(wú)故障
}
else
{
PORTD|=0x04; //PD2輸出設(shè)置為高電平,交直流輸入有一個(gè)有故障
}
if(((acundervoltage_flag||acovervoltage_flag)||overcurrent[0])==0)
{
PORTD&=0xBF; //PD6輸出設(shè)置為0,允許AC/DC輸出
}
else
{
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
}
check_overcurrent();
WDR();
delay();
if(overcurrent[0]==1)
{
PORTD|=0x40; //PD6輸出設(shè)置為1,禁止AC/DC輸出
overcurrent[0]=0;
for(i=20000;i>0;i--)
{
delay();
WDR();
}
}
if(((PINB&0x02)==0x02)&&((PIND&0x80)!=0x80)) SoftStage=1;//當(dāng)前只有直流輸入
if(((PINB&0x02)!=0x02)&&((PIND&0x80)==0x80))
SoftStage=2;//當(dāng)前只有交流輸入
if((PINB&0x30)==0x30) break;
}
}
}
}