📄 znhkgdy.c
字号:
#include<absacc.h> /*绝对地址访问函数*/
#include<reg52.h>
#include<math.h> /*各种不同类型的数字函数*/
#define uchar unsigned char
#define uint unsigned int
uchar ee,aa,qian,bai,shi,ge,addres,strdata,da1,da2;
uchar protect,naturali,naturalvd,naturalvg,voltage;
uint i,j,l;
sbit P1_0=P1^0; //A/D,D/A转换端口定义。
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit P1_4=P1^4;
sbit P1_5=P1^5;
sbit P1_6=P1^6;
sbit P1_7=P1^7;
sbit dula=P2^0;//显示选择端口定义。
sbit wela=P2^1;
sbit s1=P2^3;//键盘端口定义。
sbit s2=P2^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
uchar code tablead[]={0x9e,0xde,0xae};
void delay(uint z); //延时子函数声明。
uchar adcadc(); //ad带返回值子函数。
void dcadac(unsigned long dacdata1,dacdata2);//da函数声明。
void display(uchar,uchar,uchar,uchar); //显示子函数声明。
void main()
{
s1=1; //当按s1时候电压降低。
s2=1; //当按s2时候电压升高。
da1=0x03; //da选择a通道输出,Vsense。
da2=0x07; //da选择b通道输出,Isense。
protect=0x999; //输出1v电压。
naturali=0x333; //输出0.5v电压。
naturalvd=0x666;
naturalvg=0xccc;
voltage=0x333; //设定初始化电压。
while(1)
{
addres=tablead[0]; //选择A/D通道1工作,检测输入电压(85v~264v)。
adcadc(); //启动A/D转换。
aa=strdata;
while(aa>0xf8d) //输入超265v,电路停止工作点。
dcadac(da2,protect); //调用输出子程序,输出到Isense大于1v电路保护不工作。
while(aa<0x51e) //输入欠压低于85v,电路停止工作点。
dcadac(da2,protect); //调用输出子程序,输出到Isense大于1v电路保护不工作。
addres=tablead[1]; //选A/D通道2工作,输入超功率最大值,电路短路判断。
adcadc();
aa=strdata;
while(aa>0x100) //超电流检测,判断输出短路。
dcadac(da2,protect); //调用输出子程序,输出到Isense大于1v电路保护不工作。
dcadac(da2,naturali);//判断电路为正常工作,另Isense输入电路正常,电路正常工作。
addres=tablead[2]; //选A/D择通道2工作。
adcadc();
aa=strdata; //转化为数码显示去显示程序。
qian=2500*aa/4096/1000; //电压显示十位。
bai=2500*aa/4096%1000/100; //电压显示个位。
shi=2500*aa/4096%100/10; //电压显示小数点后第一位。
ge=2500*aa/4096%10; //电压显示小数点后第二位。
display(qian,bai,shi,ge);//调用显示子程序,显示电压,精确到小数点后两位。
if(voltage>aa) //电压低于设定值。
dcadac(da1,naturalvd); //调节pwm使电压升高。
else //否则高于设定值,调节pwm使电压降低。
dcadac(da1,naturalvg);
if(aa<0x333) //输出电压小于5v。
{
voltage=0x333; //输出电压重置,5v。
display(0x77,0x77,0x77,0x77); //电压超限最低值输出全AAAA.
dcadac(da1,naturalvd); //调节pwm使电压升高。
}
if(aa>0xfff) //输出电压大于15v。
{
voltage=0x333; //输出电压重置,5v。
display(0x71,0x71,0x71,0x71); //电压超限最高值输出全ffff.
dcadac(da1,naturalvg);//调节pwm使电压降低。
}
if(s1==0) //s1被按下。
{
delay(5); //延时50ms,消抖。
if(s1==0) //确认s1确实被按下。
{
voltage=voltage-0x51; //电压下降0.25v.
if(voltage<0x333) //输出电压小于5v。
{
voltage=0x333; //输出电压重置,5v。
display(0x77,0x77,0x77,0x77); //电压超限最低值输出全AAAA.
delay(10);
}
}
while(!s1); //松手检测。
delay(5);
while(!s1);
}
if(s2==0) //s2被按下。
{
delay(5); //延时50ms,消抖。
if(s2==0) //确认s2确实被按下。
{
voltage=voltage+0x51; //电压上升0.25v.
if(voltage>0xfff) //输出电压大于15v。
{
voltage=0x333; //输出电压重置,5v。
display(0x71,0x71,0x71,0x71); //电压超限最高值输出全ffff.
delay(10);
}
}
while(!s2); //松手检测。
delay(5);
while(!s2);
}
}
}
void display(uchar qian,uchar bai,uchar shi,uchar ge)
{
dula=1;
P0=table[qian]; //显示电压十位。
dula=0;
P0=0xff; //消隐。
wela=1;
P0=0xfe; //选中第一个数码管亮。
wela=0;
delay(1); //延时。
dula=1;
P0=table[bai]+0x80; //显示电压个位,并且显示小数点。
dula=0;
P0=0xff;
wela=1;
P0=0xfd; //选中第二个数码管亮。
wela=0;
delay(1);
dula=1;
P0=table[shi]; //显示电压小数点后一位。
dula=0;
P0=0xff;
wela=1;
P0=0xfb; //选中第三个数码管亮。
wela=0;
delay(1);
dula=1;
P0=table[ge]; //显示电压小数点后第二位。
dula=0;
P0=0xff;
wela=1;
P0=0xf7; //选中第四个数码管亮。
wela=0;
delay(1);
}
void dcadac(unsigned long dacdata1,dacdata2)//dacdata1控制信号,dacdata2输出转换。
{
unsigned long xdata dacdatrfer=0;
P1_6=0;
P1=P1&0xdf; /*片选CS 置低电平*/
for(ee=0;ee<4;ee++)
{
P1_6=0;
P1=P1&0xef;
dacdatrfer=dacdata1;
dacdatrfer=((dacdatrfer>>(3-ee))&0x01)<<3;
P1=P1|dacdatrfer;
P1_6=1;
}
P1_6=0;
for(ee=0;ee<12;ee++)
{
P1_6=0;
P1=P1&0xef;
dacdatrfer=dacdata2;
dacdatrfer=((dacdatrfer>>(11-ee))&0x01)<<3;
P1=P1|dacdatrfer;
P1_6=1;
}
P1_6=0;
P1=P1|0x20;
}
/*该子程序可完成两路DAC 模拟电压输出,欲转换的12 位二进制数据已经分别存放于变
量dacdac1、dacdac2 中。*/
/*流量A/D 转换一次,其中P1-1 为片选端,P1-0 为时钟输入端,P1-2 为数据输入,P1-3
为数据输出*/
uchar adcadc()
{
uchar adcadrestrfer;
uchar adata[12];
P1_1=0;
P1_0=0;
//adress=0x9e; /*送控制命令字:启动、选择1 通道,单极性转化、单极性模拟输入方式*/
for(i=0;i<8;i++)
{
adcadrestrfer=addres;
adcadrestrfer=(adcadrestrfer>>(7-1))&0x01;
P1_3=adcadrestrfer; /*右移动1 次,以后送到P1-3口*/
P1_0=0; /*此处为送时钟信号*/
for(j=0;j<2;j++); /*空操作*/
P1_0=1;
for(j=0;j<2;j++);
P1_0=0; /*时钟信号周期等于等于4 条指令时间*/
}
P1_1=0;
for(j=0;j<6;j++);
P1_1=0;
strdata=0;
P1_0=1;
for(i=0;i<12;i++)
{
P1_0=0;
P1_0=1;
strdata=P1_2; //读出串行12 位数据
strdata=strdata<<(11-l);
adata[j]=adata[j]|strdata;
}
strdata=adata[j];
for(j=0;j<4;j++)
{
P1_0=0;
P1_0=1;
}
P1_1=1;
return strdata;
} /*该子程序完成A/D 变换,结果存放在变量strdata中返回*/
void delay(uint z) //延时子程序。
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -