基于51单片机的数字电压表课程设计.docx
《基于51单片机的数字电压表课程设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机的数字电压表课程设计.docx(26页珍藏版)》请在冰豆网上搜索。
基于51单片机的数字电压表课程设计
摘要
随着微电子技术的不断发展,微处理器芯片的集成程度越来越高,单片机已可以在一块芯片上同时集成CPU、存储器、定时器/计数电路,这就很容易将计算机技术与测量控制技术结合,组成智能化测量控制系统。
数字电压表(DigitalVoltmeter)简称DVM,它是采用数字化测量技术,把连续的模拟量(直流输入电压)转换成不连续、离散的数字形式并加以显示的仪表。
与此同时,由DVM扩展而成的各种通用及专用数字仪器仪表,也把电量及非电量测量技术提高到崭新水平。
本章重点介绍单片A/D转换器以及由它们构成的基于单片机的数字电压表的工作原理。
目前,由各种单片A/D转换器构成的数字电压表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,显示出强大的生命力。
本设计AT89C51单片机的一种电压测量电路,该电路采用基于ADC0808芯片的一种A/D转换电路,测量范围直流0~5V的4路输入电压值,并在LED数码管上显示。
测量最小分辨率为0.019V,测量误差约为正负0.02V。
摘要1
第1章设计原理及要求3
1.1数字电压表的实现原理3
2.2数字电压表的设计要求3
第2章芯片介绍4
2.1AT89C51引脚及功能介绍4
2.1.1简单概述4
2.1.2主要功能特性5
2.1.3AT89C51的引脚介绍5
2.2ADC0808引脚及功能介绍7
2.2.1芯片概述7
2.2.2引脚简介7
2.2.3ADC0808的转换原理8
2.2.4ADC工作时序8
2.3MAX7219引脚及功能介绍9
2.3.1芯片概述9
2.3.2引脚简介10
2.3.3功能特点11
2.3.4MAX7219工作时序11
2.4矩阵键盘12
2.5LED数码管显示13
2.5.1LED数码管模型13
2.5.2数码管接口简介13
第3章软件仿真电路设计15
3.1设计思路15
3.2仿真电路图15
3.3设计过程19
第4章系统软件程序的设计20
参考文献21
心得与体会22
附录23
第1章设计原理及要求
本设计是利用单片机AT89C51与ADC0808设计一个数字电压表,测量0-5V之间的直流电压值,并用数码显示。
1.1数字电压表的实现原理
ADC0808是8位的A/D转换器。
当输入电压为5.00V时,输出的数据值为255(0FFH),因此最大分辨率为0.0196(5/255)。
ADC0808具有8路模拟量输入端口,通过3位地址输入端能从8路中选择一路进行转换。
如每隔一段时间依次轮流改变3位地址输入端的地址,就能依次对8路输入电压进行测量。
LED数码管显示采用软件译码动态显示。
通过按键选择可对8路循环显示,也可单路显示,单路显示可通过按键选择显示的通道数。
2.2数字电压表的设计要求
可以测量0~5V范围内的8路直流电压值。
通过按键选择在4位LED数码管上显示各路电压值,其中3位LED数码管显示电压值,显示范围为0.00V~5.00V,1位LED数码管显示路数,8路分别为1~8。
要求测量的最小分辨率为0.02V。
第2章
芯片介绍
2.1AT89C51引脚及功能介绍
2.1.1简单概述
AT89C51是一种带4K字节闪存可编程可擦除只读存储器(FPEROM—FlashProgrammableandErasableReadOnlyMemory)的低电压、高性能CMOS8位微处理器,俗称单片机。
AT89C51是一种带2K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。
AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
外形及引脚排列如图2-1所示。
图2-1AT89C51芯片模型
2.1.2主要功能特性
(1)4K字节可编程闪烁存储器。
(2)32个双向I/O口;128×8位内部RAM。
(3)2个16位可编程定时/计数器中断,时钟频率0-24MHz。
(4)可编程串行通道。
(5)5个中断源。
(6)2个读写中断口线。
(7)低功耗的闲置和掉电模式。
(8)片内振荡器和时钟电路。
2.1.3AT89C51的引脚介绍
89C51单片机多采用40只引脚的双列直插封装(DIP)方式,下面分别简单介绍。
(1)电源引脚
电源引脚接入单片机的工作电源。
Vcc(40引脚):
+5V电源。
GND(20引脚):
接地。
(2)时钟引脚
XTAL1(19引脚):
片内振荡器反相放大器和时钟发生器电路的输入端。
XTAL2(20引脚):
片内振荡器反相放大器的输出端。
图2-2电源接入方式
(3)复位RST(9引脚)
在振荡器运行时,有两个机器周期(24个振荡周期)以上的高电平出现在此引脚时,将使单片机复位,只要这个脚保持高电平,51芯片便循环复位。
(4)/Vpp(31引脚)
为外部程序存储器访问允许控制端。
当它为高电平时,单片机读片内程序存储器,在PC值超过0FFFH后将自动转向外部程序存储器。
当它为低电平时,只限定在外部程序存储器,地址为0000H~FFFFH。
Vpp为该引脚的第二功能,为编程电压输入端。
(5)ALE/(30引脚)
ALE为低八位地址锁存允许信号。
在系统扩展时,ALE的负跳沿江P0口发出的第八位地址锁存在外接的地址锁存器,然后再作为数据端口。
为该引脚的第二功能,在对片外存储器编程时,此引脚为编程脉冲输入端。
(6)(29引脚)
片外程序存储器的读选通信号。
在单片机读片外程序存储器时,此引脚输出脉冲的负跳沿作为读片外程序存储器的选通信号。
(7)pin39-pin32为P0.0-P0.7输入输出脚,称为P0口。
P0是一个8位漏极开路型双向I/O口。
内部不带上拉电阻,当外接上拉电阻时,P0口能以吸收电流的方式驱动八个LSTTL负载电路。
通常在使用时外接上拉电阻,用来驱动多个数码管。
在访问外部程序和外部数据存储器时,P0口是分时转换的地址(低8位)/数据总线,不需要外接上拉电阻。
(8)Pin1-Pin8为P1.0-P1.7输入输出脚,称为P1口,是一个带内部上拉电阻的8位双向I/0口。
P1口能驱动4个LSTTL负载。
(9)Pin21-Pin28为P2.0-P2.7输入输出脚,称为P2口。
P2口是一个带内部上拉电阻的8位双向I/O口,P2口能驱动4个LSTTL负载。
端口置1时,内部上拉电阻将端口拉到高电平,作输入用。
对内部Flash程序存储器编程时,接收高8位地址和控制信息。
在访问外部程序和16位外部数据存储器时,P2口送出高8位地址。
而在访问8位地址的外部数据存储器时其引脚上的内容在此期间不会改变。
(10)Pin10-Pin17为P3.0-P3.7输入输出脚,称为P3口。
P3口是一个带内部上拉电阻的8位双向I/O口,P2口能驱动4个LSTTL负载,这8个引脚还用于专门的第二功能。
端口置1时,内部上拉电阻将端口拉到高电平,作输入用。
对内部Flash程序存储器编程时,接控制信息。
2.2ADC0808引脚及功能介绍
2.2.1芯片概述
ADC0808是一种典型的A/D转换器。
它是由8位A/D转换器,一个8路模拟量开关,8位模拟量地址锁存译码器和一个三态数据输出锁存器组成;+5V单电源供电,转化时间在100us左右;内部没有时钟电路,故需外部提供时钟信号。
芯片模型如图2-3所示。
图2-3ADC0808芯片模型
2.2.2引脚简介
(1)IN0~IN7:
8路模拟量输入端。
(2)D0~D7:
8位数字量输出端口。
(3)START:
A/D转换启动信号输入端。
(4)ALE:
地址锁存允许信号,高电平有效。
(5)EOC:
输出允许控制信号,高电平有效。
(6)OE:
输出允许控制信号,高电平有效。
(7)CLK:
时钟信号输入端。
(8)A、B、C:
转换通道地址,控制8路模拟通道的切换。
A、B、C分别与地址线或数据线相连,三位编码对应8个通道地址端口,A、B、C=000~111分别对应IN0~IN7通道的地址端口。
2.2.3ADC0808的转换原理
ADC0808采用逐次比较的方法完成A/D转换,由单一的+5V电源供电。
片内带有锁存功能的8路选1的模拟开关,由A、B、C的编码来决定所选的通道。
ADC0809完成一次转换需100μs左右,它具有输出TTL三态锁存缓冲器,可直接连接到AT89C51的数据总线上。
通过适当的外接电路,ADC0808可对0~5V的模拟信号进行转换。
2.2.4ADC工作时序
ADC0808/0809的工作时序如图2-4示。
当通道选择地址有效时,ALE信号一出现,地址便马上被锁存,这时转换启动信号紧随ALE之后(或与ALE同时)出现。
START的上升沿将逐次逼近寄存器SAR复位,在该上升沿之后的2μs加8个时钟周期内(不定),EOC信号将变低电平,以指示转换操作正在进行中,直到转换完成后EOC再变高电平。
微处理器收到变为高电平的EOC信号后,便立即送出OE信号,打开三态门,读取转换结果。
模拟输入通道的选择可以相对于转换开始操作独立地进行(当然,不能在转换过程中进行),然而通常是把通道选择和启动转换结合起来完成(因为ADC0808/0809的时间特性允许这样做)。
这样可以用一条写指令既选择模拟通道又启动转换。
在与微机接口时,输入通道的选择可有两种方法,一种是通过地址总线选择,一种是通过数据总线选择。
如用EOC信号去产生中断请求,要特别注意EOC的变低相对于启动信号有2μs+8个时钟周期的延迟,要设法使它不致产生虚假的中断请求。
为此,最好利用EOC上升沿产生中断请求,而不是靠高电平产生中断请求。
图2-4ADC0808工作时序
2.3MAX7219引脚及功能介绍
2.3.1芯片概述
MAX7219/MAX7221是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。
其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。
只有一个外部寄存器用来设置各个LED的段电流。
MAX7221与SPI™、QSPI™以及MICROWIRE™相兼容,同时它有限制回转电流的段驱动来减少EMI(电磁干扰)。
一个方便的四线串行接口可以联接所有通用的微处理器。
每个数据可以寻址在更新时不需要改写所有的显示。
MAX7219/MAX7221同样允许用户对每一个数据选择编码或者不编码。
整个设备包含一个150μA的低功耗关闭模式,模拟和数字亮度控制,一个扫描限制寄存器允许用户显示1-8位数据,还有一个让所有LED发光的检测模式。
芯片模型如图2-5所示。
图2-5MAX7219芯片模型
2.3.2引脚简介
(1)DIG0~DIG7:
8位LED位选线,从共阴极LED中吸入电流。
(2)SEGA~SEGGDP7:
段驱动和小数点驱动。
(3)LOAD:
装载数据输入。
连续数据的后16位在LOAD端的上升沿时被锁定。
(4)CLK:
串行时钟输入。
最大速率为10MHz.在时钟的上升沿,数据移入内
部移位寄存器。
下降沿时,数据从DOUT端输出。
(5)DIN:
串行数据输入端口。
在时钟上升沿时数据被载入内部的16位寄存器。
2,3,5-8,10,11DIG0–DIG7八个数据驱动线路置显示器共阴极为低电平。
关闭时7219此管脚输出高电平,7221呈现高阻抗。
(6)DOUT:
串行数据输出端口,从DIN输入的数据在16.5个时钟周期后在此端有
效。
当使用多个MAX7219/MAX7221时用此端方便扩展。
(7)ISET:
通过一个10k电阻和Vcc相连,设置段电流。
2.3.3功能特点
(1)10MHz连续串行口
(2)独立的LED段控制
(3)数字的译码与非译码选择
(4)150μA的低功耗关闭模式
(5)亮度的数字和模拟控制
(6)高电压中断显示
(7)共阴极LED显示驱动
(8)限制回转电流的段驱动来减少EMI(MAX7221)
(9)SPI,QSPI,MICROWIRE串行接口(MAX7221)
(10)24脚的DIP和SO封装
2.3.4MAX7219工作时序
MAX7129是SPI总线驱动方式。
它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。
工作时,MAX7219规定一次接收16位数据,在接收的16位数据中:
D15~D12可以与操作无关,可以任意写入,D11~D8决定所选通的内部寄存器地址,D7~D0为待显示数据或是初始化控制字。
在CLK脉冲作用下,DIN的数据以串行方式依次移入内部16位寄存器,然后在一个LOAD上升沿作用下,锁存到内部的寄存器中。
注意在接收时,先接收最高位D16,最后是D0,因此,在程序发送时必须先送高位数据,在循环移位。
工作时序图见图2-6。
图2-6MAX719工作时序
2.4矩阵键盘
键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。
即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。
4*4矩阵键盘的结构如图2-7。
图2-7矩阵键盘
在本设计中中,矩阵键盘的四行依次接到单片机的P1.0~P1.3,四列依次接到单片机的P1.4~P1.7。
查找哪个按键被按下的方法:
使用逐行扫描法,一个一个地查找。
先第一行输出0,检查列线是否非全高;
否则第二行输出0,检查列线是否非全高;
否则第三行输出0,检查列线是否非全高;
如果某行输出0时,查到列线非全高,则该行有按键按下;
根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。
2.5LED数码管显示
2.5.1LED数码管模型
LED数码管模型如图2-8所示。
图2-8LED数码管模型
2.5.2数码管接口简介
LED的段码端口A~GDP分别接至MAX7219的A~GDP口,位选端1~4分别接至DIG0~DIG3,由MAX7219驱动数码管,如图2-9所示。
图2-9数码管硬件接线图
第3章
软件仿真电路设计
3.1设计思路
多路数字电压表应用系统硬件电路由单片机、A/D转换器、数码管显示电路、显示驱动器7219和按键处理电路组成,由于ADC0808在进行A/D转换时需要有CLK信号,本试验中ADC0808的CLK直接由外部电源提供为500kHz的方波。
由于ADC0808的参考电压VREF=VCC,所以转换之后的数据要经过数据处理,在数码管上显示出电压值。
实际显示的电压值(D/256*VREF)ADC0808采用逐次逼近法转换,把模拟电压转换成数字电压信号。
3.2仿真电路图
用Protues软件仿真设计的电路如下图所示。
图3-1AT89C52芯片接线图
图3-2ADC088接线图
图3-3MAX7219接线图
图3-4测量输入电路
图3-5仿真电路总体设计
3.3设计过程
简易数字电压测量电路由A/D转换、数据处理及显示控制等组成。
电路原理图见附录2。
A/D转换由集成电路0808完成。
0808具有8路模拟输入端口,地址(23-25)脚可决定对哪路模拟输入作A/D转换,22脚为地址锁存控制,当输入为高电平时,对地址信号进行锁存。
6脚为测试控制,当输入一个2us宽高电平脉冲时,就开始A/D转换。
7脚为A/D转换结束标志,当A/D转换结束时7脚输出高电平。
9脚为A/D转换数据输出允许控制,当OE脚为高电平时,A/D转换数据从该端口输出。
10脚为0808的时钟输入端,由外部信号源提供。
单片机的P1、P3.0-P3.3端口作为四位LED数码管现实控制。
P3.5端口用作单路显示/循环显示转换按钮,P3.6端口用作单路显示时选择通道。
P0端口作A/D转换数据读入用,P2端口用作0808的A/D转换控制。
第4章
系统流程图
多路数字电压表系统软件程序主要有主程序、A/D转换子程序、MAX7219子程序和显示程序组成。
程序流程图如图4-1所示。
图4-1程序流程图
参考文献
[l]边海龙,孙永奎.单片机开发与典型工程项目实例详解[J].电子工业出版社,2008,(10):
143-160.
[2]张鑫,华臻,陈书谦.单片机原理及应用[J].电子工业出版社,2008(5).
[3]黄智伟.凌阳单片机课程设计指导[J].北京航空航天大学出版社,2007,
[4]余锡存曹国华.单片机原理及接口技术[M].陕西:
西安电子科技大学出版社,2000.7
[5]雷丽文等.微机原理与接口技术[M].北京:
电子工业出版社,1997.2
[6]柴钰.单片机原理和应用[M].西安电子科技大学出版社.
[7]张靖武.单片机系统的PROTUSE设计和仿真[M].电子工业出版社.2007.
[8]唐工..51单片机工程应用实例[M].
心得与体会
经过两周的努力工作,终于完成了自己的单片机课程设计。
虽说忙碌了点,但我觉得这样的生活充实且有成就感,当然,也获益匪浅。
通过本次的课程设计,充分意识到自己所学的东西还是非常有限的,不过通过设计,还是学到了一些书本上没有学到的东西,为自己以后的学习起了很大的帮助。
就我个人而言,很深刻地体会到一点,那就是我们在设计过程中一定要有一个整体的清晰的思路,知道自己的设计的对象的基本功能和核心器件的适用及其作用,只要把握住这些主要方面,一些小问题都将围绕着这些主要问题而逐步得到解决。
同时我也懂得,在整个设计过程中,生活中也一样,一定要意志坚定,克服自己的畏难情绪,这样才能将事情做好,才能干出一番成就。
附录
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineDecode_mode0x09//译码控制寄存器
#defineIntensity0x0A//亮度控制寄存器
#defineScan_limit0x0B//扫描界限寄存器
#defineShut_down0x0C//关段模式寄存器
#defineDisplay_test0x0F//测试控制寄存器
sbitDIN=P3^0;//MAX7219串行数据
sbitLOAD=P3^1;//MAX7219片选
sbitCLK=P3^3;//MAX7219串行时钟
sbitADDA=P2^0;
sbitADDB=P2^1;
sbitADDC=P2^2;
sbitALE=P2^3;
sbitEOC=P2^4;
sbitCLOCK=P2^5;
sbitOE=P2^6;
uintnum=0,num1=0,k;
voiddelay(uintz)//延时
{
uintx,y;
for(x=110;x>0;x--)
for(y=z;y>0;y--);
}
voidt0_init()//T0初始化
{
TMOD=0x01;
TH0=(65536-200)/256;
TL0=(65536-200)%256;
TR0=1;
EA=1;
ET0=1;
}
voidselect_ch(uchara)//通道选择
{
switch(a)
{
case1:
ADDC=0,ADDB=0,ADDA=0;break;
case2:
ADDC=0,ADDB=0,ADDA=1;break;
case3:
ADDC=0,ADDB=1,ADDA=0;break;
case4:
ADDC=0,ADDB=1,ADDA=1;break;
case5:
ADDC=1,ADDB=0,ADDA=0;break;
case6:
ADDC=1,ADDB=0,ADDA=1;break;
case7:
ADDC=1,ADDB=1,ADDA=0;break;
case8:
ADDC=1,ADDB=1,ADDA=1;break;
}
}
uintadc()//模数转换
{
ALE=0;
ALE=1;
ALE=0;
while(EOC==0);
OE=1;
num=P0;
OE=0;
num=num*500.0/255;
returnnum;
}
uintkeyscan()
{
uchari,temp;
for(i=0;i<4;i++)
{
P1=~(1<
temp=P1;
temp=0xf0&temp;
while(temp!
=0xf0)
{
delay(5);
temp=P1;
temp=0xf0&temp;
while(temp!
=0xf0)
{
temp=P1;
switch(temp&0xf0)
{
case0xe0:
k=1+i*4;
break;
case0xd0:
k=2+i*4;
break;
case0xb0:
k=3+i*4;
break;
case0x70:
k=4+i*4;
break;
}
while(temp!
=0xf0)
{
temp=P1;
temp=0xf0&P1;
}
}
}
}
returnk;
}
voidwrite7219(ucharadd,uchardat)//7219
{
uchari;
LOAD=0;
for(i=0;i<8;i++)
{
CLK=0;
if(add&0x80)
DIN=1;
else
DIN=0;
add<<=1;
CLK=1;
}
for(i=0;i<8;i++)
{
CLK=0;
if(dat&0x80)
DIN=1;
else
DIN=0;
dat<<=1;
CLK=1;
}
LOAD=1;
}
voidinit7219()//7219初始化
{
write7219(Shut_down,0x01);//开启正常工作模式
write7219(Display_test,0x00);//选择工作模式
write7219(Decode_mode,0xff);//选用全译码模式
write7219(Scan_limit,0x03);//4个数码管选中
write7219(Intensity,0x08);//初始亮度
}
voidclear_7219()//清零