一、系统组成及工作原理
1.1 系统组成
该基于AT89C52单片机的数字电压表设计由AT89C51单片机,ADC0809芯片(A/D转换器),LED数码管显示电路以及蜂鸣器电路等几部分组成。(用到得芯片是HC6800-MS)
系统结构图
1.1.1 单片机AT89C52芯片
AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。
AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2 个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的 Flash存储器可有效地降低开发成本。
AT89C52管脚图
1.1.2 ADC0809芯片
ADC0809作为A/D转换器,是采样分辨率为8位的、采用CMOS工艺制成的8通道以逐次逼近原理进行模/数转 换的器件。其内部有一个8通道多路开关,它可以根据地址码锁存译码后的信号只选通8路模拟输入信号中的一个进行A/D 转换。ADC0809的内部结构包括8路模拟选通开关、通道地址锁存器与译码器、8位A/D转换器和三态输出锁存器。
ADC0809的工作过程如下:1)设置ADDA、ADDB、ADDC地址选择信号选择某一通道号;2)给START端发送一个上升沿信号,启动A/D转换;3)查询A/D转换结束信号EOC是否等于1,等于1则A/D转换结束;4)使输出允许信号OE=1,通过I/O口读取8位转换结果到CPU,准备数据处理,此时OE=0。
Table 1地址选择与被选通道之间的关系
ADDA |
ADDB |
ADDC |
通道 |
0 |
0 |
0 |
IN0 |
0 |
0 |
1 |
IN1 |
0 |
1 |
0 |
IN2 |
0 |
1 |
1 |
IN3 |
1 |
0 |
0 |
IN4 |
1 |
0 |
1 |
IN5 |
1 |
1 |
0 |
IN6 |
1 |
1 |
1 |
IN7 |
1.1.3 LED数码管显示电路
LED显示电路的主要功能是对系统处理后的电压值及时进行显示。本设计选用4位的数码型LED显示器,用AT89C51单片机的P0口来控制LED显示器的段码;用P1.0-P1.3引脚来控制LED显示器的位码。
实现代码:
void display()
{
led1=led2=led3=led4=0;
led4=1;
P0=led[volt/100] | 0x80; //整数位、小数点
delay(2000);
led4=0;
led3=1;
P0=led[(volt/10)%10]; //小数点后第一位
delay(2000);
led3=0;
led2=1;
P0=led[volt%10]; //小数点后第二位
delay(2000);
led1=led2=led3=led4=0;//清除显示
}
1.1.4 蜂鸣器电路
当测量值超过设置的最高电压时,蜂鸣器发声且LED灯闪烁。
实现代码:
if((volt/100)>=MAX_VOLT)//超过最高电压蜂鸣器报警
{
beep=~beep;
delay(200);
LED=0;
delay(6000);
LED=1;
delay(6000);
}
else
{
beep=0;
LED=1;
}
完整代码:
#include "reg52.h"
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define MAX_VOLT 4
uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint volt=0;
sbit LED=P2^7;
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit OE=P2^6;
sbit CLK=P1^7;
sbit START=P2^4;
sbit EOC=P2^5;
sbit adda=P2^3;
sbit addb=P2^2;
sbit addc=P2^0;
sbit beep=P2^1;
typedef unsigned int u32;
typedef unsigned char u16;
void delay(u32 i)
{
while(i--);
}
void ADC()
{
EA=1;
OE=0;
START=0;
adda=0;
addb=0;
addc=0;
START=1;
START=0;
while(EOC==0);
OE=1;
EA=0;
volt=P3;
volt=volt*1.96;
OE=0;
}
void display()
{
led1=led2=led3=led4=0;
led4=1;
P0=led[volt/100]|0x80; //整数位、小数点
delay(2000);
led4=0;
led3=1;
P0=led[(volt/10)%10]; //小数点后第一位
delay(2000);
led3=0;
led2=1;
P0=led[volt%10]; //小数点后第二位
delay(2000);
led1=led2=led3=led4=0;//清除显示
}
void main()
{
EA=1;/
TMOD=0x01;
TH0=0XFF;
TL0=0XB4;
ET0=1;
TR0=1;
while(1)
{
ADC();
display();
if((volt/100)>=MAX_VOLT)
{
beep=~beep;
delay(200);
LED=0;
delay(6000);
LED=1;
delay(6000);
}
else
{
beep=0;
LED=1;
}
}
}
void timer() interrupt 1
{
TH0=0XFF;
TL0=0XF0;
CLK=~CLK;
}