使用ATmega32编写交直流双电源无缝切换,输入过欠压保护,输出过流保护。主要使用了单片机自带的比较器功能,比较器的一端使用了LT431制作的2.5V基准源。
--------------------------------------------------
#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;