?? 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 + -