s作品名:数字电压表学院:电气工程学院专业:姓名:学号:指导老师:目录第一章:设计方案…………………………….3第二章:硬件电路设计……………………….42.1主控芯片.....................................42.2模数转换部分……………………………………….42.3显示模块……………………………………………….6第三章:软件设计……………………………………….73.1主程序设计…………………………………………..73.2A/D转换子模块…………………………………...8第四章:系统调试……………………………………….94.1硬件调试………………………………………………..94.1.1硬件故障…………………………………………….94.1.2硬件调试方法……………………………………..94.2软件调试…………………………………………………94.2.1软件故障……………………………………….94.2.2软件调试方法…………………………………9第五章:实验数据处理.……………………………..105.1实验数据………………………………………..105.2实验数据分析………………………………….10第六章:结论……………………………………………….11附录一:作品图……………………………………………11附录二:程序……………………………………………….12第一章:设计方案基于51单片机,以ADC0804芯片实现模数转换,由1602液晶屏显示,具有量程变换功能。量程转换模块ADC0804模数转换模块单片机控制模块1602LED显示模块上电复位串口通信ADC08041602LED显示电源电路AT89C51P0P2P1P3第二章:硬件设计2.1主控芯片本电压表采用STC89C52为主控芯片,电路如下图所接:晶振电路和复位电路略去,端口和上面各图的接口是一致的。2.2模拟转换部分该电压表采用的ADC0804,此芯片优点是并行输出,速率快,缺点是只有8位,精度不高。下来ADC0804芯片图:为了方便,将数字地和模拟地都直接接到了一起,DB0~DB7为并行输出口,CS,RD,WR为控制芯片模数转换及读取芯片数据和写数据的引脚,ADC0804可以自己产生时钟,只要在CLKR和CLKIN端接入电阻(10K)和电容(理论为150pf本人接的220pf),可产生脉冲信号。VREF为参考电压端,VIN+和VIN-为电压输入端。当电压加在VIN+和VIN-端时,在DB0~DB7可输出八位到单片机,本处参考电压为5V,则当输入电压U时,输出数据为temp,则U/temp=5/255.在自然状态下,最多也只能测5V电压,为了扩大量程,本人加了衰减网络,见下图:接到ADC芯片上面的始终是VIN和地之前的电压,为了调精度,在上面加了滑动变阻器。此处R22选用的是470K欧的,首先选的10K,因为内阻过小,导致在5V以下的电压测量不准确,choice和GND两端为外加的电压,这样,有部分电压会在R20或者R21上分压,只在保证在R22两端不超过5V,就可实现多量程电压测量。2.3显示模块本处用1602液晶显示,1602优点是价格便宜,可显示基本字符,对于做电压表这样的东西已足够。电路如下:第三章:软件设计3.1主程序主程序包括初始化部分调用A/D转换子程序和调用显示程序,如下图所示:3.2A/D转换子模块:A/D转换子程序用于对ADC0804八路输入模拟电压进行A/D转换,并将转换的数值存入八个相应的存储单元中,如下图:开始启动一次转换取数据(OE=1)A/D转换结束?返回0804地址加1地址小于8第四章:系统调试基于单片机的数字电压表在组装好以后,便可进入系统的在线调试,起主要任务是排除样机硬件故障并完善其硬件结构,试运行所设计的程序,排除程序错误,优化程序结构,使系统达到预期的功能,进而固化软件。4.1硬件调试单片机应用系统的硬件和软件调试时交叉进行的,但通常是先排除样机中明显的硬件故障,尤其是电源故障,才能安全和仿真器相连,进行综合调试。4.1.1硬件电路故障(1)错线开路短路;(2)元器件损坏(3)电源故障4.1.2硬件调试方法本设计调试中所用的调试方法是静态测试:在样机加电之前,首先用万用表等工具,根据硬件电器原理图和装配图仔细检查样机线路的正确性,并核对元器件的型号规格和安装是否符合要求。第二步是加电后检查各插件上引脚的点位,仔细测量各电位是否正常。第三步是在不加电的情况下,除单片机以外,插上所有的元器件,最后用仿真适配器将样机的单片机插座盒仿真器的仿真接口相连,为联机调试做准备。4.2软件调试4.2.1软件电路故障(1)当以断点或连续方式运行时,目标系统没有按规定的功能进行操作或什么结果也没有,这是由于程序转移到意外之外或在某处死循环所造成的。(2)结果不正确4.2.1软件调试方法软件调试所使用的方法有:计算程序的调试方法,I/O处理程序的调试法,综合调试法第五章:实验数据处理5.1实验数据0-5V量程为0-50V量程次数标准值电压示值满度误差次数标准值电压示值满度误差10.760.7250.70%11.341.50.52%21.111.0780.64%22.352.50.30%31.661.6270.66%34.424.70.56%41.991.9600.60%47.177.10.14%52.172.1560.28%510.610.11.00%62.462.4500.20%613.012.90.20%72.702.6860.28%714.614.40.40%82.852.8430.14%816.716.11.00%93.033.0190.22%918.217.61.20%103.153.156-0.12%1019.518.91.20%113.093.098-0.16%1121.721.21.00%123.763.764-0.08%1222.922.01.80%133.793.803-0.26%1323.923.01.80%144.454.470-0.40%1425.324.51.60%154.654.686-0.72%1525.824.91.80%1629.528.81.40%1730.429.51.80%1834.133.31.60%1936.535.61.80%2038.237.41.60%5.2实验数据分析0-5V量程精度为0.001V,满度误差均1.00%,为一级电压表0-50V量程精度为0.1V,满度误差均2.50%,为2.5级电压表第六章:结论1.输入电压易发生干扰不稳定,且驱动能力可能存在不足,需在被测信号的输入端加上一部分驱动电路,比如将量程转换电路改成放大能力的自动量程转换电路,将幅值较小的信号经适当放大后再测量,可显著提高精度;2.输出量可用平均值算法来改善,使测量准确度更高;3.若能将测量的电压值实时保存,使用时将更方便;附录一:作品图附录二:程序主程序:#includereg52.h//头文件#includeintrins.h//头文件#includedefinedvm.h#includedelay.h#includewarning.h#include1602.h#includekeyscan.h#includeAD.h#includedisplay.hvoidmain(){while(1){write_com(0x01);lcd_init();display_voltage();}}1、宏定义和定义变量:#defineucharunsignedchar//宏定义#defineuintunsignedintuchartable[]=measurement:;ucharrange5[]=RANGE0~20V:;ucharrange50[]=RANGE0~2A:;ucharrange500[]=RANGE0~100K:;ucharwarning[]=PleaseChoice!;/*ucharerror[]=error!;*/uintmeasure[10];sbitkey3=P2^7;sbitkey0=P2^2;sbitkey1=P2^1;sbitkey2=P2^0;sbitlcd_rs=P2^3;//定义液晶的rs端口sbitlcd_rw=P2^4;//定义液晶的rw端口sbitlcd_en=P2^5;sbitback=P2^6;sbitspk=P2^7;//定义液晶的en端口sbitcs=P3^2;//定义AD的cs端口sbitrd=P3^1;//定义AD的rd端口sbitwr=P3^0;//sbitdula=P3^7;sbitINTR=P3^7;//定义AD的wr端口uinttemp,i,A1,A2,A3,A4;//定义变量uintdate;2、延时部分:voiddelay(uintz){uintx,y;for(x=z;x0;x--)for(y=110;y0;y--);}voiddelay_lcd()//1602指令之间延时{uintx=5;while(x--);}3、AD转换和数据传送:voidAD_init()//初始化ADC0804{cs=0;wr=1;_nop_();wr=0;_nop_();wr=1;}uintAD_switch()//AD转换部分{uinttemp;P1=0xff;rd=1;_nop_();rd=0;_nop_();temp=P1;//将转后的原始值返给单片机P1口returntemp;}uintAD_smooth()//软件滤波{uintxx,i,temp;AD_init();for(i=0;i20;i++){measure[i]=AD_switch();delay(10);//每隔10usADC转换并采集一次数据,将得}//到的数据放到数组中,采集十个数据for(xx=0;xx20;xx++)//将十个数据冒泡法排序for(i=xx;i20;i++){if(measure[xx]measure[i]){temp=measure[i];measure[i]=measure[xx];measure[xx]=temp;}}for(i=6;i16;i++)//去掉了三个最小值和两个最大值,{//取中间五个数的平均值xx+=measure[i];}xx=xx/10;returnxx;//将滤过波后的值存入单片机}4、1602子程序:voidwrite_com(ucharcom)//写指令{delay(5);lcd_en=0;lcd_rs=0;lcd_rw=0;_nop_();lcd_en=1;P0=com;lcd_en=0;lcd_rs=0;}voidwrite_date(uchardate)//写数据{delay(5);lcd_en=0;lcd_rs=1;lcd_rw=0;_nop_();lcd_en=1;P0=date;lcd_en=0;lcd_rs=0;}voidlcd_init()//初始化{back=0;delay(15);lcd_en=0;write_com(0x38);write_com(0x38);write_com(0x38);write_com(0x06);write_com(0x0c);write_com(0x01);}5、键盘扫描:uintkeyscan(){if(key0==0&&key1==1&&key2==1&&key3==1)return1;elseif(key0==1&&key1==0&&key2==1&&key3==1)return(2);elseif(key0==1&&key1==1&&key2==0&&key3==1)return(3);elseif(key0==1&&key1==1&&key2==1&&key3==0)return(4);elseif(key0==1&&key1==1&&key2==1&&key3==1)return(5);elsereturn(6