交直流电源转换
扫描二维码
随时随地手机看文章
--------------------------------------------------
#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;
//直流过压标志 交流过压标志 直流欠压标志 交流欠压标志
unsigned char dcreovervoltage_flag=0,acreovervoltage_flag=0,dcreundervoltage_flag=0,acreundervoltage_flag=0;
//直流过压恢复标志 交流过压恢复标志 直流欠压恢复标志 交流欠压恢复标志
static unsigned char overcurrent[2]={0,0};
//---------------------------------------------------------
//---------------------------------------------------------
/*使能看门狗*/
void WDT_enable(void)
{
WDTCR|=0x08; //Allow change,WDT enable
WDTCR|=0x0F; //Set reset time,2.1S.
}
//---------------------------------------------------------
//---------------------------------------------------------
/*自定义延时程序*/
void delay(void)
{
unsigned char i;
for(i=2;i>0;i--);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*初始化模拟比较器*/
void initialization_ac()
{
SFIOR|=0x08; //使能模拟比较器多工输入
ACSR&=0x3F; //使能模拟比较器,利用外部基准,关闭中断
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流过压检测程序*/
unsigned char dc_overvoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8; //选择通道0,直流过压检测
delay(); //转换延迟,等待转化结果
ACSR=0x10;
if(ACSR==0x00) //条件成立,直流过压
{
PORTD&=0xDF; //PD5输出设置为0,禁止直流输出
PORTD&=0xF7; // PD3输出低电平
PORTD|=0x10; //PD4输出高电平,说明直流输入异常
value=1;
}
else //直流没有过压
{
PORTD|=0x08; // PD3输出高电平,输入正常
PORTD&=0xEF; //PD4输出低电平,输入正常
value=0;
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流过压恢复检测程序*/
void dc_reovervoltage(void)
{
if(dcovervoltage_flag==1) //条件成立,说明过压,需要检测恢复
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8; //选择通道1,直流过压恢复检测
ADMUX|=0x01;
delay(); //转换延迟,等待转化结果。
ACSR=0x10;
if(ACSR==0x20) //条件成立,说明过压恢复
{
PORTD|=0x08; // PD3输出高电平,输入正常
PORTD&=0xEF; //PD4输出低电平,输入正常
dcovervoltage_flag=0;
}
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流欠压检测程序*/
unsigned char dc_undervoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8; //选择通道2,直流欠压检测
ADMUX|=0x02;
delay(); //转换延迟,等待转化结果
ACSR=0x10;
if(ACSR==0x20) //条件成立,直流欠压
{
PORTD&=0xDF; //PD5输出设置为0,禁止直流输出
PORTD&=0xF7; // PD3输出低电平
PORTD|=0x10; //PD4输出高电平,说明直流输入异常
value=1;
}
else //直流没有欠压
{
PORTD|=0x08; // PD3输出高电平,输入正常
PORTD&=0xEF; //PD4输出低电平,输入正常
value=0;
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*直流欠压恢复检测程序*/
void dc_reundervoltage(void)
{
if(dcundervoltage_flag==1) //条件成立,说明过压,需要检测恢复
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8; //选择通道3,直流欠压恢复检测
ADMUX|=0x03;
delay(); //转换延迟,等待转化结果。
ACSR=0x10;
if(ACSR==0x00) //条件成立,说明欠压恢复
{
PORTD|=0x08; // PD3输出高电平,输入正常
PORTD&=0xEF; //PD4输出低电平,输入正常
dcundervoltage_flag =0;
}
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流过压检测程序*/
unsigned char ac_overvoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8;
ADMUX|=0x04; //选择通道4,交流过压检测
delay(); //转换延迟,等待转化结果
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x00) //条件成立,交流过压
{
PORTD|=0x40; // PD6输出设置为1,禁止AC/DC输出
PORTD|=0x02; //PD1输出高电平,说明交流输入异常
PORTD&=0xFE; // PD0输出低电平
value=1;
}
else //交流没有过压
{
PORTD|=0x01; // PD0输出高电平,输入正常
PORTD&=0xFD; // PD1输出低电平,输入正常
value=0;
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流过压恢复检测程序*/
void ac_reovervoltage(void)
{
if(acovervoltage_flag==1) //条件成立,说明过压,需要检测恢复
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8;
ADMUX|=0x05; //选择通道5,交流过压恢复检测
delay(); //转换延迟,等待转化结果。
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x20) //条件成立,说明过压恢复
{
PORTD|=0x01; // PD0输出高电平,输入正常
PORTD&=0xFD; // PD1输出低电平,输入正常
acovervoltage_flag=0;
}
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流欠压检测程序*/
unsigned char ac_undervoltage(void)
{
unsigned char value;
ADCSRA&=0x7F; // ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8;
ADMUX|=0x06; //选择通道6,交流欠压检测
delay(); //转换延迟,等待转化结果
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x20) //条件成立,交流欠压
{
PORTD|=0x40; // PD6输出设置为1,禁止AC/DC输出
PORTD|=0x02; //PD1输出高电平,说明交流输入异常
PORTD&=0xFE; // PD0输出低电平
value=1;
}
else //交流没有欠压
{
PORTD|=0x01; // PD0输出高电平,输入正常
PORTD&=0xFD; // PD1输出低电平,输入正常
value=0;
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
return(value);
}
//---------------------------------------------------------
//---------------------------------------------------------
/*交流欠压恢复检测程序*/
void ac_reundervoltage(void)
{
if(acundervoltage_flag==1) //条件成立,说明过压,需要检测恢复
{
ADCSRA&=0x7F; //ADCSRA的ADEN位(位7)为0时,打开多路复用器,ADC多路复用器为模拟比较器选择负极输入
ADMUX&=0xF8; //选择通道7,交流欠压恢复检测
ADMUX|=0x07;
delay(); //转换延迟,等待转化结果。
delay();
delay();
delay();
delay();
ACSR=0x10;
if(ACSR==0x00) //条件成立,说明欠压恢复
{
PORTD|=0x01; // PD0输出高电平,输入正常
PORTD&=0xFD; // PD1输出低电平,输入正常
acundervoltage_flag=0;
}
ADCSRA|=0x80; //关闭多路复用器,模拟比较器选择负极输入
}
}
//---------------------------------------------------------
//---------------------------------------------------------
/*过流检测程序*/
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; //交流输出过流
PORTD|=0x40; //PD6输出设置为1,禁止AC/DC输出
PORTD&=0xDF; //PD5输出设置为0,禁止直流输出
}
if((PINB&0x02)==0x02)
{
overcurrent[1]=1;
PORTD&=0xDF; //PD5输出设置为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设置为输出
PORTD&=0xE0; //PD0~PD4输出设置为0,均无指示
PORTD&=0xDF; //PD5输出设置为0,禁止直流输出
PORTD|=0x40; //PD6输出设置为1,禁止AC/DC输出
DDRD&=0x7F; //PD7设置为输入
PORTD|=0x80; //PD7上拉有效
DDRB&=0xCF; // PB4、PB5设置为输入
PORTB|=0x30; // PB4、PB5上拉有效
DDRB&=0xFD; // PB1设置为输入
PORTB|=0x02; // PB1上拉有效
initialization_ac(); //初始化模拟比较器
WDT_enable();
for(i=20000;i>0;i--)
{
delay();
WDR();
}
while(1)
{
while((PINB&0x30)==0x30) //无开机信号
{
PORTD&=0xDF; //PD5输出设置为0,禁止直流输出
PORTD|=0x40; //PD6输出设置为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 //无直流输入
{
PORTD&=0xE7; //PD3=0,PD4=0,清除直流显示标志
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 //无交流输入
{
PORTD&=0xFC; //PD0=0,PD1=0,清除交流显示标志
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输出设置为低电平,交直流输入均为无故障
}
else
{
PORTD|=0x04; //PD2输出设置为高电平,交直流输入有一个有故障
}
}
/********************************************************************/
/********************************************************************/
while((PINB&0x30)!=0x30) //有开机信号,PB4、PB5不同时为1开机
{
if(((PINB&0x02)==0x02)&&((PIND&0x80)!=0x80)) SoftStage=1;//当前只有直流输入
if(((PINB&0x02)!=0x02)&&((PIND&0x80)==0x80)) SoftStage=2;//当前只有交流输入
if(((PINB&0x02)==0x02)&&((PIND&0x80)==0x80)) SoftStage=3;//交直流都有输入情况下
while(SoftStage==1)//当前只有直流输入
{
PORTD|=0x40; //PD6输出设置为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,清除交流显示标志
acovervoltage_flag=0;
acundervoltage_flag=0;
acreundervoltage_flag=0;
acreovervoltage_flag=0;
state_checkinput_dc();
}
else
{
PORTD&=0xE7; //清除直流显示标志
dcovervoltage_flag=0;
dcundervoltage_flag=0;
dcreundervoltage_flag=0;
dcreovervoltage_flag=0;
}
if((dcundervoltage_flag||dcovervoltage_flag)==0)
{
PORTD&=0xFB; //PD2输出设置为低电平,交直流输入均为无故障
}
else
{
PORTD|=0x04; //PD2输出设置为高电平,交直流输入有一个有故障
}
if(((dcundervoltage_flag||dcovervoltage_flag)||overcurrent[1])==0)
{
PORTD|=0x20; // PD5输出设置为1,允许直流输出
}
else
{
PORTD&=0xDF; //PD5输出设置为0,禁止直流输出
}
check_overcurrent();
WDR();
delay();
if(overcurrent[1]==1)
{
PORTD&=0xDF; //PD5输出设置为0,禁止直流输出
overcurrent[1]=1;
}
if(((PINB&0x02)==0x02)&&((PIND&0x80)==0x80)) SoftStage=3;//交直流都有输入情况下
{
PORTD&=0xBF; //PD6输出设置为0,允许AC/DC输出
for(i=5000;i>0;i--) delay();
}
if((PINB&0x30)==0x30) break;
}
while(SoftStage==2)//当前只有交流输入
{
PORTD&=0xDF; //PD5输出设置为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,清除直流显示标志
dcovervoltage_flag=0;
dcundervoltage_flag=0;
dcreundervoltage_flag=0;
dcreovervoltage_flag=0;
state_checkinput_ac();
}
else
{
PORTD&=0xFC; //清除交流显示标志
acovervoltage_flag=0;
acundervoltage_flag=0;
acreundervoltage_flag=0;
acreovervoltage_flag=0;
}
WDR();
if((acundervoltage_flag||acovervoltage_flag)==0)
{
PORTD&=0xFB; //PD2输出设置为低电平,交直流输入均为无故障
}
else
{
PORTD|=0x04; //PD2输出设置为高电平,交直流输入有一个有故障
}
if(((acundervoltage_flag||acovervoltage_flag)||overcurrent[0])==0)
{
PORTD&=0xBF;; //PD6输出设置为0,允许AC/DC输出
}
else
{
PORTD|=0x40; //PD6输出设置为1,禁止AC/DC输出
}
check_overcurrent();
WDR();
delay();
if(overcurrent[0]==1)
{
PORTD|=0x40; //PD6输出设置为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)//当前交直流一起输入
{
PORTD&=0xDF; //PD5输出设置为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; //清除直流显示标志
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; //清除交流显示标志
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输出设置为低电平,交直流输入均为无故障
}
else
{
PORTD|=0x04; //PD2输出设置为高电平,交直流输入有一个有故障
}
if(((acundervoltage_flag||acovervoltage_flag)||overcurrent[0])==0)
{
PORTD&=0xBF; //PD6输出设置为0,允许AC/DC输出
}
else
{
PORTD|=0x40; //PD6输出设置为1,禁止AC/DC输出
}
check_overcurrent();
WDR();
delay();
if(overcurrent[0]==1)
{
PORTD|=0x40; //PD6输出设置为1,禁止AC/DC输出
overcurrent[0]=0;
for(i=20000;i>0;i--)
{
delay();
WDR();
}
}
if(((PINB&0x02)==0x02)&&((PIND&0x80)!=0x80)) SoftStage=1;//当前只有直流输入
if(((PINB&0x02)!=0x02)&&((PIND&0x80)==0x80))
SoftStage=2;//当前只有交流输入
if((PINB&0x30)==0x30) break;
}
}
}
}