基于51单片机数字万用表的制作

更新时间:2024-03-19 03:00:02 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

基于51单片机数字万用表

摘要:

本设计采用AT89C52为主控芯片配以振荡电路设计设计了一个数字万用表,可用于测量直流电压,直流电流,电阻和电容,并配以档位转换。本系统使用ADC0832作为数据转换芯片,LM358作为放大芯片,通过LCD1602显示,各模块主要通过AD转换以及电压放大实现测量功能。

绪论:

数字多用表(GMM)就是在电气测量中要用到的电子仪器。它可以有很多特殊功能,但主要功能就是对电压、电阻和电流进行测量。传统的指针式万用表功能单精度低,不能满足数字化时代的需求,采用单片机制作的数字万用表,具有精度高、抗干扰能力强,可扩展力强、集成方便等优点,目前,由各种单片机芯片构成的数字电万用表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,显示出强大的生命力。

总体设计设计方案:

1

AD电路 显示电路 分压电路 电压 单 片 机 AD电路 放大电路 电流 晶振电路 功能开关 振荡电路 放大电路 路路 电阻 电容 1.电压测量原理与AD转换电路

ADC0832是美国国家半导体公司生产的一种8 位分辨率、双通道A/D转换芯片。其最高分辨可达256级,可以适应一般的模拟量转换要求。其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间。芯片转换时间仅为32μS,据有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。通过DI 数据输入端,可以轻易的实现通道功能的选择。本系统只对CH0 进行单通道转换。

2

电压信号输入 分压 AD转换 单片机显示 电压测量流程图

对于本设计分压电路模块介绍之前首先分析以下两种设计方案。

多量程分压电路

多量程分压器原理

上述两图所制作的多量程电压测量,其内阻比较小,不能达到测量要求,对电路做以下改进。

3

对于本次设计的电压模块只设置5V,30V两个档位,如图直接采

用一组分压电路既可达到要求。

2.电流测量原理与放大电路

对于电流模块此处给予多种方案:(本系统采用的方案二) 方案一:

原理:通过改变检流电阻的大小实现不同档位的转换。

4

图中保险丝可保护电流过大,二极管防止电压过大,当二极管两端电压达到导通电压,检流电阻连端电压将达到稳定,从而有效的控制输入电压的大小。 方案二:

5

电流测量原理与方案一基本相同,但在相同电流的测量上此电路比方案一电路的内组更小,由于加入了运算放大器,所以最大的输出电压不会超过电源电压(实验数据显示不会超过3.6V)并不用担心检流电阻两端电压大小。而且此方案还有一个最大的优势,它的分辨率更高,理由如下:

根据ADC0832的最小分辨率x可知,此方案中测量电流的最小分辨电流i满足i*R*k=x(R为检流电阻,k为放大器放大倍数),得到i=x/(R*k)

在方案一中,i’=x/R’,由于电阻材质的问题其本身电压不能超过额定电压,在量程相同的情况下Imax*R*k=3,Imax*R’<3.因此Rx>R’ 即i

(LM358 内部包括有两个独立的、高增益、内部频率补偿的双运算放大器,适合于电源电压范围很宽的单电源使用,也适用于双电源工作模式,在推荐的工作条件下,电源电流与电源电压无关。它的使用范围包括传感放大器、直流增益模块和其他所有可用单电源供电的使用运算放大器的场合。)

3.电阻模块的测量原理

选择量程 接入电阻 放大电压 AD转换 单片机处理 6 显示

放大电路

放大器的最大放大电压为3V左右(实际放大为3.5V左右,这里取3V),则输入电压满足5*10

ADC0832的最小分辨率为0.02V即放大后的最小电压为0.02V. 则输入电压满足5*10>v(1010+R).v是最小输入电压。根据上述说明可以得出各个档位测量范围。

档位1(V=0.05,v=0.0003..),R<148990 档位2(V=0.005, v=0.00003..),8990

在上述电路制作成功后并没有达到比较好的测量效果,对于大电阻的

7

测量测量值往往会远小于实际电阻值。针对这个问题,在对放大器各级电压比较后发现主要是由于大电阻测量时输入电压太小以至于达不到放大器的正常放大电压,因此上述电路在很大程度上限制了测量电阻的范围。 对电路做以下改变:

直接将前两级放大合并为一级放大,达到减小放大的门款电压。

其他测量方法: 原理图如下:

8

通过恒流源(恒流电路此处用电流源代替)给待测电阻供电,放大待测电阻的电压,输出给电压表。

此方法和上述方案原理上的差别在于一个利用的是电流恒定,另一个利用的是电压恒定,对于电流的恒定,一方面,它的电路设计比较复杂,另一方面,如果电流源电路设计的不太理想,电流源的大小变化会产生很大的测量误差。不过它可以使测量误差比较稳定,在测量误差不大的情况下电压恒定电路的误差变化可以忽约吗,因此本设计不采用这种设计思路。

4.电容的测量原理与振荡电路:

选择量程 接入电容 电容充放电 单片机 显示 9

根据555定时器构成单稳态,产生脉冲波形,通过单片机读取高低电平得出频率,通过公式换算得到电容值。

总结:

整个设计基本上是围绕放大器所组成的放大电路展开,放大器的放大误差直接决定着测量的误差。此设计设计电路简单,测量精度比较小。 而且材料成本低,对于直流电路的测量有着很好的实用性。

程序

主函数

#include\

10

TH0=0x3c; TL0=0xb0;

}

void keyboat() interrupt 2 //功能转换开关 { unsigned char trange=200; if(key_boat==0) { delay(50); if(key_boat==0) {

key++; TR0=0;

if(key>11){key=1; TR0=1;} writeadd(1); switch(key)

