您的当前位置:首页基于ADC0809的电压表设计

基于ADC0809的电压表设计

来源:小侦探旅游网
基于单片机的万用表设计原理

此项目由我们专业几个人合作完成,学习电子设计初期经历了不少困难,现在展示与网上供兴趣爱好者查阅。本团队承接电气工程及其自动化专业毕业设计,望广大朋友们支持,假如有意者加QQ:1396654916祥聊,或者发到我QQ邮箱1396654916@qq.com

此次设计是运用STC89RC52单片机、ADC0804、555定时器制作万用表,可以初略测量交流、直流的电压、电流;电阻;电容。

1ADC0804部分

用ADC0804采集电压信号,参考电压为2.5V输入到ADC0804,把被测电压将输入到芯片Vin+和Vin-上,通过运算即可得到电压测量值。

ADC0804连接电路如图

2直流电压测量

电路图

运算法则:5 V量程 a=AD_change();volts_dc=a*(2*Vref/256.0); 5 V量程 b=AD_change();volts_dc=b*(2*Vref*10.0/256.0); 3直流电流部分

电流测量电路

运算法则:

5mA量程 c=AD_change();current_dc=c*(2*Vref/256.0); 5mA量程 d=AD_change();current_dc=d*(2*Vref*10.0/256.0); 3交流电压的测量

交流电压的测量比较复杂,笔者进行了诸多的实验,最终觉得采用交流采样法比较好,主要是误差较小。测量原理:把输入的交流电压通过半波或全波整流后进行AD采样,本设计采用半波整流,对多次采集的数据进行求和,对采样的数据求平均值,最后把平均值送到LCD1602显示数据,就得到交流电压的有效值Ualue=Uave-0.7.

假如需要测量交流电压的峰值,即在整流二极管够串联一个电容,采集电容两端的电压即可(由于二极管的单向导电性,电容充满电后不能放电,即为脉动电压的峰值)

交流电压连接图 算法:

3V 量程 volts_ac=(sum/Count*(Vref/256.0))*2-0.7; 30V量程 volts_ac=(sum/Count*(10.0*Vref/256.0))*2-0.7; 0. 7V为整流管的压降(0.7)

4交流电流

测量原理和测量交流电压类似。原理图如下

算法

5mA量程: current_ac=sum/Count*(2*Vref/256.0)-0.7; 50mA量程: current_ac=sum/Count*(2*10.0*Vref/256.0)-0.7;

5电阻的测量

电阻的测量采用的事比例法,原理为:

Vin/Vref=Rx/R0;

由ADc0804的特性得:当Vin=Vref时,AD输出128;由此得到当R0=1K时Rx=1K;所以Rx=2*AD_Ave*R0/256;以此类推。

这种测量电阻的方法采用外部电源供电;需要把前面AD系统给参考电压置0。 电路如图所示

算法

2K量程 Res_value=AD_Ave*2/256.0; 200K量程 Res_value= AD_Ave*200/256.0;

6电容的测量

测量电容不用ADC0804,采用555定时器,利用直接反馈型无稳电路产生方波。用单片机测量方波的周期(定时器0),通过周期计算电容值

测量电路

计算公式:

量程200UF

float Capacitandc_Cycle200UF() {

static float Cycle=0,Count=0,sum=0,ave=0; unsigned char i; for(i=0;i<10;i++) {

WaveInput=1; TL0=0; TH0=0;

T0IntCount=0; TR0=0; while(WaveInput==0); while(WaveInput==1); while(WaveInput==0); TR0=1;

while(WaveInput==1); while(WaveInput==0); TR0=0;

Cycle=(T0IntCount*65536+TH0*256+TL0)/1000.0; Count=(Cycle*33.0)/10.0; sum=Count+sum; }

ave=sum/10.0;sum=0; return (ave); }

变量WaveInput为P3^5 I/O口。

式Count=(Cycle*33.0)/10.0;中。Count单位uF;Cycle单位ms;10为电阻值10K。33.0为常数。

R19为2UF量程,由于找不到10欧姆电阻才用15欧姆的。

程序代码:由几个子程序组成 多用表.c文件: #include \"reg52.h\" #include \"AD_change.h\"

#include \"display.h\" #include \"shift_key.h\" #include \"function.h\" #include \"key-scan.h\"

void Lcd_init()

{ Lcden=0; Write_com(0x38); Write_com(0x0c); Write_com(0x06); Write_com(0x01); }

