跳到主要内容

使用 8051 单片机的数字电压表

在本项目中,我将演示如何使用 8051 单片机设计数字电压表,并解释其工作原理。电压表是一种测量仪器,用于测量电网中两点之间的电压差。通常,电压表有两种类型:模拟电压表数字电压表

在模拟电压表中,指针在刻度上移动以表示电压。而数字电压表则借助 模数转换器 (ADC) 直接以数字形式显示电压。本文将讲解两种数字电压表设计方法:

  1. 使用 8051 单片机
  2. 使用 IC L7017
alt text

1. 项目概述

本项目测量输入电压范围为 0V 到 25V。输入电压应为直流电压,以便在 LCD 上得到准确输出。如果输入交流电压,则由于 AC 电压连续变化,LCD 上会显示连续变化的数字。

本项目的主要元件包括:

  • 8051 单片机
  • 电压传感器模块
  • ADC IC ADC0804

本项目使用模拟到数字转换过程显示电压。

2. 模拟到数字转换

在实际应用中,通常我们获取的是模拟数据。为了使用数字系统处理这些数据,需要将模拟信号转换为数字信号,使微处理器或单片机能够理解和处理。

alt text

2.1 物理量与数字系统接口

  • 传感器 (Transducer):将物理量转换为电信号。例如光敏电阻、温度传感器、湿度传感器、气体传感器等。
  • ADC(模数转换器):将输入电压转换为数字值。
  • 数字系统:读取数字数据并在 LCD 上显示物理量。

在本项目中,ADC IC根据输入电压生成数字输出,8051 单片机读取数字值并显示在 LCD 上。

3.使用 8051 单片机的数字电压表电路图

alt text

4. 电路元件

  • AT89C51 单片机

  • ADC0804 IC

  • 25V 电压传感器

  • AT89C51 编程板

  • 可变电阻(用于演示程序)

  • DC 适配器或电池

5. 电路设计

在电路中,ADC IC 的数据位连接到 PORT2,LCD 数据端口连接到 PORT3,控制端 RSEN 分别连接到 P1.6P1.7

5.1 ADC0804

  • 8 位模数转换器,采用逐次逼近法转换模拟信号为数字
  • 每次只能处理一个模拟输入
  • 引脚 9 可调节步长,若未连接则参考电压为 VCC
  • 当步长为 5V 时,每升高 19.53mV 输出增加 1

步长计算公式:

Step size=Vref2n\text{Step size} = \frac{V_\text{ref}}{2^n}

其中 n=8n = 8

数字输出公式:

Dout=VinStep sizeD_\text{out} = \frac{V_\text{in}}{\text{Step size}}

示例:模拟输入电压 Vin=4VV_\text{in} = 4V,则数字输出:

Dout=40.01953204D_\text{out} = \frac{4}{0.01953} \approx 204

5.2 数字处理步骤

  1. PORT2 读取 ADC 值
#define dat P2
val = dat * 0.02;
val1 = val * 100;
  1. 分解数字并显示在 LCD 上,包括小数点
temp = (((val1/100)%10)+48);
display(temp);
display('.');
temp = (((val1/10)%10)+48);
display(temp);
temp = ((val1%10)+48);
display(temp);

5.3 电压传感器

电压传感器模块是一个简单的 分压网络,可将模拟输入电压范围扩展至约 25V。

alt text

5.4 接口连接

电压传感器与 Arduino 接口连接方式与本项目类似。

5.5 代码示例

#include<reg51.h>
#define lcd P3
#define dat P2
sbit rs=P1^6;
sbit e=P1^7;


void delay (int);
void display (unsigned char);
void cmd (unsigned char);
void init (void);
void string (char *);
void intro (void);
char i=0;


void delay (int d)
{
unsigned char i=0;
for(;d>0;d--)
{
for(i=250;i>0;i--);
for(i=248;i>0;i--);
}
}
void cmd (unsigned char c)
{
lcd=c;
rs=0;
e=1;
delay(10);
e=0;
}
void display (unsigned char c)
{
lcd=c;
rs=1;
e=1;
delay(10);
e=0;
}
void string (char *c)
{
while(*c)
{
display(*c++);
}
}
void init (void)
{
cmd(0x38);
cmd(0x01);
cmd(0x0c);
cmd(0x80);
}
void intro (void)
{
string(" Electronics ");
cmd(0xc0);
string(" Hub ");
delay(2000);
cmd(0x01);
string(" Digital ");
cmd(0xc0);
string(" Voltmeter ");
delay(2000);
cmd(0x01);
cmd(0x80);
}

