基于单片机数字万用表的制作.docx
- 文档编号:15720725
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:24
- 大小:240.17KB
基于单片机数字万用表的制作.docx
《基于单片机数字万用表的制作.docx》由会员分享,可在线阅读,更多相关《基于单片机数字万用表的制作.docx(24页珍藏版)》请在冰点文库上搜索。
基于单片机数字万用表的制作
基于51单片机数字万用表
摘要:
本设计采用AT89C52为主控芯片配以振荡电路设计设计了一个数字万用表,可用于测量直流电压,直流电流,电阻和电容,并配以档位转换。
本系统使用ADC0832作为数据转换芯片,LM358作为放大芯片,通过LCD1602显示,各模块主要通过AD转换以及电压放大实现测量功能。
绪论:
数字多用表(GMM)就是在电气测量中要用到的电子仪器。
它可以有很多特殊功能,但主要功能就是对电压、电阻和电流进行测量。
传统的指针式万用表功能单精度低,不能满足数字化时代的需求,采用单片机制作的数字万用表,具有精度高、抗干扰能力强,可扩展力强、集成方便等优点,目前,由各种单片机芯片构成的数字电万用表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,显示出强大的生命力。
总体设计设计方案:
1.电压测量原理与AD转换电路
ADC0832是美国国家半导体公司生产的一种8位分辨率、双通道A/D转换芯片。
其最高分辨可达256级,可以适应一般的模拟量转换要求。
其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间。
芯片转换时间仅为32μS,据有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。
独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。
通过DI数据输入端,可以轻易的实现通道功能的选择。
本系统只对CH0进行单通道转换。
电压测量流程图
对于本设计分压电路模块介绍之前首先分析以下两种设计方案。
多量程分压电路
多量程分压器原理
上述两图所制作的多量程电压测量,其内阻比较小,不能达到测量要求,对电路做以下改进。
对于本次设计的电压模块只设置5V,30V两个档位,如图直接采用一组分压电路既可达到要求。
2.电流测量原理与放大电路
对于电流模块此处给予多种方案:
(本系统采用的方案二)
方案一:
原理:
通过改变检流电阻的大小实现不同档位的转换。
图中保险丝可保护电流过大,二极管防止电压过大,当二极管两端电压达到导通电压,检流电阻连端电压将达到稳定,从而有效的控制输入电压的大小。
方案二:
电流测量原理与方案一基本相同,但在相同电流的测量上此电路比方案一电路的内组更小,由于加入了运算放大器,所以最大的输出电压不会超过电源电压(实验数据显示不会超过3.6V)并不用担心检流电阻两端电压大小。
而且此方案还有一个最大的优势,它的分辨率更高,理由如下:
根据ADC0832的最小分辨率x可知,此方案中测量电流的最小分辨电流i满足i*R*k=x(R为检流电阻,k为放大器放大倍数),得到i=x/(R*k)
在方案一中,i’=x/R’,由于电阻材质的问题其本身电压不能超过额定电压,在量程相同的情况下Imax*R*k=3,Imax*R’<3.因此Rx>R’
即i
(LM358内部包括有两个独立的、高增益、内部频率补偿的双运算放大器,适合于电源电压范围很宽的单电源使用,也适用于双电源工作模式,在推荐的工作条件下,电源电流与电源电压无关。
它的使用范围包括传感放大器、直流增益模块和其他所有可用单电源供电的使用运算放大器的场合。
)
3.电阻模块的测量原理
放大电路
放大器的最大放大电压为3V左右(实际放大为3.5V左右,这里取3V),则输入电压满足5*10 可以知道待测电阻R=50k/Uo-1010. ADC0832的最小分辨率为0.02V即放大后的最小电压为0.02V.则输入电压满足5*10>v(1010+R).v是最小输入电压。 根据上述说明可以得出各个档位测量范围。 档位1(V=0.05,v=0.0003..),R<148990 档位2(V=0.005,v=0.00003..),8990 档位3(V=0.0005,v=0.000003..),98990 如果挡位1取9000,档位2取99000,档位3取999000. 在上述电路制作成功后并没有达到比较好的测量效果,对于大电阻的测量测量值往往会远小于实际电阻值。 针对这个问题,在对放大器各级电压比较后发现主要是由于大电阻测量时输入电压太小以至于达不到放大器的正常放大电压,因此上述电路在很大程度上限制了测量电阻的范围。 对电路做以下改变: 直接将前两级放大合并为一级放大,达到减小放大的门款电压。 其他测量方法: 原理图如下: 通过恒流源(恒流电路此处用电流源代替)给待测电阻供电,放大待测电阻的电压,输出给电压表。 此方法和上述方案原理上的差别在于一个利用的是电流恒定,另一个利用的是电压恒定,对于电流的恒定,一方面,它的电路设计比较复杂,另一方面,如果电流源电路设计的不太理想,电流源的大小变化会产生很大的测量误差。 不过它可以使测量误差比较稳定,在测量误差不大的情况下电压恒定电路的误差变化可以忽约吗,因此本设计不采用这种设计思路。 4.电容的测量原理与振荡电路: 根据555定时器构成单稳态,产生脉冲波形,通过单片机读取高低电平得出频率,通过公式换算得到电容值。 总结: 整个设计基本上是围绕放大器所组成的放大电路展开,放大器的放大误差直接决定着测量的误差。 此设计设计电路简单,测量精度比较小。 而且材料成本低,对于直流电路的测量有着很好的实用性。 程序 主函数 #include"lcd.h" sbitAAD_CS=P1^0; sbitAAD_D0=P1^2; sbitAAD_D1=P1^3; sbitAAD_CLK=P1^1; sbitAVD_CS=P1^4; sbitAVD_D0=P1^6; sbitAVD_D1=P1^7; sbitAVD_CLK=P1^5; sbitkey_boat=P3^3; unsignedcharAAD_read(),AVD_read(); unsignedchardat[4]={0,0,0,0}; unsignedchardate=0,date1=0,key=0,time=18; unsignedlongadd; voidmain() {init(); TH0=0x3c; TL0=0xb0; TH1=0x3c; TL1=0xb0; TMOD=0x11; EA=1; EX0=1; EX1=1; IT0=1; IT1=1; ET0=1; ET1=1; PT0=0; PX0=0; PX1=1; TR0=1; while (1); } voidcapac()interrupt0//电容测量,记数中断 {add++;TR0=1; } voidtime_ADC()interrupt1//其他测量,数据采集周期 { time--; if(time==0) { if(date==1)//电压档位1 {add=AVD_read(); dat[0]=add*196/10000; dat[1]=(add*196/1000)%10; dat[2]=(add*196/100)%10; writedate(0x80,dat[0]+'0'); writedate(0x81,'.'); writedate(0x82,dat[1]+'0'); writedate(0x83,dat[2]+'0');} if(date==2)//电压档位2 {add=AVD_read(); dat[0]=add*1176/100000; dat[1]=(add*1176/10000)%10; dat[2]=(add*1176/1000)%10; dat[3]=(add*1176/100)%10; writedate(0x80,dat[0]+'0'); writedate(0x81,dat[1]+'0'); writedate(0x82,'.'); writedate(0x83,dat[2]+'0'); writedate(0x84,dat[3]+'0');} if(date1==1)//电流档位1 {add=AAD_read(); if(add<163) { dat[0]=(add*1000/163)/100; dat[1]=((add*1000/163)/10)%10; dat[2]=(add*1000/163)%10; writedate(0xc0,dat[0]+'0'); writedate(0xc1,'.'); writedate(0xc2,dat[1]+'0'); writedate(0xc3,dat[2]+'0');} else writedate(0xc0,'1');} if(date1==2)//电流档位2 {add=AAD_read(); if(add<173){ dat[0]=(add*1000/173)/100; dat[1]=((add*1000/173)/10)%10; dat[2]=(add*1000/173)%10; writedate(0xc0,dat[0]+'0'); writedate(0xc1,dat[1]+'0'); writedate(0xc2,'.'); writedate(0xc3,dat[2]+'0');} else writedate(0xc0,'1'); } if(date1==3)//电流档位3 {add=AAD_read(); if(add<144){ dat[0]=(add*150/144)/100; dat[1]=((add*150/144)/10)%10; dat[2]=(add*150/144)%10; writedate(0xc0,dat[0]+'0'); writedate(0xc1,dat[1]+'0'); writedate(0xc2,dat[2]+'0');} else writedate(0xc0,'1'); } if(date1==4)//电阻档位1 {add=AAD_read(); if(add>13){ dat[0]=(153000/add-1010)/1000; dat[1]=((153000/add-1010)/100)%10; dat[2]=((153000/add-1010)/10)%10; dat[3]=(153000/add-1010)%10; writedate(0xc0,dat[0]+'0'); writedate(0xc1,dat[1]+'0'); writedate(0xc2,dat[2]+'0'); writedate(0xc3,dat[3]+'0');} else writedate(0xc0,'1'); } if(date1==5)//电阻档位2 { add=AAD_read(); if(add>16){ dat[0]=(168300/add-101)/1000; dat[1]=((168300/add-101)/100)%10; dat[2]=((168300/add-101)/10)%10; dat[3]=(168300/add-101)%10; writedate(0xc0,dat[0]+'0'); writedate(0xc1,dat[1]+'0'); writedate(0xc2,'.'); writedate(0xc3,dat[2]+'0'); writedate(0xc4,dat[3]+'0');} else writedate(0xc0,'1'); } if(date1==6)//电阻档位3 {add=AAD_read(); if(add>15) {dat[0]=(1545300/add-101)/10000; dat[1]=((1545300/add-101)/1000)%10; dat[2]=((1545300/add-101)/100)%10; dat[3]=((1545300/add-101)/10)%10; writedate(0xc0,dat[0]+'0'); writedate(0xc1,dat[1]+'0'); writedate(0xc2,dat[2]+'0'); writedate(0xc3,'.'); writedate(0xc4,dat[3]+'0'); } else writedate(0xc0,'1');} if(date1==7)//电容档位1 {TR0=0; if(add>51) {dat[0]=(505000/add)/1000; dat[1]=((505000/add)/100)%10; dat[2]=((505000/add)/10)%10; dat[3]=(505000/add)%10; writedate(0x80,dat[0]+'0'); writedate(0x81,dat[1]+'0'); writedate(0x82,dat[2]+'0'); writedate(0x83,'.'); writedate(0x84,dat[3]+'0');} else writedate(0x80,'1'); add=0; } if(date1==8)//电容档位2 {TR0=0; if(add>51) {dat[0]=(505000/add)/1000; dat[1]=((505000/add)/100)%10; dat[2]=((505000/add)/10)%10; dat[3]=(505000/add)%10; writedate(0x80,dat[0]+'0'); writedate(0x81,dat[1]+'0'); writedate(0x82,dat[2]+'0'); writedate(0x83,'.'); writedate(0x84,dat[3]+'0');} else writedate(0x80,'1'); add=0; } if(date1==9)//电容档位3(此档位不可用) {TR0=0; writedate(0xc0,add/10000000+'0'); writedate(0xc1,(add/1000000)%10+'0'); writedate(0xc2,(add/100000)%10+'0'); writedate(0xc3,(add/10000)%10+'0'); writedate(0xc4,(add/1000)%10+'0'); writedate(0xc5,(add/100)%10+'0'); writedate(0xc6,(add/10)%10+'0'); writedate(0xc7,(add)%10+'0'); add=0;} time=18; } TH0=0x3c; TL0=0xb0; } voidkeyboat()interrupt2//功能转换开关 {unsignedchartrange=200; if(key_boat==0) {delay(50); if(key_boat==0) { key++; TR0=0; if(key>11){key=1;TR0=1;} writeadd (1); switch(key) {case1: writedate(0x80+13,'U');writedate(0x80+14,'5'); writedate(0x80+15,'v');break; case2: writedate(0x80+12,'U');writedate(0x80+13,'3');writedate(0x80+14,'0'); writedate(0x80+15,'v');break; case3: writedate(0xc0+11,'I');writedate(0xc0+12,'1');writedate(0xc0+13,'0'); writedate(0xc0+14,'m');writedate(0xc0+15,'A');break; case4: writedate(0xc0+11,'I');writedate(0xc0+12,'8');writedate(0xc0+13,'0'); writedate(0xc0+14,'m');writedate(0xc0+15,'A');break; case5: writedate(0xc0+10,'I');writedate(0xc0+11,'1');writedate(0xc0+12,'5');writedate(0xc0+13,'0'); writedate(0xc0+14,'m');writedate(0xc0+15,'A');break; case6: writedate(0xc0+13,'R');writedate(0xc0+14,'9'); writedate(0xc0+15,'K');break; case7: writedate(0xc0+12,'R');writedate(0xc0+13,'9');writedate(0xc0+14,'9'); writedate(0xc0+15,'K');break; case8: writedate(0xc0+11,'R');writedate(0xc0+12,'9');writedate(0xc0+13,'9'); writedate(0xc0+14,'9');writedate(0xc0+15,'K');break; case9: writedate(0x80+12,'C');writedate(0x80+13,'='); writedate(0x80+14,'u');writedate(0x80+15,'F');break; case10: writedate(0x80+12,'C');writedate(0x80+13,'='); writedate(0x80+14,'n');writedate(0x80+15,'F');break; case11: writedate(0x80+10,'e');writedate(0x80+11,'r');writedate(0x80+12,'r');writedate(0x80+13,'o'); writedate(0x80+14,'r');break; } date=key; date1=key-2;}} delay(50); while(key_boat==0&&trange) trange--; key_boat=1; TR0=1; } unsignedcharAAD_read()//电流测量端数据接收函数 {unsignedchardat,i,test=0,adval=0; AAD_CLK=0;// AAD_D1=1; _nop_(); AAD_CS=0; _nop_(); AAD_CLK=1; _nop_(); AAD_CLK=0;// AAD_D1=0; _nop_(); AAD_CLK=1; _nop_(); AAD_CLK=0;// AAD_D1=0; _nop_(); AAD_CLK=1; _nop_(); AAD_CLK=0; AAD_D1=1; for(i=0;i<8;i++) {_nop_(); adval<<=1; AAD_CLK=1;_nop_(); AAD_CLK=0; if(AAD_D0) adval|=1; } for(i=0;i<8;i++) {_nop_();test>>=1; if(AAD_D0) test|=0x80; AAD_CLK=1;_nop_(); AAD_CLK=0; } if(adval==test) dat=test; _nop_(); AAD_CS=1; AAD_D0=1; AAD_D1=1; AAD_CLK=1; returndat; } unsignedcharAVD_read()//电压测量端ADC0832数据接收函数 {unsignedchardat,i,test=0,adval=0; AVD_CLK=0;// AVD_D1=1; _nop_(); AVD_CS=0; _nop_(); AVD_CLK=1; _nop_(); AVD_CLK=0;// AVD_D1=0; _nop_(); AVD_CLK=1; _nop_(); AVD_CLK=0;// AVD_D1=0; _nop_(); AVD_CLK=1; _nop_(); AVD_CLK=0; AVD_D1=1; for(i=0;i<8;i++) {_nop_(); adval<<=1; AVD_CLK=1;_nop_(); AVD_CLK=0; if(AVD_D0) adval|=1; } for(i=0;i<8;i++) {_nop_();test>>=1; if(AVD_D0) test|=0x80; AVD_CLK=1;_nop_(); AVD_CLK=0; } if(adval==test) dat=test; _nop_(); AVD_CS=1; AVD_D0=1; AVD_D1=1; AVD_CLK=1; returndat; } 显示函数 #include"lcd.h" voiddelay(unsignedchari) {unsignedcharj=100; while(i>0) {j=100; while(j--); i--;} } voidwriteadd(unsignedcharadd)//写入指令 { check(); E=0; RS=0; RW=0; delay (1); LCD=add; delay (1); E=1; delay (1); E=0; delay (1); } voidcheck() { RS=0;RW=1; delay (1); E=1; while(LCD&0x80); E=0; delay (1);} voidwritedate(unsignedcharadd,unsignedchardate)//写入地址和数据 { writeadd(ad
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 数字 万用表 制作