数字电压表实习报告.docx
《数字电压表实习报告.docx》由会员分享,可在线阅读,更多相关《数字电压表实习报告.docx(28页珍藏版)》请在冰豆网上搜索。
![数字电压表实习报告.docx](https://file1.bdocx.com/fileroot1/2023-5/16/4603c624-33b3-455e-ae70-396db15a843c/4603c624-33b3-455e-ae70-396db15a843c1.gif)
数字电压表实习报告
机械与电子信息学院
通信工程系
2009年寒假实习报告
题目:
数字电压表的设计
姓名:
杜世超班序号:
11206113
指导教师:
王巍、李杏梅、闻兆海
2008年12月
摘要:
本数字电压表可以对直流电源和交流电压进行比较准确的测量。
其中直流部分的测量范围是0-20V,分为三个档位:
0-0.2V,0.2V-2V,2V-20V。
该直流电压表的测量电路主要由三个模块组成:
模拟数据采集处理模块、A/D转换模块及译码显示控制模块。
模拟数据的采集处理模块由模拟电路部分完成。
A/D转换模块主要由芯片ADC0809来完成,它负责把采集到的模拟量转换为相应的数字量再传送到AT89S51单片机进行数据处理。
译码显示模块是单片机将译好的数据传送到由74LS244驱动的4位7段数码管进行显示。
交流部分的测量范围是0-5V,测量的是交流电压的有效值。
该交流电压表的测量电路由三个模块构成:
AC-DC转换模块、电压补偿模块、直流电压表测试模块。
其中AC-DC转换模块由AD637完成。
电压补偿模块对AD637的非线性部分进行补偿,由LM324完成。
直流电压表测试模块由直流部分完成。
关键字:
AT89S51,数模转换,AC-DC转换,数码管显示
1.系统方案的选择和论证
1.1数模转换模块
方案一:
用分离元件完成数据采集AD转换的功能。
该方案由于需要大量的元器件,实现起来比较复杂,而且精度不易控制。
方案二:
选则集成芯片ADC0809。
ADC0809的采样频率为8位的、以逐次逼近原理进行模—数转换的器件。
其内部有一个8通道多路开关,它可以根据地址码锁存译码后的信号,只选通8个单断模拟输入信号中的一个进行A/D转换。
由于本实验要求的测量误差是<=1%,显示精度是0.01V,本设计采用ADC0809就可以满足要求。
ADC0809的分辨率是1/28,量化间隔为∆=
满量程输入电压/28-1,完成一次转换的时间是100us。
适合此设计使用。
方案三:
采用其他采样频率位数更高的AD转换芯片,如积分型(如TLC7135)、压频变换型(如AD650)、调制型(如AD7705)、并行比较型/串并行比较型(如TLC5510)。
这些AD转换芯片各有各的特点。
单本实验只需要采用常用的、性价比高的芯片就可以完成。
1.2模拟数据采集处理模块:
方案一:
不加另外的模拟电路,直接让ADC0809采集输入的电压。
对于此设计不可行。
因为ADC0809只能对0-5V的模拟电压进行采样,而要求对0-20V的电压进行处理,故淘汰此设计。
方案二:
用滑动变阻器对输入的电压进行分压,实现了对比较大的电压进行采样的目的。
再对不同的分压厚的电压进行不同的处理放大,这样可以避免ADC0809对比较小的电压采样误差较大的弊端。
所以分压与放大两部分电路结合成功完成数据采集处理模块。
1.3译码显示模块:
方案一:
用CD4511进行译码,四位七段数码管进行显示。
因为CD4511可将BCD,码转换为可以再数码管上显示的数字,则在单片机的程序中不需要写译码的程序。
由于CD4511译码出的数据不能显示小数点,小数点的控制仍需在单片机程序中另外编写。
方案二:
用单片机直接控制四位的七段数码管进行显示,在单片机的程序中完成译码。
其中在单片机和数码管之间要加驱动芯片驱动。
所以实现起来较为简单。
1.4AC-DC转换模块
方案一:
采用分立元件设计,经过整理滤波等措施,使交流电压变为直流电压。
但是设计要求的是测量其有效值,所以电路实现起来较为复杂,而且精确度不高。
方案二:
采用AD637完成AC-DC转换,再配合LM324完成交流转其对应的直流有效值的功能,精度较高。
2.详细软件硬件设计
2.1硬件设计部分
整体设计流程图
2.1.1单片机最小系统
单片机的最小系统由AT89S51、6M晶振、两个20p电容、10K电阻、复位开关组成。
如图1:
图1
2.1.2数模转换模块
该模块采用的主要芯片使ADC0809。
首先输入3位地址,并使ALE=1,将地址存入地址锁存器中。
此地址经译码选通8路模拟输入之一到比较器。
START上升沿将逐次逼近寄存器复位。
下降沿启动A/D转换,之后EOC输出信号变低,指示转换正在进行。
直到A/D转换完成,EOC变为高电平,指示A/D转换结束,结果数据已存入锁存器,这个信号可用作中断申请。
当OE输入高电平时,输出三态门打开,转换结果的数字量输出到数据总线上。
ALE信号常与START信号连在一起,这样连接可以在信号的前沿写入地址信号,在其后沿启动A/D转换,图2为ADC0809信号的时序配合图)。
图2ADC0809信号的时序配合
在本设计中,选通了IN-0通道(A、B、C都为0),IN-0作为模拟信号的输入,通过D0-D7数据输出口与单片机进行数据传输。
由于ADC0809没有内部时钟,所以需要单片机提供时钟,ALE输出的是六分频的时钟(1M),再经过D触发器的设计实现二分频,最终是ADC0809的工作时钟为500KHz。
工作的ADC0809与单片机的连接图如图3。
图3
2.1.3模拟数据采集处理模块
此模块完成将0-0.2V,0.2V-2V,2V-20V的数据分开处理。
配合单片机指令完成了使输入要测试的直流电压进行五分压后,对2V-20V的数据不作处理。
对0.2V-2V的数据通过LM324进行十倍的放大,对0V-200MV的数据进行一百倍的放大。
这样设计的目的是为了使传送给ADC0809的测试电压即在0-5VADC0809所允许的电压范围之内,又对较小的电压进行了放大,加强其采样处理的准确性。
U0为传送给ADC0809的接口。
如图4为所设计的具体电路。
图4
2.1.4译码显示控制模块
将AT89S51的译码输出通过驱动芯片74LS244驱动四位七段数码管。
74HC138进行片选实现动态扫描四位数码管的每一位。
图5是其具体连接电路。
图5
2.1.5AC-DC转换模块、电压补偿模块
采用的AC-DC转换芯片是AD637,完成了将交流电转换成其直流有效值。
其最终转换公式是:
V0=VIN2/VDEN之所以要有电压补偿,是因为AD637的电压转换不是线性的,在大于4V之后则输出的电压小于输入的交流电压的有效值。
在0-4V的范围就直接将V0加到直流电压的输入。
所以要加一个放大器LM324进行补偿。
R2设计为可调电阻就是为了调节放大器的放大倍数。
具体的电路连接图如下:
图6
2.2软件设计部分
软件设计流程图
若电压大于0.4V
若电压小于0.04V
OE=1
OE=1
OE=1
若电压小于0.4V
图7
2.2.1CD4051的控制模块
CD4051是八通道数字控制模拟开关,有三个输入端A0、A1、A2作为控制八路开关的其中一路选通。
当INH输入端为“1”时,所有通道截止。
单片机的P2.7-P2.5口控制一路选通,也就是对不同的电压范围的数据分别进行放大处理。
2.2.2数模转换模块
首先启动AD,由一START的端口的下降沿触发。
当AD转换完成标志EOC为0时,先将数据锁存,当AD采样数据给getdata后,再将OE置为1,输出转换得到的数据。
其中因为在采样处理模块有五分压,所以送给U0的电压值并不是原始的电压值。
对于2V-20V的电压,采样处理模块只对其进行五分压,然后送到U0。
要注意的是AD转换的数据是八位二进制的数。
而此二进制的数是由:
(参考电压/256)*输入电压所得到的。
所以,若getdata<21(21对应000101010,也就是0.4V,是2V经过二分压所得到的。
)就转到0.2V-2V的档。
若getdata>21则正常处理:
temp=(temp/51)*5;temp扩大1000倍,然后对其进行转换,即除以51(因为256/5是其转换的公式),最后再乘以5变换到五分压之前的数值。
同样在0-0.2V档和0.2V-2V档都是这样处理的。
2.2.3译码显示模块
对temp进行除以和模操作,将其每一位分别取出,然后在数码管上显示。
然后根据不同的档位显示小数点,20V档点亮第三个数码管的小数点(从低位到高位),2V档位点亮第四个数码管的小数点,0.2V档位点亮第一个数码管的小数点。
uchardispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};定义0~9的显示段码,即完成了4511的功能。
ucharcodescan_con[]={0x03,0x02,0x01,0x00}; 实现了数码管从低位到高位的扫描
其中值得注意的是:
在temp=temp*1000; temp=(temp/51)*5;将temp扩大了1000倍,其目的是在最后的显示中实现0.01的精确度。
那么P1=dispcode[dispbuf[k]]也应改为P1=dispcode[dispbuf[k+1]];
若temp*100则在最后的显示中只能显示0或5,原因是:
因为temp/51,在C语言中两个整形数字相除,结果只能是整数,也就是说如果2900/51=56.862745,但在程序的运算中结果是56!
将一个整数temp*5结果肯定是5的整数倍,所以末位不是5就是0。
(56*5末位是0)。
改为temp*1000则虽不能改变末位为0或5的结果,但我们可以从倒数第二位显示。
也就对应dispcode[dispbuf[k+1]]。
3.测试数据与结果分析
3.1测试仪器
(1)数字万用表
(2)双通道数字示波器
(3)频率发生器
3.2测试数据
3.2.10-0.2V档测量的数据(直流)
万用表测量值(mv)
数码管显示值(mv)
17.3
18.5
43.4
46
53.8
53.5
77.2
77.0
95.6
93.0
125.1
124.5
184.1
187.0
表1
3.2.20.2V-2V档测量的数据(直流)
万用表测量值(v)
数码管显示值(v)
0.225
0.225
0.428
0.430
0.624
0.625
0.828
0.820
1.050
1.045
1.238
1.245
1.483
1.480
1.678
1.675
1.878
1.870
表2
3.2.30.2V-2V档测量的数据(直流)
万用表测量值(v)
数码管显示值(v)
2.23
2.25
3.95
3.90
6.16
6.15
8.03
8.10
9.96
10.05
12.41
12.45
12.32
12.40
16.32
16.35
18.31
18.40
19.73
19.90
表3
3.2.40-5V档测量的数据(交流)
万用表测量值(v)
数码管显示值(v)
0.1662
0.1843
0.241
0.264
0.337
0.352
0.544
0.549
0.816
0.813
1.450
1.362
1.690
1.607
1.885
1.872
2.24
2.25
2.68
2.64
3.11
3.03
3.44
3.43
3.80
3.82
4.12
4.21
4.46
1.60
4.70
4.70
4.97
5.00
5.00
5.00
表4
3.3测试数据分析
用MATLAB分别做不同量程的曲线拟合图,横坐标是数码管显示值,纵坐标万用表测量值,做三次曲线拟合。
然后做万用表测量值和数码管显示值之差,再做三次曲线拟合
3.3.10-0.2V档测量的数据(直流)
图8
图9
分析:
从图8可以看出,线性良好,也就是数码管显示值和万用表测量值很接近。
图9纵坐标单位为MV,在60MV和160MV左右时,误差较小接近于0.但在量程的两端误差较大。
3.2.20.2V-2V档测量的数据(直流)
图10
图11
分析:
从图10可以看出,线性良好,也就是数码管显示值和万用表测量值很接近。
图11纵坐标单位为MV,0.4-1.4范围内,误差较小,在2MV左右.但在量程的两端误差较大。
3.2.32V-20V档测量的数据(直流)
图12
图13
分析:
从图12可以看出,线性良好,也就是数码管显示值和万用表测量值很接近。
图13纵坐标单位为V,4V-12V范围内,误差较小,在0.05V左右.但在量程的两端误差较大,误差达到0.1V-0.15V
3.2.40-5V档测量的数据(交流)
图14
图15
分析:
从图14可以看出,线性良好,也就是数码管显示值和万用表测量值很接近。
图15纵坐标单位为V,误差见上图所示。
4、总结
通过本次实习,我掌握了AD采样的操作,同时也对单片机有了更好的掌握。
在实习的过程中我们遇到了很多问题,如:
AD的时序、交流转换直流的电路设计、单片机程序的调试等。
在电路焊接方面我们做的比较好,几乎没有因为电路的焊接而出现故障。
整个实习的难点在精度的调节和交流部分的制作。
在实习的最后才解决了末尾只能显示0或5的问题,但在直流的数据记录时没有改正过来。
在交流的数据记录中显示了正确的结果(末尾可以显示从0-9的所有数字)。
在交流部分的制作中,刚开始用分离元件做,结果天违人愿。
不光交流-直流没有做出来,反而把直流部分也烧坏了。
于是我又用了两天的时间从电路检查到程序调试做好了直流部分。
鉴于用分离元件失败的教训,我们采用集成元件AD637.问题又出来,AD637在0-4V的交直流转换中成线性转换,效果较好。
但在4V-5V的转换中,转换后的电压远小于交流的有效值。
我们又采用放大器功率补偿的方法加以矫正。
电压上去了,但仍然不是线性关系。
于是在软件部分又加以矫正。
最终得到了比较精确的电压值。
5、参考文献
【1】汪文,《单片机原理及应用》【M】.武汉:
华中科技大学出版社,2007.3
【2】谢子美,《电子线路.设计.试验.测试》【M】.北京:
清华大学出版社,2007
【3】高峰,《单片微型计算机与接口技术》【M】.北京:
科学出版社,2003
6.附录
6.1单片机程序
#include
#defineucharunsignedchar;
ucharcodescan_con[]={0x03,0x02,0x01,0x00}; //定义列扫描
uchardispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//定义0~9的显示段码
uchardispbuf[8]={0,0,0,0,0,0,0,0};//定义8个存储空间
uchardispcount=0;
uchargetdata;
unsignedlongtemp;//定义暂存空间
uchari,j,k,l,m;
sbits3=P2^7; //位定义,控制模拟开关
sbits2=P2^6;
sbits1=P2^5;
sbitdp=P1^7;//定义小数点
#definev20_on{s3=1;s2=0;s1=0;}//宏定义不同量程,不同的开关状态
#definev2_on{s3=0;s2=1;s1=0;}
#definev02_on{s3=0;s2=0;s1=1;}
sbitST=P2^0; //定义单片机和ADC的控制信号
sbitOE=P2^1;
sbitEOC=P2^2;
main()
{
while
(1)
{
_20v:
//2~20V量程
v20_on;
ST=0; //启动A/D转换
ST=1;
ST=0;
while(EOC==0);
OE=0;
getdata=P0;
OE=1;
if(getdata<21) //量程不合适,切换
{
goto_2v;
}
l=3;
temp=getdata; //量程合适,数据处理
temp=temp*1000;
temp=(temp/51)*5;
gotodisp; //跳到数码管显示程序段
_2v:
//200MV~2V量程
v2_on;
ST=0;
ST=1;
ST=0;
while(EOC==0);
OE=0;
getdata=P0;
OE=1;
if(getdata<21)
{
goto_02v;
}
elseif(getdata>204)
{
goto_20v;
}
l=2;
temp=getdata;
temp=(temp*1000/51)*10;
temp=temp/2;
gotodisp;
_02v:
//0~200MV量程
v02_on;
ST=0;
ST=1;
ST=0;
while(EOC==0);
OE=0;
getdata=P0;
OE=1;
if(getdata>204)
{
goto_2v;
}
l=1;
temp=getdata;
temp=(temp*1000/51)*100;
temp=temp/20;
disp:
dispbuf[0]=0;
dispbuf[1]=0;
dispbuf[2]=0;
dispbuf[3]=0;
dispbuf[4]=0;
dispbuf[5]=0;
dispbuf[6]=0;
dispbuf[7]=0;
i=0;
while(temp/10) //电压值的每个位计算
{
dispbuf[i]=temp%10;
temp=temp/10;
i++;
}
dispbuf[i]=temp;
for(k=0;k<=3;k++) //数码管显示
{
P1=dispcode[dispbuf[k+1]];
P3=scan_con[k];
if(l==3){if(k==2){P1=P1|0x80;}}//小数点的确定
elseif(l==2){if(k==3){P1=P1|0x80;}}
elseif(l==1){if(k==1){P1=P1|0x80;}}
for(m=0;m<=2;m++) //延时
for(j=0;j<=100;j++);
}
}
}
6.2附图
6.2.1系统整体图