|
求高手帮我修改一下这个数控直流稳压电源, 问题是 精度不够高 采集的电流没有显示
proteus仿真图 (原文件名:数控稳压电源.jpg)
系统框图 (原文件名:数控稳压电源系统框图.jpg)
下面是程序:
#include<reg52.h>
#include<stdio.h>
#include<intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define _nop()_nop_()
#define DAT P0
uchar go;
sbit K1=P3^1;//第一个键
sbit K2=P3^2;//第二个键
sbit K3=P3^3;//第三个键
sbit WR2=P3^0;//DAC的控制端
//位定义
#define Lcd_Data P0 //定义数据端口
sbit RS=P2^0;//定义连接端口
sbit RW=P2^1;
sbit E=P2^2;
sbit Busy=P0^7;
bit hold=0;
bit _Int=0;
bit k=0;
bit m=0;
bit fushu=0;
bit q=0;
//全局变量定义
uint DAdat;//存放送到DA的数据
uint x;
uchar ADdat; //存放从ADC读出的数据
uchar vol;//存放输入电压值
uchar keynum;
uchar kyreg;
uchar temp;//存放功能状态
uchar hh;
//数组定义
static code uchar Disp[] ="0123456789-";
static code uchar Disp2[]="Error! ";
static code uchar Disp3[]="Vol is:";
//函数声明
uchar keyread(void);//读键函数
uchar keyread2(void);//读键函数2
uchar keyread3(void);//读键函数3
void reADC(void);//AD反馈读数函数
uchar cmp(uchar ADdat,uchar DAdat);//反馈比较函数
void lcdinit(); //LCD初始化函数
void lcdcmd(uchar cmd);//LCD写控制字函数
void lcddata(uchar dat);//LCD写数据函数
void seDAC(uchar DAdata);//DAC送数函数
void delay(uchar t);//延时函数
void extint(void);
void volchange();//输出电压自增自减函数
/***********DAC送数*******************/
main() //主程序
{
unsigned int vol;
uchar i,j,l=0,a=0,b=0,e=0;
bit dian=0;
bit o=0,p=0;//负数标志位、确认标志位
delay(255);
EA=1;
EX0=1;
PX0=1;
IT0=1;
//EX1=1;
//IT1=1;
pp:
a=b=0;dian=0;o=p=0,x=0;
P1=0;
lcdinit();
lcdcmd(0x80);
for(j=0;j<7;j++) //开机送0V并显示到LCD
{
lcddata(Disp3[j]);
}
seDAC(128);
DAdat=128;
lcddata('0');
lcddata('0');
lcddata('.');
lcddata('0');
lcddata('V');
while(1)
{
while(!k)
{ delay(200);
i=keyread();
if(!m)
{
lcdcmd(0x1);
for(j=0;j<7;j++)
lcddata(Disp3[j]);
m=1;
}
else if(i==11){m=0;goto pp;} //复位
else if(i==12){temp=1;k=1;q=!q;hh=1;;} //加一
else if(i==13){temp=2;k=1;q=!q;hh=1;;} //减一
}
if(vol>150)
{
lcdcmd(0x01);
delay(2);
lcdcmd(0x80);
for(i=0;i<16;i++)
lcddata(Disp2);
p=1; //溢出标志,P=1溢出
}
if(!fushu&&!hh) //送入DAC的数字量
{
DAdat=256*vol/150+128;
if(DAdat==512)
DAdat=511;hh=0;
}
else if(fushu&&!hh)
{
DAdat=256-256*vol/150;fushu=0;
hh=0;
}
if((temp==0)&&(!p))seDAC(DAdat); //函数调用
else if(temp==1){volchange();seDAC(DAdat);keyread2();temp=0;}
else if(temp==2){volchange();seDAC(DAdat);keyread3();temp=0;}
p=0;
k=0;
}
}
/******************输出电压自增自减程序******************/
void volchange()
{ uchar i,a,b,c,y,z;
if(temp==1&&(DAdat<511))
{
if(q)
{
if(z==9){DAdat+=3;z=0;} //进位
else DAdat+=2;
}
else DAdat+=3;
z++;
if(DAdat>=129)
{x=x+1;
lcdcmd(0x01);
for(i=0;i<7;i++)
lcddata(Disp3);
c=x/100,a=x%100/10;b=x%10;//一位小数、个位、十位的运算
lcdcmd(0x01);
for(i=0;i<7;i++)
lcddata(Disp3); //电压显示
lcddata(Disp[c]);
lcddata(Disp[a]);
lcddata('.');
lcddata(Disp);
lcddata('V');
}
}
else if(temp==2&&(DAdat>1))
{
if(q)
{
if(y==9){DAdat-=3;y=0;} //借位
else DAdat-=2;
}
else DAdat-=3;
y++;
if(DAdat>127)
{ x=x-1;
c=x/100,a=x%100/10;b=x%10; //一位小数、个位、十位的运算
lcdcmd(0x01);
for(i=0;i<7;i++)
lcddata(Disp3);//电压显示
lcddata(Disp[c]);
lcddata(Disp[a]);
lcddata('.');
lcddata(Disp);
lcddata('V');
}
}
hh=0;
}
/*******************DAC送数***********************/
void seDAC(uchar DAdat)
{
WR=1;
_nop_();
_nop_();
DAT=DAdat;
WR=0;
_nop_();
_nop_();
WR=1;
}
//***********************读键值*************
uchar keyread()
{
uchar kysta=1; //按键标志,kysta=1无按键
while(kysta) //锁定P3口低三位
{
P3=0x0e;
kyreg=P3;
if(kyreg!=0x0e)
{
delay(20);
kyreg=P3;
if(kyreg!=0x0e)
{
if(kyreg==0x0c) return 11; //第一个键
if(kyreg==0x0a) return 12; //第二个键
if(kyreg==0x06) return 13; //第三个键
}
}
while(kyreg!=0x0e) //键复位
{
P3=0x0e;
kyreg=P3;
}
}
}
uchar keyread2()
{
if(K2==0) //KEY2键实现数据增加
{
WR2=1;
delay(50);
WR2=0;
if(K2==0) //第二个键按下
delay(50);
//P1口数值加一
P1=go;
go++;
while(!K2);
}
}
uchar keyread3()
{
if(K3==0) //KEY3键实现数据减少
{
WR2=1;
delay(50);
WR2=0;
if(K3==0) //第三个键按下
delay(50);
P1=go;
go--;//P1口数值减1
while(!K3);
}
}
/************************延时**********************/
void delay(uchar t)
{
uchar i=100;
while(t--)
{while(i--);}
}
void delay1(uchar time)
{
while(time--);
}
/************************LCD驱动*******************/
//写控制字函数
void lcdcmd(uchar cmd)
{
RS=0;
RW=0;
DAT=cmd;
E=1;
_nop_();
_nop_();
E=0;
delay(2);
}
//写数据函数
void lcddata(uchar dat)
{
RS=1;
RW=0;
DAT=dat;
_nop_();
E=1;
_nop_();
_nop_();
E=0;
delay(2);
}
//LCD初始化函数
void lcdinit() //显示初始化
{
lcdcmd(0x38);
delay(2);
lcdcmd(0x38);
delay(2);
lcdcmd(0x38);
delay(2);
lcdcmd(0x01);
lcdcmd(0x06);
lcdcmd(0x0c);
}
/*********************ADC反馈函数*********************/
void reADC() interrupt 2 using 1
{
uchar result;
bit state;
DAT=0xff;
ADdat=DAT;
_nop_();
_nop_();
if(ADdat>=DAdat) //输出值大于显示值
{
result=ADdat-DAdat; //输出值减显示值
state=0;
}
else
{
result=DAdat-ADdat;//显示值减输出值
state=1;
}
if(result>=2)
{
result/=2;
if(state) result=DAdat-result;
else
result=DAdat+result;
}
else result=DAdat;
_Int=1;
}
/******************反馈比较****************/
uchar cmp(uchar x,uchar y)
{
uchar result;
bit state;
if(x>=y)
{
result=x-y;
state=0;
}
else
{
result=y-x;
state=1;
}
if(result>=2)
{
result/=2;
if(state) result=y-result;
else result=y+result;
}
else result=y;
return(result);
} |
|