简易数字直流电压表的设计单片机课程设计.docx
《简易数字直流电压表的设计单片机课程设计.docx》由会员分享,可在线阅读,更多相关《简易数字直流电压表的设计单片机课程设计.docx(16页珍藏版)》请在冰豆网上搜索。
简易数字直流电压表的设计单片机课程设计
1、前言
数字电压表(DigitalVoltmeter)简称DVM,它是采用数字化测量技术,把连续的模拟量(直流输入电压)转换成不连续、离散的数字形式并加以显示的仪表。
传统的指针式电压表功能单一、精度低,不能满足数字化时代的需求,采用单片机的数字电压表,由精度高、抗干扰能力强,可扩展性强、集成方便,还可与PC进行实时通信。
目前,由各种单片A/D转换器构成的数字电压表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,示出强大的生命力。
与此同时,由DVM扩展而成的各种通用及专用数字仪器仪表,也把电量及非电量测量技术提高到崭新水平。
本章重点介绍单片A/D转换器以及由它们构成的基于单片机的数字电压表的工作原理。
2、系统原理及基本框图
如图2.1所示,模拟电压经过档位切换到不同的分压电路衰减后,经隔离干扰送到A/D转换器进行A/D转换,然后送到单片机中进行数据处理。
处理后的数据送到LED中显示。
图2.1系统基本方框图
3、硬件设计
3.1、电源电路
图3.1电源电路原理图
3.2、A/D转换电路
A/D转换器的转换精度对测量电路极其重要,它的参数关系到测量电路性能。
本设计采用A/D转换器,它的性能比较稳定,转换精度高,具有很高的抗干扰能力,电路结构简单,其缺点是工作速度较低。
在对转换精度要求较高,而对转换速度要求不高的场合如电压测量有广泛的应用。
图3.2.1A/D转换器
图3.2.2双积A/D转换器的波形图
图3.2.1.2双积A/D转换器的波形图
如图所示:
对输入模拟电压和基准电压进行两次积分,先对输入模拟电压进行积分,将其变换成与输入模拟电压成正比的时间间隔T1,再利用计数器测出此时间间隔,则计数器所计的数字量就正比于输入的模拟电压;接着对基准电压进行同样的处理。
在常用的A/D转换芯片(如ADC-0809、ICL7135、ICL7109等)中,ICL7135与其余几种有所不同,它是一种四位半的A/D转换器,具有精度高(精度相当于14位二进制数)、价格低廉、抗干扰能力强等优点。
3.3、单片机部分
单片机选用的是ATMEL公司新推出的AT89S52,如图3.2.1.1所示。
该芯片具有低功耗、高性能的特点,是采用CMOS工艺的8位单片机,与AT89C51完全兼容。
AT89S52还有以下主要特点:
①采用了ATMEL公司的高密度、非易失性存储器(NV-SRAM)技术;
②其片内具有256字节RAM,8KB的可在线编程(ISP)FLASH存储器;
③有2种低功耗节电工作方式:
空闲模式和掉电模式
④片内含有一个看门狗定时器(WDT),WDT包含一个14位计数器和看门狗定时器复位寄存器(WDTRST),只要对WDTRST按顺序先写入01EH,后写入0E1H,WDT便启动,当CPU由于扰动而使程序陷入死循环或“跑飞”状态时,WDT即可有效地使系统复位,提高了系统的干扰性能。
图3.2.1.1AT89S52引脚图
3.4、LED显示部分
本实验的显示模块主要由一个4位一体的7段LED数码管构成,用于显示测量到的电压值。
它是一个共阳极的数码管,每一位数码管的原理图如图1-13所示。
每一位数码管的a,b,c,d,e,f,g和dp端都各自连接在一起,用于接收AT89S52的P1口产生的显示段码。
1,2,3,4引脚端为其位选端,用于接收AT89S52的P3口产生的位选码。
图3.4.1和图3.4.2分别为其原理图和实物图。
图3.4.1一位数码管的原理图
图3.4.2数码管实物图
3.5总原理图
图3.5.1数字电压表总原理图
4、程序设计部分
4.1程序设计流程
初始化中主要对AT89S52,ADC0809的管脚和数码管的位选及所用到的内存单元进行初始化设置。
准备工作做好后便启动ADC0809对IN0脚输入进的0.000~2.500V电压模拟信号进行数据采集并转换成相对应的0~255十进制数字量。
在数据处理子程序中,运用标度变换知识,编写算法将0~255十进制数字量转换成0.000~2.500V的数据,输出到显示子程序进行显示。
整个主程序就是在A/D转换,数据处理及显示程序循环执行。
整个程序流程框图如图1-16所示。
图4.1.1主程序流程图
4.2程序段解释
延时程序:
voiddelay(uintt)
{
while(--t);
}
根据TLC549的工作时序图,使用P1.0作为片选端cs,P1.1作为数据输出端dt,P1.2作为时钟输入端io。
先初始化AD芯片,然后打开片选端cs,开始检测数据输出端dt的电平,用变量temp记录数据。
程序如下:
ucharduqu()
{
uchartemp;
temp=0;
cs=1;
io=0;
cs=0;
for(i=0;i<8;i++)//AD数据是串行输出,所以用移位方式存储数据
{
io=1;
temp=temp<<1;
if(dt)
{temp++;}
io=0;
}
cs=1;
delay(10);
return(temp);
}
用aa获得AD转换值,用c取得整数部分,d取得第一位小数,e取得第二位小数。
然后通过P0、P2口控制数码管显示。
voidxianshi()
{
aa=duqu();
bb=(0.009804*aa);
cc=bb*1000;
qian=bb;
c=(cc-qian*1000)/100;
d=(cc-qian*1000-c*100)/10;
e=cc-qian*1000-c*100-d*10;//获得数据
P2=0xff;
P0=table[qian]|0x80;
P2=0xf7;
delay(50);
P0=0;
P2=0xfb;
P0=table[c];
delay(50);
P0=0;
P2=0xfd;
P0=table[d];
delay(50);
P0=0;
P2=0xfe;
P0=table[e];
delay(50);//数码管显示数据
P0=0;
}
以下是主程序部分,直接使用显示程序即可获得测的电压值。
voidmain()
{
while
(1)
{
xianshi();
}
}
5总结
通过本次课题设计,我们对单片机这门课程有了更进一步的了解。
无论是在其硬件连接方面还是在软件编程方面,都取得了新的收获。
对AltiumDesigne仿真软件有了初步的了解和认识,使用AltiumDesigne仿真软件,可以让我们在虚拟的环境中进行实验,不需要真实电路环境的介入,不必顾及仪器设备的短缺与时间环境的限制,能够极大的提高实验的效率。
本次实验采用了AT89S52单片机芯片,与以往我们我们所熟悉的C51芯片有许多不同之处,通过本次实验及查阅相关资料,我们对其之间的区别有了一定的认识,在本课题设计报告的硬件介绍部分也对其作了详细的论述。
另外,在对单片机编程方面,我们又掌握了一些新的编程思想,使得程序更为简练、易懂,而且更为严谨,程序执行的稳定性得到了提高。
实验中我们还用到了模/数转换芯片ADC0809,以前在学单片机这门课程时只是对其理论知识有了初步的了解。
通过本次实验,我们对它的工作原理彻底理解了,对其启动设置、转换结束判断以及输出控制等都基本掌握。
电路连接方面,我们对其与单片机的连接也有了更为直观的认识,通过实验的摸索以及必要的理论知识,我们准确的实现了它于单片机的互连。
另外,在布线方面,我们也存在一些问题,导致我们做好的电路板在外观上不怎么美观。
这次单片机课程设计,高了我们的逻辑思维能力,使我们在逻辑电路的分析与设计上有了很大的进步。
加深了我们对组合逻辑电路与时序逻辑电路的认识,进一步增进了对一些常见逻辑器件的了解。
还使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
我希望像这样的课程设计能多来几次,锻炼我们的独立思考和动手能力。
致谢
在我写本论文的过程中,贺科学老师给我提供了许多帮助,并对实践中出现的问题给予耐心的解答,完稿之后在百忙之中仔细阅读,给出修改意见。
贺老师爱岗敬业,治学严谨,思维严密,平易近人是我十分尊敬的老师,在此对他表示感谢。
在本文撰写的过程中,得到了李森涛和吴文俊同学的大力帮助,在这里对他们也表示的感谢!
参考文献
[1]李鸿等.单片机原理及应用[M].湖南大学出版社,2005.
[2]何立民.单片机高级教程---应用与设计[M].北京航空航天大学出版社,2000,8.
[3]戴佳.51单片机C语言应用程序设计实例精讲[M].北京:
电子工业出版社,2006.
[4]于京. 51系列单片机C程序设计与应用案例[M].北京:
中国电力出版社,2006.
[5]孙育才. ATMEL新型AT89S52系列单片机及其应用[M].北京:
清华大学出版社,2005.
[6]李华.MCS-51系列单片机实用接口技术[M].北京:
北京航空航天大学出版社,2000.
附录
附录A总原理图
附录BPCB图
附录C数字直流电压表总程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitcs=P1^0;
sbitdt=P1^1;
sbitio=P1^2;
charcodetable[]=
{0x3F,//0
0x06,//1
0x5B,//2
0x4F,//3
0x66,//4
0x6D,//5
0x7D,//6
0x07,//7
0x7F,//8
0x6F};//9
ucharaa;
uintqian;
uintc,d,a,e,i,cc;
floatbb;
voiddelay(uintt)
{
while(--t);
}
ucharduqu()
{
uchartemp;
temp=0;
cs=1;
io=0;
cs=0;
for(i=0;i<8;i++)
{
io=1;
temp=temp<<1;
if(dt)
{temp++;}
io=0;
}
cs=1;
delay(10);
return(temp);
}
voidxianshi()
{
aa=duqu();
bb=(0.009804*aa);
cc=bb*1000;
qian=bb;
c=(cc-qian*1000)/100;
d=(cc-qian*1000-c*100)/10;
e=cc-qian*1000-c*100-d*10;
P2=0xff;
P0=table[qian]|0x80;
P2=0xf7;
delay(50);
P0=0;
P2=0xfb;
P0=table[c];
delay(50);
P0=0;
P2=0xfd;
P0=table[d];
delay(50);
P0=0;
P2=0xfe;
P0=table[e];
delay(50);
P0=0;
}
voidmain()
{
while
(1)
{
xianshi();
}
}