void main()
{
unsigned int temp=0;
unsigned int temp1=0;
float val=0.0;

init();
intro();
dat=0xff;
while(1)
{
if(i==0)
{
string(" Volts - ");
i++;
}
val=dat*0.02; // 0.02 is resolution of adc
val=val/0.2; // 0.2 is nothing but (R2/(R1+R2)) resistor values in the voltage sensor
cmd(0x89);
if((val>=1.0) && (val<10.0))
{
display(' ');
temp=val*1000;
temp1=((temp/1000)+48);
display(temp1);

display('.');

temp1=(((temp/100)%10)+48);
display(temp1);
}
else if((val>=10.0) && (val<100.0))
{
temp=val*100;
temp1=((temp/1000)+48);
display(temp1);

temp1=(((temp/100)%10)+48);
display(temp1);

display('.');

temp1=(((temp/10)%10)+48);
display(temp1);
}
else
{
display(' ');
string("0.0");
}
delay(1000);
}
while(1);
}

6. 电压表工作原理

  1. 将程序烧录到 AT89C51 单片机
  2. 按电路图连接
  3. 将电池或电压源接入电压传感器输入
  4. 确保最大模拟输入电压小于 25V DC
  5. 将数字万用表接入电压传感器输入端
  6. 打开电路板电源,LCD 和万用表显示相同电压
  7. 缓慢调整模拟输入电压,可观察 LCD 与万用表同步变化
  8. 关闭电路板电源
alt text

7. 数字电压表应用

  • 用于低电压应用的电压测量

  • 测量玩具电池

  • 可通过小幅改动测量温度、湿度、气体等物理量

8. 数字电压表局限性

  • 输入电压范围应为 0 到 5V

  • 每次只能测量一个模拟输入值

9. 使用 ICL7107 的数字电压表

无需单片机也可设计电压表,使用 ICL7107。该 IC 为低功耗 3½ 位 A/D 转换器,内置 7 段解码器、显示驱动器、参考电压与时钟。

  • 可直接驱动非复用七段显示

  • 测量范围:200mV – 2V,分辨率 0.001V

9.1 原理

  • 使用 ICL7107 进行模拟到数字转换
  • 分为两个阶段:模拟到数字转换与解码
  • 输入信号先被积分,得到斜坡信号,再用参考电压积分使输出回零
  • 得到的数字码通过解码器驱动显示单元

9.2 使用 ICL7107 的数字电压表电路图

alt text

9.3 电路设计要点

  • 振荡器元件:频率 48 kHz,电阻约 100K,电容约 100pF

  • 参考电容:0.1uF – 1uF,本例选择 0.5uF

  • 自动清零电容:0.01uF – 1uF,本例选择 0.1uF

  • 积分电容:根据积分时间、积分电流与电压计算,选择 0.22uF

  • 积分电阻:全量程电压与最佳积分电流计算,选择 500K

9.4 操作方法

该集成电路由 ±5V 双电源供电。当电路上电后,通过调节参考电阻来设定参考信号。参考电压需要设置为大约输入电压的一半。振荡元件(电阻和电容)决定了器件的振荡频率或时钟频率。

参考电容被充电到参考电压,随后闭合反馈回路以给自动清零电容充电,从而补偿电压的任何波动。接下来,转换器在固定时间内对输入端的差分电压进行积分,使积分器的输出成为一条斜坡信号。

然后,将一个已知的参考电压施加到积分器输入端,并允许其积分,直到积分器输出回到零。输出返回零所需的时间与输入信号成正比,数字读数由以下公式给出:

显示计数=VinVref×1000\text{显示计数} = \frac{V_\text{in}}{V_\text{ref}} \times 1000

接下来的过程是对数字计数进行解码,以生成与七段数码管兼容的信号,从而驱动显示器。最终,数字输出会显示在多路复用的七段显示器上。

9.5 应用

  • 数字万用表

  • 测量 AC/DC 电压

  • 测量物理量(压力、温度、应力)

  • 高精度、高分辨率测量场合

9.6 局限性

  • 只能测量低电压
  • IC 为 CMOS,静电敏感
  • 参考电压差异可能导致溢出误差
  • 全量程负电压可能导致积分器饱和
  • LED 驱动器内部发热可能影响性能
  • 温度系数、芯片内部功耗及封装热阻增加噪声