制作出来的实物图如下:
实物工作图
设计要求系统能实现电压测量,检测技术指标为: ①测量范围为0-10V ②测量精度:±0.1V ③通过显示器进行显示当前电压值,显示到小数点后两位 2.2系统简介⑴根据设计要求,选择AT89C51单片机为核心控制器件。 ⑵A/D转换采用ADC0832实现。 ⑶电压显示采用4位一体的LED数码管。 ⑷LED数码的段码输入,由并行端口P2产生:位码输入,用并行端口P0产生。 2.3方案比较(一)、采用FPGA进行设计 采用FPGA进行设计的系统流程图如图2-1所示 图2-1 FPGA设计系统流程图 FPGA内部集成锁项环,可以把外部时钟倍频,核心频率可以到几百M,而单片机运行速度低的多.在高速场合,单片机无法代替FPGA。虽然FPGA在频率范围和逻辑实现方面要高出单片机一块。但是由于没有指令系统,所以控制和运算能力比较弱。 (二)、采用单片机控制 采用单片机进行设计的系统流程图如图2-2所示 图2-2 单片机设计系统流程图 数字电压表的一种设计方案是以单片机为核心操作系统, 硬件电路设计由6个部分组成; A/D转换电路,AT89C51单片机系统,LED显示系统、时钟电路、复位电路以及测量电压输入电路。 应用单片机操作系统的好处是能准确有效的输入电压值、操作简单、技术成熟、算法较为灵活、成本费用低。
3硬件电路设计
3.1 AT89C51单片机简介AT89C51是一个低功耗,高性能CMOS 8位单片机,片内含4k Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,AT89C51在众多嵌入式控制应用系统中得到广泛应用。51单片机内包含以下几个部件: - 8位微处理器(CPU)。
- 数据存储器(128B RAM)。
- 程序存储器(ROM/EPROM)。
- 4个8位可编程并行I/O口(P0口,P1口,P2口,P3口)。
- 1个全双工的异步串行口。
- 2个16定时器/计数器。
- 中断系统。
- 特殊功能寄存器(SFR)。
单片机片内结构如图3-1所示:
图3-1 单片机片内结构 3.2 ADC0832转换器简介ADC0832是一种8 位分辨率、双通道A/D转换芯片。由于它体积小,兼容性强,性价比高而深受单片机爱好者及企业欢迎,其目前已经有很高的普及率。学习并使用ADC0832 可是使我们了解A/D转换器的原理,有助于我们单片机技术水平的提高。芯片如下图3-2所示: 图3-2 ADC0809 芯片接口说明如下: CS_ 片选使能,低电平芯片使能。 CH0 模拟输入通道0,或作为IN+/-使用。 CH1 模拟输入通道1,或作为IN+/-使用。 GND 芯片参考0 电位(地)。 DI 数据信号输入,选择通道控制。 DO 数据信号输出,转换数据输出。 CLK 芯片时钟输入。 Vcc/REF 电源输入及参考电压输入(复用)。 工作原理如下: 正常情况下ADC0832 与单片机的接口应为4条数据线,分别是CS、CLK、DO、DI。但由于DO端与DI端在通信时并未同时有效并与单片机的接口是双向的,所以电路设计时可以将DO和DI 并联在一根数据线上使用。当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用,CLK 和DO/DI 的电平可任意。当要进行A/D转换时,须先将CS使能端置于低电平并且保持低电平直到转换完全结束。此时芯片开始转换工作,同时由处理器向芯片时钟输入端CLK 输入时钟脉冲,DO/DI端则使用DI端输入通道功能选择的数据信号。在第1 个时钟脉冲的下沉之前DI端必须是高电平,表示启始信号。在第2、3个脉冲下沉之前DI端应输入2 位数据用于选择通道功能。当此2 位数据为“1”、“0”时,只对CH0 进行单通道转换。当2位数据为“1”、“1”时,只对CH1进行单通道转换。当2 位数据为“0”、 “0”时,将CH0作为正输入端IN+,CH1作为负输入端IN-进行输入。当2 位数据为“0”、“1”时,将CH0作为负输入端IN-,CH1 作为正输入端IN+进行输入。到第3 个脉冲的下沉之后DI端的输入电平就失去输入作用,此后DO/DI端则开始利用数据输出DO进行转换数据的读取。从第4个脉冲下沉开始由DO端输出转换数据最高位DATA7,随后每一个脉冲下沉DO端输出下一位数据。直到第11个脉冲时发出最低位数据DATA0,一个字节的数据输出完成。也正是从此位开始输出下一个相反字节的数据,即从第11个字节的下沉输出DATD0。随后输出8位数据,到第19 个脉冲时数据输出完成,也标志着一次A/D转换的结束。最后将CS置高电平禁用芯片,直接将转换后的数据进行处理就可以了。 3.3 时钟电路XTAL1是片内振荡器的反相放大器输入端,XTAL2则是输出端,使用外部振荡器时,外部振荡信号应直接加到XTAL1,而XTAL2悬空。内部方式时,时钟发生器对振荡脉冲二分频,如晶振为12MHz,时钟频率就为6MHz。晶振的频率可以在1MHz-24MHz内选择。电容取30PF左右。系统的时钟电路设计是采用的内部方式,即利用芯片内部的振荡电路如下图3-3所示: 图3-3 时钟电路 3.4 复位电路由电容串联电阻构成,由图并结合"电容电压不能突变"的性质,可以知道,当系统一上电,RST脚将会出现高电平,并且,这个高电平持续的时间由电路的RC值来决定.典型的51单片机当RST脚的高电平持续两个机器周期以上就将复位,所以,适当组合RC的取值就可以保证可靠的复位.一般教科书推荐C 取10u,R取8.2K.当然也有其他取法的,原则就是要让RC组合可以在RST脚上产生不少于2个机周期的高电平.至于如何具体定量计算,可以参考电路分析相关书籍.复位电路如下图3-4所示。
图3-4 复位电路 3.5 LED显示电路本项目所用显示屏为4位LED显示屏。本LED显示器为8段(DP为小数点段),每一段为一个发光二极管。发光二极管有共阳极和共阴极两种。本显示器的发光二极管为共阳极数码管。发光二极管的阳极连接在一起,通常在此共阳极接正电压,当某个发光二极管的阴极接低电平时,发光二极管被点亮,相应的段被显示。通过给LED显示器提供不同的代码,是这些不同的LED显示器相应的段发光显示不同的字型,这些代码称为段码。 本项目所用段码值如下 (表 1) 所示: 表1 4 软件程序设计
4.1系统整体软件设计设计的环境Keil是德国知名软件公司Keil (现已并入ARM公司)开发的微控制器软件开发平台,是目前ARM内核单片机开发的主流工具。KEIL提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器在内的完整开发方案,通过-一个集成开发环境( uVision )将这些功能组合在一起。 uVision当前最 高版本是uVision3,它的界面和常用的微软VC+ +的界面相似,界面友好,易学易用,在调试程序,软件仿真方面也有很强大的功能。因此很多开发ARM应用的工程师,都对它十分喜欢。 使用Keil来开发嵌入式软件,开发周期和其他的平台软件开发周期是差不多的,大致有以下几个步骤: 1.创建一个工程,选择一块目标芯片,且做一些必要的工程配置。 2.编写C或者汇编源文件。 3.编译应用程序。 4.修改源程序中的错误。 5.联机调试。 Proteus是英国Labcenter公司的电路分析与实物仿真软件,可以仿真分析(Spice)各种模拟器件和集成电路,该软件的特点是: (1)实现了单片机仿真和Spice电路仿真相结合。具有模拟电路仿真数字电路仿真郸机及其外围电路组成的系统的仿真RS 232动态仿真、I2C调试器、SPI调试器、键盘和LCD系统仿真的功能;有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等。 (2)支持主流单片机系统的仿真。目前支持的单片机类型有: 68000系列、8051系列、AVR系列、PIC12系列、PIC16系列、 PIC18系列、 Z80系列、 HC11系列以及各种外围芯片。 (3)提供软件调试功能。在硬件仿真系统中具有全速、步设置断点等调试功能,同时可以观察各个变量、存器等的当前状态,因此在该软件仿真系统中,也必须具有这些功能;同时支持第三方的软件编译和调试环境,如Keil C51 μVision 2等软件。 (4)具有强大的原理图绘制功能。启动Proteus后将出现ISIS的设计窗口 ,如图1所示。包括:标题栏、主菜单、标准工具栏、绘图工具栏、状态栏、对象选择按钮、预览对象方位控制按钮、仿真进程控制按钮(最下面一行)、 预览窗口、对象选择器窗口、图形编辑窗口。 4.2软件设计流程图4.2.1程序设计总方案根据模块的划分原则,将该程序划分初始化模块,A/D转换子程序和显示子程序,这三个程序模块构成了整个系统软件的主程序,如图4-1所示。 图4.1 数字式直流电压表主程序框图 4.2.2 系统子程序设计(一)初始化程序 所谓初始化,是对将要用到的51系列单片机内部部件或扩展芯片进行初始工作状态设定,初始化子程序的主要工作是设置定时器的工作模式,初值预置,开中断和打开定时器等。 (二)AD转换子程序 A/D转换子程序用来控制对输入的模块电压信号的采集测量,并将对应的数值存入相应的内存单元,其转换流程图如图4-2所示。 图4-2 AD转换子程序 (三) 显示子程序 显示子程序采用动态扫描实现四位数码管的数值显示,在采用动态扫描显示方式时,要使得LED显示的比较均匀,又有足够的亮度,需要设置适当的扫描频率,当扫描频率在70HZ左右时,能够产生比较好的显示效果,一般可以采用间隔10ms对LED进行动态扫描一次,每一位LED的显示时间为1ms。 在本设计中,为了简化硬件设计,主要采用软件定时的方式,即用定时器0溢出中断功能实现11μs定时,通过软件延时程序来实现5ms的延时。显示子程序流程图如图4-3所示。 图4-3 显示子程序流程图
5 系统调试
5.1 硬件调试在系统上电开始测量前,要用万用表的电压档对被测电压进行估测,然后以此选择适当的量程,防止过大电压烧坏A/D转换器。首先用万用表按照原理图逐步检查中各器件的电源及各引脚的连接是否正确,有否断路、短路或者虚焊,尤其是给电路供电的电源部分需重点检查,用数字万用表测量0832输出端的电压是否是+10V,是否稳定,能够输出+10V,且稳定即可说明电源电路的设计基本达到目的要求。如果电压没有达到预期要求,要及时排查解决,以免烧坏芯片和其他元器件。 软件调试时先进行单元测试,分别对各个代码模块进行测试,看其是否实现了规定功能,再把已经测试过的模块组合起来进行调试,一旦不能正确运行,要找出程序中的代码错误,确定大致的错误位置,研究有关部分的错误程序,找出错误的原因,修改设计和代码,以排除故障。 我们在程序编写完成后,就能利用仿真器初步调试,观察在计算机里能否通过编译与运行并且达到设计的基本要求。在基本符合的情况下,利用仿真器和工作正常的硬件连接进行仿真调试;或用编程器把程序烧写到芯片中,直接观察能否正常运行。如果达不到设计要求或者不能正常运行,能直接在程序中进行编译和修改。 系统调试中遇到的问题及解决的方法: 1)在应用滤波电容的过程中,开始时是把电容串联在电路中,导致电路无法导通,而后我们短路电容,解决了问题。 2)电源指示灯上,一开始发现接上电源,指示灯不亮,经过仪器测量发现正负极接反,后重新焊接。 3)由于源程序的多处错误,使得仿真无法通过,后经过单步调试,把存在的错误一一排除,通过了软件仿真。 4)在烧录芯片的过程中,由于选择烧录文件的错及芯片质量的问题(因多次烧录,无法再次烧录)使得烧录失败,后经过查阅资料并且更换了AT89C51芯片,解决了问题。 系统原理图如图5-1所示 图5-1 系统原理图 5.2软件调试本设计应用Proteus6及KEIL51软件,首先根据自己设计的电路图用Proteus6软件画出电路模型,关于这个软件的使用通过查一些资料和自己的摸索学习;然后我们用KEIL51软件对所编写的程序进行编译、链接,如果没有错误和警告便可生成程序的hex文件,将此文件加到电路图上使软硬件结合运行,最后进行端口电压的对比测试,测试的第一路对比见图5.2中标准电压值采用Proteus6软件中的模拟电压表测得。 图5-2 仿真结果图 6 总结经过一段时间的努力,基于单片机的简易数字电压表基本完成。但设计中的不足之处仍然存在。这次设计是我第一次设计电路,并用Proteus实现了仿真。在这过程中,我对电路设计,单片机的使用等都有了新的认识。通过这次设计学会了Proteus和Keil软件的使用方法,掌握了从系统的需要、方案的设计、功能模块的划分、原理图的设计和电路图的仿真的设计流程,积累了不少经验。 基于单片机的数字电压表使用性强、结构简单、成本低、外接元件少。在实际应用工作应能好,测量电压准确,精度高。系统功能、指标达到了课题的预期要求、系统在硬件设计上充分考虑了可扩展性,经过一定的改造,可以增加功能。本文设计主要实现了简易数字电压表测量一路电压的功能,详细说明了从原理图的设计、电路图的仿真再到软件的调试。 通过本次设计,我对单片机这门课有了进一步的了解。无论是在硬件连接方面还是在软件编程方面。本次设计采用了AT89C51单片机芯片,与以往的单片机相比增加了许多新的功能,使其功能更为完善,应用领域也更为广泛。设计中还用到了模/数转换芯片ADC0832,以前在学单片机时只是对其理论知识有了初步的理解。通过这次设计,对它的工作原理有了更深的理解。在调试过程中遇到很多问题,硬件上的理论知识学得不够扎实,对电路的仿真方面也不够熟练。 总之这次电路的设计和仿真,基本上达到了设计的功能要求。在以后的实践中,我将继续努力学习电路设计方面的理论知识,并理论联系实际,争取在电路设计方面能有所提升。 通过这次设计,使我深入了解了AT89C51单片机和ADC0832(A\D转换器)的结构和特点及数字电压表的工作原理,加深了对课本理论知识的理解,锻炼了实践动手能力,理论知识与实践设计相结合,培养了创新开发的思维。在此次设计中,收获知识的同时,我还收获了阅历。在此过程中,我们通过查找资料,以及不懈的努力,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。
在电量的测量中,电压、电流和频率是最基本的三个被测量,其中电压量的测量最为经常。而且随着电子技术的发展,更是经常需要测量高精度的电压,所以数字电压表就成为一种必不可少的测量仪器。数字电压表简称DVM,它是采用数字化测量技术,把连续的模拟量转换成不连续、离散的数字形式并加以显示的仪表。由于数字式仪器具有读数准确方便、精度高、误差小、测量速度快等特而得到广泛应用。
传统的指针式刻度电压表功能单一,进度低,容易引起视差和视觉疲劳,因而不能满足数字化时代的需要。采用单片机的数字电压表,将连续的模拟量如直流电压转换成不连续的离散的数字形式并加以显示,从而精度高、抗干扰能力强,可扩展性强、集成方便,还可与PC实时通信。数字电压表是诸多数字化仪表的核心与基础。以数字电压表为核心,可以扩展成各种通用数字仪表、专用数字仪表及各种非电量的数字化仪表。目前,由各种单片机和A/D转换器构成的数字电压表作全面深入的了解是很有必要的。
最近的几十年来,随着半导体技术、集成电路(IC)和微处理器技术的发展,数字电路和数字化测量技术也有了巨大的进步,从而促使了数字电压表的快速发展,并不断出现新的类型。数字电压表从1952年问世以来,经历了不断改进的过程,从最早采用继电器、电子管和形式发展到了现在的全固态化、集成化(IC化),另一方面,精度也从0.01%-0.005%。
目前,数字电压表的内部核心部件是A/D转换器,转换的精度很大程度上影响着数字电压表的准确度,因而,以后数字电压表的发展就着眼在高精度和低成本这两个方面。
本文是以简易数字直流电压表的设计为研究内容,本系统主要包括三大模块:转换模块、数据处理模块及显示模块。其中,A/D转换采用ADC0832对输入的模拟信号进行转换,控制核心AT89C51再对转换的结果进行运算处理,最后驱动输出装置LED显示数字电压信号。
背景及意义
众所周知,在当今的社会中电已成为人们日常生产,生活中一个必不可缺的因素。电的发现和应用极大的节省了人类的体力劳动和脑力劳动,使人类的力量长上了翅膀,使人类的信息触角不断延伸。而在这其中,电压,电流等已成为描述电的一-些重要参数。
在电气测量中,电压是一个很重要的参数。如何准确地测量模拟信号的电压值,一直是电测仪器研究的内容之一。数字电压表是通用仪器中使用较广泛的种测试仪器,很多电量或非电量经变化后都用可数字电压表完成测试。目前,由各种单片A/D转换器构成的数字电压表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,显示出强大的生命力。
这个课题的目的和意义在于使自己掌握对数字电压表的理解,自己动手设计数字电压表与仿真,它可以广泛的应用于电压测量外,通过各种变换器还可以测量其它电量和非电量,测量是一种认识过程吗,就是用实验的方法将被测量和被选用的相同参量进行比较,从而确定它的大小。DVM广泛应用于测量领域每期测量的准确度和可信度取决于它的主要性能和技术指标。所以我们要学习和掌握如何设计DVM就显得十分重要。
设计内容主要包括:查资料、总体设计、元器件选型、原理图、PCB图、仿真、实物制作和调试、实践训练文档和验收六个部分。实训的最后要求是写出实训文档,把总体设计、原理图、元器件选型、PCB过程进行全面的说明,上升到一定高度。
电压的测量虽然在电量测量中是最基本的,但在电气测量中却占据着重要的地位。当代的测量仪器的研究是在电压的基础上才能实现的,因此电压测量已成为研究的重点之一。时代的发展,促使人类技术的不断进步,现代用到的测量技术都是依靠高精度的测量仪器,并且随着计算机的发展,测量技术融合计算机的功能,使得现代测量技术具有存储、计算、控制、显示、语音等功能。
以单片机为主控电路的高科技电子仪器仪表,不仅具有测量精确度高,灵敏度高和分辨率高的特点,还具有可靠性,稳定性强,测量速度快,通信,可存储等的优点。关于它的应用非常广泛。现已广泛应用于电子、电气测量,工业自动化仪表,自动测试系统等。现代检测技术中,常需用高精度数字电压表进行现场检测,将检测到的数据送入微计算机系统,完成计算、存储、控制和显示等功能。
数字电压表利用A/D转换原理,将被测模拟量转换成数字量,并用数字方式显示测量结果的电子测量仪表。A/D转换器的精度影响数字万用表的准确度,本文采AT89C51单片机,内部自带的A/D转换器将输入模拟信号进行转换,单片机对转换的结果进行运算和处理,最后驱动输出装置显示数字电压信号,通过Proteus仿真软件实现接口电路设计,并进行实时仿真。
电压的测量虽然在电量测量中是最基本的,但在电气测量中却占据着重要的地位。当代的测量仪器的研究是在电压的基础上才能实现的,因此电压测量已成为研究的重点之一。
原理图
仿真图
程序
#include <reg51.h>
#include <intrins.h>
/*********************************端口定义**********************************/
sbit CS = P3^5;
sbit Clk = P3^3;
sbit DATI = P3^4;
sbit DATO = P3^4;
sbit DIAN = P0^5; //小数点
/*******************************定义全局变量********************************/
unsigned char dat = 0x00; //AD值
unsigned char count = 0x00; //定时器计数
unsigned char CH; //通道变量
unsigned char dis[4]; //显示数值
unsigned int sum=0;
/*******************************共阴LED段码表*******************************/
unsigned char code tab[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7};
char code tablewe[]={ 0xfd,0xfb,0xf7,0xef,0xdf,0xfe };
/****************************************************************************
函数功能:AD转换子程序
入口参数:CH
出口参数:dat
****************************************************************************/
unsigned char adc0832(unsigned char CH)
{
unsigned char i,test,adval;
adval = 0x00;
test = 0x00;
Clk = 0; //初始化
DATI = 1;
_nop_();
CS = 0;
_nop_();
Clk = 1;
_nop_();
if ( CH == 0x00 ) //通道选择
{
Clk = 0;
DATI = 1; //通道0的第一位
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 0; //通道0的第二位
_nop_();
Clk = 1;
_nop_();
}
else
{
Clk = 0;
DATI = 1; //通道1的第一位
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 1; //通道1的第二位
_nop_();
Clk = 1;
_nop_();
}
Clk = 0;
DATI = 1;
for( i = 0;i < 8;i++ ) //读取前8位的值
{
_nop_();
adval <<= 1;
Clk = 1;
_nop_();
Clk = 0;
if (DATO)
adval |= 0x01;
else
adval |= 0x00;
}
for (i = 0; i < 8; i++) //读取后8位的值
{
test >>= 1;
if (DATO)
test |= 0x80;
else
test |= 0x00;
_nop_();
Clk = 1;
_nop_();
Clk = 0;
}
if (adval == test) //比较前8位与后8位的值,如果不相同舍去。若一直出现显示为零,请将该行去掉
dat = test;
nop_();
CS = 1; //释放ADC0832
DATO = 1;
Clk = 1;
return dat;
}
/****************************************************************************
函数功能:延时子程序
入口参数:
出口参数:
****************************************************************************/
void delay(void)
{
int k;
for(k=10;k<500;k++);
}
/****************************************************************************
函数功能:将0-255级换算成0.00-5.00的电压数值
入口参数:i
出口参数:
****************************************************************************/
void convdata(unsigned int i)
{
i=i*1.96;
dis[0] = i/100; //个位
dis[1] = i%100/10; //小数点后第一位
dis[2] = i%100%10; //小数点后第二位
// dis[3] = i%1000%100%10;
}
/****************************************************************************
函数功能:数码管显示子程序
入口参数:
出口参数:
****************************************************************************/
void display(void)
{
P0=tab[dis[0]]; //显示个位和小数点11011111
DIAN=1;
P2=0xdf; //11011111
delay();
P2=0xff;
P0=tab[dis[1]]; //显示小数点后第一位
P2=0xbf; //10111111
delay();
P2=0xff;
P0=tab[dis[2]]; //显示小数点后第二位
P2=0x7f; //01111111
delay();
P2=0xff;
}
/****************************************************************************
函数功能:主程序
入口参数:
出口参数:
****************************************************************************/
void main(void)
{
unsigned char m;
CH = 0x00; //在这里选择通道 0x00或0x01
while(1) //主循环
{
for(m=0;m<50;m++)
{
dat = adc0832(CH);
sum=sum+dat;
display(); //显示数值
}
dat=sum/50;
sum=0;
convdata(dat); //数据转换
display(); //显示数值
}
}
Keil代码与Proteus仿真下载:
123.7z
(783.35 KB, 下载次数: 117)
以上文档:
word文档.doc
(1.19 MB, 下载次数: 37)
|