{case 1: writedate(0x80+13,'U');writedate(0x80+14,'5'); writedate(0x80+15,'v');break;

case 2: writedate(0x80+12,'U') ;writedate(0x80+13,'3'); writedate(0x80+14,'0'); writedate(0x80+15,'v');break;

case 3: writedate(0xc0+11,'I') ;writedate(0xc0+12,'1'); writedate(0xc0+13,'0'); writedate(0xc0+14,'m');writedate(0xc0+15,'A');break;

case 4: writedate(0xc0+11,'I') ;writedate(0xc0+12,'8'); writedate(0xc0+13,'0'); writedate(0xc0+14,'m');writedate(0xc0+15,'A');break; case 5: writedate(0xc0+10,'I') ;writedate(0xc0+11,'1'); writedate(0xc0+12,'5');writedate(0xc0+13,'0');

writedate(0xc0+14,'m');writedate(0xc0+15,'A');break; case 6: writedate(0xc0+13,'R');writedate(0xc0+14,'9'); writedate(0xc0+15,'K');break;

case 7: writedate(0xc0+12,'R') ;writedate(0xc0+13,'9'); writedate(0xc0+14,'9'); writedate(0xc0+15,'K');break;

case 8: writedate(0xc0+11,'R') ;writedate(0xc0+12,'9'); writedate(0xc0+13,'9'); writedate(0xc0+14,'9');writedate(0xc0+15,'K');break; case 9: writedate(0x80+12,'C'); writedate(0x80+13,'=');

writedate(0x80+14,'u');writedate(0x80+15,'F');break; case 10:writedate(0x80+12,'C'); writedate(0x80+13,'=');

writedate(0x80+14,'n');writedate(0x80+15,'F');break; case 11:writedate(0x80+10,'e') ;writedate(0x80+11,'r'); writedate(0x80+12,'r');writedate(0x80+13,'o'); writedate(0x80+14,'r');break;

16

}

date=key;

date1=key-2; }}

delay(50);

while(key_boat==0&&trange) trange--; key_boat=1; TR0=1; }

unsigned char AAD_read() {unsigned char dat,i,test=0,adval=0; AAD_CLK=0;// AAD_D1=1; _nop_(); AAD_CS=0; _nop_(); AAD_CLK=1; _nop_();

AAD_CLK=0; // AAD_D1=0; _nop_(); AAD_CLK=1; _nop_();

AAD_CLK=0; // AAD_D1=0; _nop_(); AAD_CLK=1; _nop_();

AAD_CLK=0; AAD_D1=1;

for(i=0;i<8;i++) {_nop_(); adval<<=1;

AAD_CLK=1;_nop_(); AAD_CLK=0;

//电流测量端数据接收函数17

if(AAD_D0) adval|=1; }

for(i=0;i<8;i++) {_nop_();test>>=1; if(AAD_D0) test|=0x80;

AAD_CLK=1;_nop_(); AAD_CLK=0; }

if(adval==test) dat=test; _nop_(); AAD_CS=1; AAD_D0=1; AAD_D1=1; AAD_CLK=1;

return dat; }

unsigned char AVD_read() {unsigned char dat,i,test=0,adval=0; AVD_CLK=0;// AVD_D1=1; _nop_(); AVD_CS=0; _nop_(); AVD_CLK=1; _nop_();

AVD_CLK=0; // AVD_D1=0; _nop_(); AVD_CLK=1; _nop_();

//电压测量端ADC0832数据接收函数18

AVD_CLK=0; // AVD_D1=0; _nop_(); AVD_CLK=1; _nop_();

AVD_CLK=0; AVD_D1=1;

for(i=0;i<8;i++) {_nop_(); adval<<=1;

AVD_CLK=1;_nop_(); AVD_CLK=0;

if(AVD_D0) adval|=1; }

for(i=0;i<8;i++) {_nop_();test>>=1; if(AVD_D0) test|=0x80;

AVD_CLK=1;_nop_(); AVD_CLK=0; }

if(adval==test) dat=test; _nop_(); AVD_CS=1; AVD_D0=1; AVD_D1=1; AVD_CLK=1;

return dat; }

19

显示函数

#include\

void delay(unsigned char i) {unsigned char j=100; while(i>0) {j=100; while(j--); i--;} }

void writeadd(unsigned char add) //写入指令 {

check(); E=0; RS=0; RW=0; delay(1); LCD=add; delay(1); E=1; delay(1); E=0; delay(1); }

void check() {

RS=0;RW=1; delay(1); E=1;

while(LCD&0x80); E=0;

delay(1);}

void writedate(unsigned char add,unsigned char date) {

writeadd(add); check(); E=0; RS=1;

//写入地址和数据20

RW=0; delay(1); LCD=date; delay(1); E=1; delay(1); E=0; delay(1); }

void init()

{writeadd(0xc); writeadd(0x3c); }

显示函数头文件

#ifndef LCD_H #define LCD_H #include\ #include #define LCD P0 sbit RS=P2^6; sbit RW=P2^5; sbit E=P2^7;

void delay(unsigned char i);

void writeadd(unsigned char add);

void writedate(unsigned char add,unsigned char date); void check(); void init(); #endif

21

RW=0; delay(1); LCD=date; delay(1); E=1; delay(1); E=0; delay(1); }

void init()

{writeadd(0xc); writeadd(0x3c); }

显示函数头文件

#ifndef LCD_H #define LCD_H #include\ #include #define LCD P0 sbit RS=P2^6; sbit RW=P2^5; sbit E=P2^7;

void delay(unsigned char i);

void writeadd(unsigned char add);

void writedate(unsigned char add,unsigned char date); void check(); void init(); #endif

21

本文来源:https://www.bwwdw.com/article/65v8.html

Top