|
//陳永飛于2016年3月28號寫的數控電源,上電初始電壓是3V
//采用ATMEGA8芯片做的,四位數碼管顯示電壓值,調節范圍是1.8V到12V之間
//采用開關穩壓芯片LM2576ADJ做的降壓,效率高達77%,電流最大3A,誤差電壓為正負0.2V
#include<avr/io.h>
#include<avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define duan PORTD
uchar const tab[]={ 0xC0,/*0*/
0xF9,/*1*/
0xA4,/*2*/
0xB0,/*3*/
0x99,/*4*/
0x92,/*5*/
0x82,/*6*/
0xF8,/*7*/
0x80,/*8*/
0x90,/*9*/
};
uint DY=30; //30就是為3.0V電壓,用于設定電壓
uint AD_shu,tiao_shu; //一個用于保存ADC轉換后的數,一個用于運算比較
void delay(uint k)
{
for(;k>0;k--);
}
void init()
{
DDRD=0xff; //D端口全為輸出
PORTD=0;
DDRC=0xfc; //C端口低兩位用于ADC,高四位用于數碼管位選
PORTC=0x0; //C端口輸出全0
DDRB=0x07; //定義PB口的低三位為輸出,PB1為PWM輸出信號
PORTB=0xf8; //低三位輸出0,高五位加上拉電阻
TCCR1A=0X63; //設置PWM比較匹配器
TCCR1B=0X13; //設置PWM比較匹配器
OCR1A=250; //裝PWM寄存器的高位比較值
OCR1B=10; //裝PWM寄存器的低位比較值,開啟后自加,達到高位時,PB1端口取反
ADMUX=0xc0; //ADC選通道0,并且用內部的2.56V參考電壓,數據右對齊
ADCSRA=0xac; //ADC是連續轉換,并且16分頻,并且開了中斷
}
void desplay(uint dian_ya)
{
duan=tab[dian_ya/100]; //顯示十位電壓
PORTB|=0x04; //PC2為位選
delay(400);
PORTB&=0xfb;
duan=tab[dian_ya%100/10]&0x7f; //顯示個位電壓,并點亮小數點
PORTB|=0x08; //PC3為位選
delay(400);
PORTB&=0xf7;
duan=tab[dian_ya%10]|0x80; //顯示小數位電壓,并滅小數點
PORTB|0x10; //PC4為位選
delay(400);
PORTB&=0xef;
duan=tab[11]; //用于設定時點亮
PORTB|=0x20; //PB5為位選
delay(400);
PORTB&=0xdf;
}
void key()
{
if(!(PINB&0x08)) //PB3為加電壓按鍵
{
delay(5000);
if(!(PINB&0x08))
{
DY++;
if(DY>120)DY=120;
}
}
if(!(PINB&0x10)) //PB4為減電壓按鍵
{
delay(5000);
if(!(PINB&0x10))
{
DY--;
if(DY<18)DY=18;
}
}
}
int main()
{
uchar i=1;
init();
ADCSRA|=0x40; //開始ADC轉換
while(1)
{
key();
tiao_shu=(uint)(((float)AD_shu)/8.5); //計算ADC采樣后的數進行電阻分壓后的實際數據轉換補常
if(tiao_shu>(DY+2)) i--; //如果采樣轉換后數值大于設定值,就減小PWM脈寬(設定值加2是電壓誤差值)
if(tiao_shu<(DY-2)) i++; //如果采樣轉換后數值小于設定值,就加大PWM脈寬(設定值減2是電壓誤差值)
delay(20); //延時
OCR1B=i; //裝入PWM寄存器
desplay(DY);
}
}
SIGNAL(SIG_ADC)
{
AD_shu=ADCL;
AD_shu|=(uint)(ADCH<<8);
}
|
|