简易数字电压表设计内容
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
简易数字电压表设计
一、设计要求
1、利用ADC0809设计一简易数字电压表,要求可以测量0—5V之间8路输入电压值、电压值由四位LED数码管显示,并在数码管上轮流显示或单路选择显示;
2、测量最小分辨率为0.019V,测量误差为±0.02V。
二、设计作用与目的
利用AT89S51与ADC0809设计制作一个数字表,能够测量直流电压值。
三、所用设备及软件
单片机AT89S51、ADC0809芯片、PC设计台
四、系统设计方案
本设计采用AT89S51单片机芯片配合ADC0809模/数转换芯片构成一个简易的数字电压表,原理框图如图1所示。
该电路通过ADC0809芯片采样输入口IN0输入的0~5 V的模拟量电压,经过模/数转换后,产生相应的数字量经过其输出通道D0~D7传送给AT89S51芯片的P0口。
AT89S51负责把接收到的数字量经过数据处理,产生正确的7段数码管的显示段码,并通过其P1口经三极管驱动,再传送给数码管。
同时它还通过其三位I/O口P3.0、P3.1、P3.2产生位选信号,控制数码管的亮灭。
另外,AT89S51还控制着ADC0809的工作。
其ALE管脚为ADC0809提供了1MHz工作的时钟脉冲;P2.3控制ADC0809的地址锁存端(ALE);P2.4控制ADC0809的启动端(START);P2.5控制ADC0809的输出允许端(OE);P3.7控制ADC0809的转换结束信号(EOC)。
图1 系统原理框图
本设计与其它方法实现主要区别在于元器件上例如:AT89C51与AT89C51、AT89S51在AT89C51的基础上,又增加了许多功能,性能有了较大提升。
1.ISP在线编程功能,这个功能的优势在于改写单片机存储器内的程序不需要把芯片从工作环境中剥离。
是一个强大易用的功能。
2.工作频率为33MHz,大家都知道89C51的极限工作频率只有24M,就是说S51具有更高工作频率,从而具有了更快的计算速度。
3.具有双工UART串行通道。
4.内部集成看门狗计时器,不再需要像89C51那样外接看门狗计时器单元电路。
5.双数据指示器。
6.电源关闭标识。
7.全新的加密算法,这使得对于89S51的解密变为不可能,程序的保密性大大加强,这样就可以有效的保护知识产权不被侵犯。
8.兼容性方面:向下完全兼容51全部字系列产品。
比如8051、89C51等等早期MCS-51兼容产品。
在89C51上一样可以照常运行,这就是所谓的向下兼容。
五、系统硬件设计
5.1 模数转换芯片ADC0809
ADC0809是典型的8位8通道逐次逼近式A/D转换器。
它可以和微型计算机直接接口。
ADC0809转换器的系列芯片是ADC0808,可以相互替换。
5.1.1 ADC0809内部逻辑结构
图2 ADC0809的内部逻辑结构及引脚图
ADC0809的内部逻辑结构如图2所示。
图中多路模拟开关可选通8路模拟通道,允许8路模拟量分时输入,并共用一个A/D转换器进行转换。
地址锁存与译码电路完成对A、B、C三个地址位进行锁存与译码,如表1所示。
表1 ADC0809通道选择表
C(ADDC) B(ADDB) A(ADDA) 选择的通道
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
5.1.2 ADC0809的引脚
ADC0809芯片为28引脚双列直插式封装,其引脚排列如图2所示。
1.IN0~IN7:8路模拟量输入通道。
2.A、B、C:模拟通道地址线。
这3根地址线用于对8路模拟通道的选择,其译码关系如表1所示。
其中,A为低地址,C为高地址,引脚图中为ADDA,ADDB 和ADDC。
3.START:转换启动信号。
START上升沿时,复位ADC0809;START下降沿时启动芯片,开始进行A/D转换;在A/D转换期间,START应保持低电平。
本信号有时简写为ST。
4.D7~D0:数据输出线。
为三态缓冲输出形式,可以和单片机的数据线直接相连。
D0为最低位,D7为最高。
5.OE:输出允许信号。
用于控制三态输出锁存器向单片机输出转换得到的数据。
OE=0,输出数据线呈高阻;OE=1,输出转换得到的数据。
6.CLK:时钟信号。
ADC0809的内部没有时钟电路,所需时钟信号由外界提供,因此有时钟信号引脚。
通常使用频率为500KHz的时钟信号。
7.EOC:转换结束信号。
EOC=0,正在进行转换;EOC=1,转换结束。
使用中该状态信号即可作为查询的状态标志,又可作为中断请求信号使用。
8.Vcc: +5V电源,GND:地。
9.Vref:参考电压。
参考电压用来与输入的模拟信号进行比较,作为逐次逼近的基准。
其典型值为+5V(Vref(+)=+5V, Vref(-)=0V)。
3.1.3 ADC0809的工作原理
首先输入3位地址,并使ALE=1,将地址存入地址锁存器中。
此地址经译码选通8路模拟输入之一到比较器。
START上升沿将逐次逼近寄存器复位。
下降沿启动 A/D转换,之后EOC输出信号变低,指示转换正在进行。
直到A/D转换完成,EOC变为高电平,指示A/D转换结束,结果数据已存入锁存器,这个信号可用作中断申请。
当OE输入高电平时,输出三态门打开,转换结果的数字量输出到数据总线上。
(注意:ALE信号常与START信号连在一起,这样连接可以在信号的前沿写入地址信号,在其后沿启动A/D转换,图3为ADC0809信号的时序配合图)。
图3 ADC0809信号的时序配合
5.2 数据处理及控制芯片AT89S51
AT89S51是美国ATMEL公司生产的低功耗、高性能CMOS 8位单片机。
AT89S51片内含有4k字节Flash闪速存储器,128字节内部 RAM,32个I/O 口线,看门狗(WDT),两个数据指针,两个16 位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。
同时,S51可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。
空闲方式停止CPU的工作,但允许 RAM,定时/计数器,串行通信口及中断系统继续工作。
掉电方式保存 RAM 中的内容,但振荡器停止工作并禁止其它所有部件工作直到下一个硬件复位。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89S51是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
5.2.1 主要性能参数
1.与MCS-51产品指令系列完全兼容;
2.4K字节在系统编程(ISP)Flash闪速存储器;
3.1000次擦写周期;
4.4.0~
5.5 V工作电压范围;
5.全静态工作模式:0Hz~33MHz;
6.三级程序加密锁;
7.128字节内部RAM;
8.32个可编程I/O口线;
9.2个16位的定时/计数器;
10.6个中断源;
11.全双工串行UART通道;
12.低工耗空闲和掉电模式;
13.中断可从空闲模式唤醒系统;
14.看门狗(WDT)及双数据指针;
15.掉电标识和快速编程特性;
16.灵活的在系统编程(ISP-字节或页写模式)。
5.2.2 AT89S51的引脚
图4 AT89S51的引脚图
AT89S51芯片为40引脚双列直插式封装,其引脚排列如图4所示。
1.P2口:P2口是一个内部提供上拉电阻的8位双向I/O口,P2口的输出缓冲器可驱动4个TTL逻辑门电路。
对P2口管脚写入“1”后,被内部上拉电阻拉高,可用作输入。
P2口被外部下拉为低电平时,将输出电流,这是由于内部接有上拉电阻的缘故。
P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。
在访问8位地址外部数据存储器时,P2口线上的内容,在整个访问期间不改变。
P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
2.P3口:P3口是一个内部提供上拉电阻的8位双向I/O口,P3口的输出缓冲器可驱动4个TTL逻辑门电路。
对P3口管脚写入“1”后,被内部上拉电阻拉高,可用作输入。
P3口被外部下拉为低电平时,将输出电流,这是由于内部接
有上拉电阻的缘故。
P3口除了一般I/O线的功能外,还具有更为重要的第二功能,如表2所示。
P3口同时为FLASH编程和编程校验接收一些控制信号。
表2 P1口的第二功能
端口引脚第二功能
P1.5 MOSI(用于ISP编程)
P1.6 MISO(用于ISP编程)
P1.7 SCK(用于ISP编程)
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INTO(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(定时器0外部输入)
P3.5 T1(定时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)(1)VCC:电源电压;
(2)GND:接地;
(3)P0口:P0口是一组8位漏极开路双向I/O口,每位引脚可驱动8个TTL逻辑门路。
对P0口的管脚写“1”时,被定义为高阻抗输入。
在访问外部数据存储器或程序存储器时,它可以被定义为数据总线和地址总线的低八位。
在FLASH编程时,P0 口作为原码输入口;当FLASH进行校验时,P0输出原码,此时P0外部必须接上拉电阻。
(4)P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口的输出缓冲器可驱动4个TTL逻辑门电路。
对P1口管脚写入“1”后,被内部上拉电阻拉高,可用作输入。
P1口被外部下拉为低电平时,将输出电流,这是由于内部接有上拉电阻的缘故。
在FLASH编程和校验时,P1口作为低八位地址接收。
P1口还具有第二功能,如表3-2所示。
(5)RST:复位输入。
当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
(6) ALE//RPOG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。
在FLASH编程期间,此引脚用于输入编程脉冲。
在平时,ALE 端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。
因此它可用作对外部输出的脉冲或用于定时目的。
然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。
如想禁止ALE的输出可在SFR8EH地址上置0。
此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。
另外,该引脚被略微拉高。
如果微处理器在外部执行状态ALE禁止,置位无效。
(7)/PSEN:外部程序存储器的选通信号。
在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。
但在访问外部数据存储器时,这两次有效的信号将不出现。
(8)/EA/VPP:当保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。
注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。
在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
(9)XTAL1:片内高增益反向放大器的输入及内部时钟工作电路的输入。
(10)XTAL2:片内高增益反向放大器的输出端。
5.2.3 AT89S51的复位电路
AT89S51的复位电路如图5所示。
当单片机一上电,立即复位;另外,如果在运行中,外界干扰等因素使单片机的程序陷入死循环状态或“跑飞”,就可以通过按键使其复位。
复位也是使单片机退出低功耗工作方式而进入正常状态的一种操作。
图5 复位电路
电容C和电阻R1实现上电自动复位。
增加按键开关S和电阻R2又可实现按键复位功能。
R2的作用是在S按下的时候,防止电容C放电电流过大烧坏开关S 的触点。
因保证R1/R2 >10。
一般取C=10uF,R2=100Ω,R1=8.2KΩ。
5.2.4 AT89S51与ADC0809的连接
图6 AT89S51与ADC0809的连接电路
AT89S51与ADC0809的连接电路如图6所示。
AT89S51与ADC0809的连接必须注意处理好3个问题:
1.在START端送一个100ns宽的启动正脉冲;
2.获取EOC端上的状态信息,因为它是A/D转换的结束标志;
3.给“三态输出锁存器”分配一个端口地址,也就是给OE端送一个地址译码器的输出信号。
5.3 4位一体7段LED数码管
本设计的显示模块主要由一个4位一体的7段LED数码管(SM410564)构成,用于显示测量到的电压值。
它是一个共阳极的数码管,每一位数码管的原理图如图1-13所示。
每一位数码管的a,b,c,d,e,f,g和dp端都各自连接在一起,用于
接收AT89S51的P1口产生的显示段码。
1,2,3,4引脚端为其位选端,用于接收AT89S51的P3口产生的位选码。
图7为引脚图。
图7 一位数码管的原理图
5.4 整机电路及工作原理
本设计采用AT89S51单片机芯片配合ADC0809模/数转换芯片构成一个简易的数字电压表。
设计的硬件电路由主控部分(单片机AT89S51)、采集模拟量部分(A/D转换一路ADC0804)、显示部分(四位八段数码管)、报警电路(蜂鸣器)4个部分组成。
各部分之间相互协作,构成一个统一的有机整体,实现数字电压表的功能。
该电路通过ADC0809芯片采样输入口IN0输入的0~5 V的模拟量电压,经过模/数转换后,产生相应的数字量经过其输出通道D0~D7传送给AT89S51芯片的P0口。
AT89S51负责把接收到的数字量经过数据处理,产生正确的7段数码管的显示段码,并通过其P1口经驱动芯片74HC245驱动,再传送给数码管。
同时它还通过其三位I/O口P3.0、P3.1、P3.2产生位选信号,控制数码管的亮灭。
另外,AT89S51还控制着ADC0809的工作。
其ALE管脚为ADC0809提供了1MHz 工作的时钟脉冲;P2.3控制ADC0809的地址锁存端(ALE);P2.4控制ADC0809的启动端(START);P2.5控制ADC0809的输出允许端(OE);P3.7控制ADC0809的转换结束信号(EOC)。
六、系统软件设计
6.1 主程序设计
初始化中主要对AT89S51,ADC0809的管脚和数码管的位选及所用到的内存单元70H,78H,79H,7AH 进行初始化设置。
准备工作做好后便启动ADC0809对IN0脚输入进的0~5V电压模拟信号进行数据采集并转换成相对应的0~255十进制数字量。
在数据处理子程序中,运用标度变换知识,编写算法将0~255十进制数字量转换成0.00~5.00V的数据,输出到显示子程序进行显示。
整个主程序就是在A/D转换,数据处理及显示程序循环执行。
整个程序流程框图如图8所示。
图8 主程序流程图
6.2 各子程序设计
1.A/D转换子程序
启动ADC0809对模拟量输入信号进行转换,通过判断EOC(P3.1引脚)来确定转换是否完成,若EOC为0,则继续等待;若EOC为1,则把OE置位,将转换完成的数据存储到70H中。
程序流程图如图9所示。
图9 A/D转换程序流程图
2.数据处理子程序
数据处理子程序主要根据标度变换公式,把0~255十进制数转换为0.00~5.00V。
Ax 0+(Am-A0)*(Nx-N0)/(Nm-N0)
A
Ax:模拟测量值; A0:模拟量输入最小值; Am:模拟量输入最大值;
Nx:摸/数转换后的数值; N0:摸数转换后的最小值; Nm摸/数转换的最大值。
在本设计中,根据要求知:
A0=0V,Am=5V,N0=0,Nm=255
则公式1-1可化简为:
Ax=A0+(Am-A0)*(Nx-N0)/(Nm-N0)=5Nx/255=Nx/51 程序流程图如图10所示。
图10 数据处理子程序流程图
3.显示子程序
显示子程序采用动态扫描法实现三位数码管的数值显示。
测量所得的A/D 转换数据放在70H内存单元中,测量数据在显示时需转换成10进制BCD码放在78H~7AH单元中。
寄存器R1用作显示数据地址指针。
程序流程图如图11所示。
图11 显示子程序流程图
七、仿真调试分析
7.1 仿真工具
Proteus具有4大功能模块
1.智能原理图设计(ISIS)
2.完善的电路仿真功能(Prospice)
3.独特的单片机协同仿真功能(VSM)
4.实用的PCB设计平台
Proteus ISIS是英国Labcenter公司开发的电路分析与实物仿真软件。
它运行于Windows操作系统上,可以仿真、分析(SPICE)各种模拟器件和集成电路,
该软件的特点是:①实现了单片机仿真和SPICE电路仿真相结合。
具有模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统的仿真、RS232动态仿真、I2C调试器、SPI调试器、键盘和LCD系统仿真的功能;有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等。
②支持主流单片机系统的仿真。
目前支持的单片机类型有:68000系列、8051系列、AVR系列、PIC12系列、PIC16系列、PIC18系列、Z80系列、HC11系列以及各种外围芯片。
③提供软件调试功能。
在硬件仿真系统中具有全速、单步、设置断点等调试功能,同时可以观察各个变量、寄存器等的当前状态,因此在该软件仿真系统中,也必须具有这些功能;同时支持第三方的软件编译和调试环境,如Keil C51 uVision2等软件。
④具有强大的原理图绘制功能。
总之,该软件是一款集单片机和SPICE分析于一身的仿真软件,功能极其强大。
7.2 仿真步骤
在PROTEUS绘制好原理图后,调入已编译好的目标代码文件:*.HEX,可以在PROTEUS的原理图中看到模拟的实物运行状态和过程。
图12 仿真图
7.3 测量结果
本设计经过对所设计的对象的程序以及对原理图进行了修改完善成功的取
得了一组测量数据,通过对LED显示管所显示的数字与通过用模拟电压表所测得
的数值进行比较以便更加说明本设计的可靠性。
所测数据如表3所示。
表3 测量结果显示
LED显示数值(V) 0.45 1.07 2.21 3.15 4.00 4.60 5.00 模拟值测量数(V) 0.458 1.075 2.2 3.158 4.060 4.620 4.99
八、设计中的问题及解决方法
1.在应用滤波电容的过程中,一开始是把电容串联在电路中,导致电路无法
导通,而后我们短路电容,解决了问题。
2.电源指示灯上,一开始发现接上电源,指示灯不亮,经过仪器测量发现正
负极接反,问题解决。
3.焊接完成后接上电源发现数码显示管最后一个某一段不发光,经过检查之
后发现了虚焊点,重焊之后正常显示。
4.由于源程序的多处错误,使得仿真无法通过,后经过单步调试,把存在的
错误一一排除,通过了软件仿真。
九、学习心得
通过本次课题设计,我们对单片机这门课程有了更进一步的了解。
无论是在
其硬件连接方面还是在软件编程方面,都取得了新的收获。
本次实验采用了
AT89S51单片机芯片,与以往我们我们所熟悉的C51芯片有许多不同之处,通过
本次实验及查阅相关资料,我们对其之间的区别有了一定的认识,在本课题设计
报告的硬件介绍部分也对其作了详细的论述。
S51在C51的基础上增加了许多新
的功能,使其功能更为完善,应用领域也更为广泛。
另外,在对单片机编程方面,
我们又掌握了一些新的编程思想,使得程序更为简练、易懂,而且更为严谨,程
序执行的稳定性得到了提高。
实验中我们还用到了模/数转换芯片ADC0809,以前在学单片机这门课程时
只是对其理论知识有了初步的了解。
通过本次实验,我们对它的工作原理彻底理
解了,对其启动设置、转换结束判断以及输出控制等都基本掌握。
电路连接方面,
我们对其与单片机的连接也有了更为直观的认识,通过实验的摸索以及必要的理论知识,我们准确的实现了它于单片机的互连。
十、参考文献
[1] 康华光.电子技术基础.数字部分.北京:高等教育出版社, 2000
[2] 顾永杰.电工电子技术实训教程.上海:上海交通大学出版社, 1999
[3] 陈小虎.电工实习(I).北京:中国电力出版社,1996
[4] 焦辎厚.电子工艺实习教程.哈尔滨:哈尔滨工业大学出版社, 1993
[5] 陈坚.电力电子学[M].北京:高等教育出版社, 2002
[6] 宋春荣.通用集成电路速查手册.山东:山东科学技术出版社, 1995
[7] 高吉祥.电子技术基础实验与课程设计.北京:电子工业出版社, 2002
[8] 吕思忠.数子电路实验与课程设计.哈尔滨:哈尔滨工业大学出版社, 2001
[9] 谢自美.电子线路设计、实验、测试.武汉:华中理工大学出版社, 2000
附录一整机原理图
附录二程序清单
#include<reg52.h>
Unsigned char code
dispbitcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //显示0~9
unsigned char dispbuf[4];//存放数组
unsigned char getdata;
unsigned int temp;
sbit ST=P3^0; //位申明
sbit OE=P3^1;
sbit EOC=P3^2;
sbit CLK=P3^3;
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit P17=P1^7;
sbit bb=P3^7;
//unsigned char o;
void TimeInitial();
void Delay(unsigned int i);
void TimeInitial() //定时器初始化
{
TMOD=0x11; //定时器T1工作于方式1
TH1=(65536-200)/256; //赋初值
TL1=(65536-200)%256;
TH0=(65536-2000)/256; //进入赋初值
TL0=(65536-2000)%256;
EA=1; //开总中断
ET1=1;
ET0=1; //开中断T1
TR1=1; //启动T1 }
void Delay(unsigned int i) //延时函数{
unsigned int j,k;
for(k=0;k<i;k++)
for(j=0;j<125;j++);
}
void Display() //显示子函数
{
P1=dispbitcode[dispbuf[3]];
P20=0;
P21=1;
P22=1;
P23=1;
Delay(10);
P1=0x00;
P1=dispbitcode[dispbuf[2]];
P17=1;
P20=1;
P21=0;
P22=1;
P23=1;
Delay(10);
P1=0x00;
P1=dispbitcode[dispbuf[1]];
P20=1;
P21=1;
P22=0;
P23=1;
Delay(10);
P1=0x00;
P1=dispbitcode[dispbuf[0]];
P20=1;
P21=1;
P22=1;
P23=0;
Delay(10);
P1=0x00;
}
void main() //主函数{ //初始化
TimeInitial();
while(1)
{
ST=0;
OE=0;
ST=1;
ST=0;
while(EOC==0); //等待
OE=1;
getdata=P0;
OE=0;
if(getdata>=255)
{
TR0=1;
}
else
TR0=0;
temp=getdata*1.0/255*500; //三位显示
dispbuf[0]=temp%10; //个位
dispbuf[1]=temp/10%10; //十位
dispbuf[2]=temp/100; //百位
dispbuf[3]=temp/1000; //千位
Display(); //显示函数调用
}
}
void t1(void) interrupt 3 using 0 //中断用T1 {
TH1=(65536-200)/256; //进入赋初值 TL1=(65536-200)%256;
CLK=~CLK; //时钟取反
}
void t0(void) interrupt 1 using 0 //中断用T1 {
TH0=(65536-2000)/256; //进入赋初值 TL0=(65536-2000)%256;
bb=~bb; //报警程序
}。