|
|
楼主 |
发表于 2016-12-31 18:25:04
|
显示全部楼层
下面是程序,还需要改进,请大家多多指教
#include<reg51.h>
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
/****************************************************/
sbit A=P3^1;
sbit b=P1^7;
sbit C=P3^2;
sbit D=P3^4;
sbit E=P3^5;
sbit F=P3^0;
sbit G=P1^4;
sbit H=P3^3; //小数点
sbit D1=P1^5; //第一位
sbit D2=P1^0; //第二位
sbit D3=P1^2; //第三位
sfr P1M0=0x91; //IO口控制寄存器
sfr P1M1=0x92; //IO口控制寄存器
sfr P3M0=0xb1;
sfr P3M1=0xb2;
sfr ADC_CONTR=0xc5; //ADC控制寄存器
sfr ADC_DATA=0xc6;
sfr ADC_LOW2=0xbe;
sfr AUXR=0x8e;
/****************************************************/
u8 w,t,tt;
u8 vf; //负电压
u16 a; //电流
u32 r,v,u; //参考 测量 显示电压
u8 d[4]; //3位数字
u16 ad[4]; //3个AD值
/****************************************************/
//软件延时函数
void delay2ms() //@6.0MHz 2ms
{
u8 i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void delay_ms(u8 i)
{
while(i--)
delay2ms();
}
void shuju() //数据处理
{
r=ad[3]; //基准电压
v=ad[2]; //测量电压
a=ad[1]; //电流检测
if(v<r)v=r-v,vf=1; //测量电压为负
else v=v-r,vf=0; //测量电压为正
u=1000*v/r; //测量电压换算
//基准电压1.5V,量程10V,分压电阻22K+3.9K
if(u>999)
{
d[1]=10;
d[2]=10;
d[3]=10;
}
else
{
d[1]=u/100;
d[2]=u%100/10;
d[3]=u%10;
}
}
/******************************************************/
void zifu(u8 n) //字符显示
{
switch(n) //笔画控制(共阳数码管)
{
case 0:A=0;b=0;C=0;D=0;E=0;F=0;G=1;break;
case 1:A=1;b=0;C=0;D=1;E=1;F=1;G=1;break;
case 2:A=0;b=0;C=1;D=0;E=0;F=1;G=0;break;
case 3:A=0;b=0;C=0;D=0;E=1;F=1;G=0;break;
case 4:A=1;b=0;C=0;D=1;E=1;F=0;G=0;break;
case 5:A=0;b=1;C=0;D=0;E=1;F=0;G=0;break;
case 6:A=0;b=1;C=0;D=0;E=0;F=0;G=0;break;
case 7:A=0;b=0;C=0;D=1;E=1;F=1;G=1;break;
case 8:A=0;b=0;C=0;D=0;E=0;F=0;G=0;break;
case 9:A=0;b=0;C=0;D=0;E=1;F=0;G=0;break;
case 10:A=0;b=1;C=1;D=0;E=0;F=0;G=0;break; //E
}
}
/**********显示函数*****************************************/
void xianshi()
{
if(t==1)
{zifu(d[1]);
D1=1; //显示第一位 4ms
H=0; //小数点
}
if(t==5)
{D1=0; //1ms间歇
H=1;
}
if(t==6)
{zifu(d[2]);
D2=1; //显示第二位
}
if(t==10)D2=0;
if(t==11)
{zifu(d[3]);
D3=1; //显示第三位
if(vf==1) //测量电压为负
H=0; //末尾小数点显示(使电路简化)
}
if(t==15)
{D3=0; H=1;}
if(t>15)t=0;
}
/****************************************************/
void initial()
{
ADC_CONTR=0x80; //ADC上电
P1M0=0x4a; //配置IO口为ADC输入
P1M1=0x25; //配置IO口为推挽模式
AUXR=0x10; //允许ADC中断
TMOD=0x01; //定时器T0为16位
delay_ms(5); //等待ADC稳定
IE=0xa2; //启用ADC转换和定时器TR0
}
/****************************************************/
main()
{
delay_ms(200); //开机延时
initial();
ADC_CONTR=0x88; //准备AD转换
TR0=1;
while(1)
{
xianshi();
if(tt>250)
{tt=0;shuju();}
}
}
/****************************************************/
void et0()interrupt 1
{
TH0=0xfe,TL0=0x0c; //定时1ms @6.0MHz
t++;tt++; //次数累加
}
/****************************************************/
void adc_spi()interrupt 5 //轮流测量AD值
{
if(tt==100)
{
w++;
ad[w]=ADC_DATA,ad[w]<<=2,ad[w]+=ADC_LOW2; //每通道AD值(10位)
switch(w)
{
case 1:ADC_CONTR=0x8b;break; //p1^3通道AD转换
case 2:ADC_CONTR=0x8e;break; //p1^6通道AD转换
case 3:ADC_CONTR=0x89; //p1^1通道AD转换
w=0;break;
}
}
}
|
| |