void Time_init_capacitandce() {

TMOD=0x01; EA=1;ET0=1; TL0=0; TH0=0; WaveInput=1;

}

void main() {

Lcd_init();

Time_init_capacitandce();

while(1) {

Key_scan(); } }

void Time0() interrupt 1 {

T0IntCount++; TL0=0; TH0=1; }

Display.h文件

sbit Lcdrs =P3^0; //sbit Lcdwr =P3^1; sbit Lcden =P3^2;

//

1602初始化

// 脉冲引脚液晶数据口

unsigned char code table_dat[]={\"0123456789.\ // 显示数组

void delayms(unsigned char n)

{

static unsigned char i;

for(;n>0;n--) for(i=110;i>0;i--); }

void Write_com(unsigned char com) {

Lcdrs=0;Lcdwr=0; P2=com;delayms(5);

//定义数据口

Lcden=1;delayms(5);Lcden=0;

}

void Write_data(unsigned char Data) { Lcdrs=1;

P2=Data;delayms(5);

//数据输出

Lcden=1;delayms(5);Lcden=0;

}

void Lcd_display(float display_Data)

//

{

unsigned int afloat,aint; static unsigned char Buf[8];

aint=display_Data/1;

afloat=(display_Data-aint)*1000;

for(i=3;i>0;i--) {

Buf[i]=aint%10; aint/=10; }

for(i=7;i>4;i--) {

Buf[i]=afloat%10; afloat/=10; }

// 5ms延时 显示

Buf[4]=10;

for(i=1;i<8;i++) {

Write_com(0x80+i);

Write_data(table_dat[Buf[i]]); } }

AD.h文件

sbit AD_wr =P3^6;

sbit AD_rd =P3^5;

unsigned int i,Count,temp,sum; unsigned char Collection_flag;

float AD_change() {

static unsigned char Data;

AD_wr=1; AD_wr=0; AD_wr=1; while(INT1==1); // P1=0xff;

AD_rd=0; Data=P1; AD_rd=1;

return (Data);

}

void Volts_adchange() {

static unsigned char Data;

AD_wr=1; AD_wr=0; AD_wr=1; while(INT1==1); P1=0xff;

AD_rd=0; Data=P1; AD_rd=1; // P1 sum=sum+Data; Count++;

}

Shift.h文件

#define Vref (4.56)

//AD数据口

等待AD转换 //清空P1口 // P1为ad输出数据 //等待AD转换 //清空P1口

为ad输出数据

sbit WaveInput =P3^7;

float volts_dc,current_dc,volts_ac,current_ac,resistance,capacitance; unsigned char T0IntCount=0;

/***************************************************** 交流电压档

*******************************************************/ float Volts_ac3V() {

volts_ac=(sum/Count*(Vref/256.0))*2-0.7; sum=0;Count=0; return (volts_ac); }

float Volts_ac30V() {

volts_ac=(sum/Count*(10.0*Vref/256.0))*2-0.7; sum=0;Count=0; return (volts_ac); }

/***************************************************** 直流电压档

*******************************************************/ float Volts_dc5V() {

static unsigned char a;

a=AD_change();

volts_dc=a*(2*Vref/256.0); return (volts_dc); }

float Volts_dc50V() {

static unsigned char b;

b=AD_change();

volts_dc=b*(2*Vref*10.0/256.0); return (volts_dc); }

/***************************************************** 交流电流档

*******************************************************/ float Current_ac5mA() {

current_ac=sum/Count*(2*Vref/256.0)-0.7; sum=0;Count=0; return (current_ac); }

float Current_ac50mA() {

current_ac=sum/Count*(2*10.0*Vref/256.0)-0.7; sum=0;Count=0; return (current_ac); }

/***************************************************** 直流电流档

*******************************************************/ float current_dc5mA() {

static unsigned char c;

c=AD_change();

current_dc=c*(2*Vref/256.0); return (current_dc); }

float current_dc50mA() {

static unsigned char d;

d=AD_change();

current_dc=d*(2*Vref*10.0/256.0); return (current_dc); }

/***************************************************** 电容档

*******************************************************/

float Capacitandc_Cycle10UF() {

static float Cycle=0,Count=0,sum=0,ave=0;

unsigned char i; for(i=0;i<10;i++) {

WaveInput=1; TL0=0; TH0=0; T0IntCount=0;TR0=0; while(WaveInput==0); while(WaveInput==1); while(WaveInput==0); TR0=1;

while(WaveInput==1); while(WaveInput==0); TR0=0;

Cycle=(T0IntCount*65536+TH0*256+TL0)/1000.0; Count=(Cycle*16.0)/1.0; sum=Count+sum; }

ave=sum/10.0;sum=0; return (ave); }

float Capacitandc_Cycle200UF() {

static float Cycle=0,Count=0,sum=0,ave=0; unsigned char i; for(i=0;i<10;i++) {

WaveInput=1; TL0=0; TH0=0;

T0IntCount=0; TR0=0; while(WaveInput==0); while(WaveInput==1); while(WaveInput==0); TR0=1;

while(WaveInput==1); while(WaveInput==0); TR0=0;

Cycle=(T0IntCount*65536+TH0*256+TL0)/1000.0; Count=(Cycle*33.0)/10.0; sum=Count+sum; }

ave=sum/10.0;sum=0; return (ave);

//稳定方波

}

/***************************************************** 电阻档

*******************************************************/ float resistance2K() {

static unsigned int Sum=0,AD_value=0,Res_value=0; static float Ave=0.0; unsigned char i;

for(i=0;i<20;i++) {

AD_value=AD_change(); Sum=Sum+AD_value; Ave=Sum/20.0; }

Res_value=Ave*2/256.0; return (Res_value); }

float resistance200K() {

static unsigned int Sum=0,AD_value=0,Res_value=0; static float Ave=0.0; unsigned char i;

for(i=0;i<20;i++) {

AD_value=AD_change(); Sum=Sum+AD_value; Ave=Sum/20.0; }

Res_value=Ave*200/256.0; return (Res_value); }

Function.h文件

/***************************************************** 交流电压档

*******************************************************/ void voltsac_action3V() {

for(i=20;i>0;i--)Volts_adchange(); Lcd_display(Volts_ac3V()); }

void voltsac_action30V() {

for(i=20;i>0;i--)Volts_adchange(); Lcd_display(Volts_ac30V()); }

/***************************************************** 直流电压档

*******************************************************/ void voltsdc_action5V() {

Lcd_display(Volts_dc5V()); }

void voltsdc_action50V() {

Lcd_display(Volts_dc50V()); }

/***************************************************** 交流电流档

*******************************************************/ void Currentac_action5mA() {

for(i=20;i>0;i--)Volts_adchange(); Lcd_display(Current_ac5mA()); }

void Currentac_action50mA() {

for(i=20;i>0;i--)Volts_adchange(); Lcd_display(Current_ac50mA()); }

/***************************************************** 直流电流档

*******************************************************/ void Currentdc_action5mA() {

Lcd_display(current_dc5mA()); }

void Current_action50mA() {

Lcd_display(current_dc50mA()); }

/***************************************************** 电容档

*******************************************************/ void Capacitandc_action200UF() {

Lcd_display(Capacitandc_Cycle200UF()); }

void Capacitandc_action10UF() {

Lcd_display(Capacitandc_Cycle10UF()); }

/***************************************************** 电阻档

*******************************************************/ void Resistance_action2K() {

Lcd_display(resistance2K()); }

void Resistance_action200K() {

Lcd_display(resistance200K()); }

Key_scan.h文件

sbit Key_volts_dc =P0^7; sbit Key_volts_ac =P0^6; sbit Key_currentdc_dc =P0^5; sbit Key_currentac_ac =P0^4; sbit Key_resistance =P0^3; sbit Key_capacitance =P0^2; sbit Key_reduce =P0^1; sbit Beep =P0^0;

void Key_scan() {

if(Key_volts_ac==0) //交流电压 {

voltsac_action30V();

while(Key_reduce==0){voltsac_action3V();} }

if(Key_currentac_ac==0) //交流电流 {

Currentac_action50mA();

while(Key_reduce==0){Currentac_action5mA();} }

if(Key_volts_dc==0) // 直流电压 {

voltsdc_action50V();

while(Key_reduce==0){voltsdc_action5V();} }

if(Key_currentdc_dc==0) //直流电流 {

Current_action50mA();

while(Key_reduce==0){Currentdc_action5mA();} }

if(Key_capacitance==0) //电容 //换挡时一定记得换跳帽 {

Capacitandc_action200UF();

while(Key_reduce==0){Capacitandc_action10UF();} }

if(Key_resistance==0) //电阻 {

Resistance_action200K();

while(Key_reduce==0){Resistance_action2K();} } }

因篇幅问题不能全部显示,请点此查看更多更全内容