简易数字直流电压表的设计--单片机课程设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、前言
数字电压表(Digital Voltmeter)简称DVM,它是采用数字化测量技术,把连续的模拟量(直流输入电压)转换成不连续、离散的数字形式并加以显示的仪表。
传统的指针式电压表功能单一、精度低,不能满足数字化时代的需求,采用单片机的数字电压表,由精度高、抗干扰能力强,可扩展性强、集成方便,还可与PC进行实时通信。
目前,由各种单片A/D 转换器构成的数字电压表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,示出强大的生命力。
与此同时,由DVM扩展而成的各种通用及专用数字仪器仪表,也把电量及非电量测量技术提高到崭新水平。
本章重点介绍单片A/D 转换器以及由它们构成的基于单片机的数字电压表的工作原理。
2 、系统原理及基本框图
如图2.1所示,模拟电压经过档位Array切换到不同的分压电路衰减后,经隔离
干扰送到A/D转换器进行A/D转换,然
后送到单片机中进行数据处理。
处理后
的数据送到LED中显示。
图2.1系统基本方框图
3、硬件设计
3.1 、电源电路
图 3.1 电源电路原理图
3.2 、A/D 转换电路
A/D 转换器的转换精度对测量电路极其重要,它的参数关系到测量电路性能。
本设计采用A/D 转换器,它的性能比较稳定,转换精度高,具有很高的抗干扰能力,电路结构简单,其缺点是工作速度较低。
在对转换精度要求较高,而对转换速度要求不高的场合如电压测量有广泛的应用。
图3.2.1 A/D 转换器
图
3.2.2双积A/D 转换器的波形图
如图所示:对输入模拟电压和基准电压进行两次积分,先对输入模拟电压进行积分,将其变换成与输入模拟电压成正比的时间间隔 T1,再利用计数器测出此时间间隔,则计数器所计的数字量就正比于输入的模拟电压;接着对基准电压进行同样的处理。
在常用的A/D转换芯片(如ADC -0809、ICL7135、
ICL7109 等)中,ICL7135与其余几种有所不同,它是一种四位半的A/D转换器,具有精度高(精度相当于14位二进制数)、价格低廉、抗干扰能力强等优点。
3.3、单片机部分
单片机选用的是ATMEL 公司新推出的AT89S52,如图 3.2.1.1所示。
该芯
图3.2.1.2双积A/D 转换器的波形图
片具有低功耗、高性能的特点,是采用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.1 AT89S52引脚图
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 程序段解释
延时程序:
void delay(uint t)
{
while(--t);
}
根据TLC549的工作时序图,使用P1.0作为片选端cs,P1.1作为数据输出端dt,P1.2作为时钟输入端io。
先初始化AD芯片,然后打开片选端cs,开始检测数据输出端dt的电平,用变量temp记录数据。
程序如下:
uchar duqu()
{
uchar temp;
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口控制数码管显示。
void xianshi()
{
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;
}
以下是主程序部分,直接使用显示程序即可获得测的电压值。
void main()
{
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 总原理图
附录B PCB图
附录C 数字直流电压表总程序
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit cs=P1^0;
sbit dt=P1^1;
sbit io=P1^2;
char code table[]=
{ 0x3F, //0
0x06, //1
0x5B, //2
0x4F, //3
0x66, //4
0x6D, //5
0x7D, //6
0x07, //7
0x7F, //8
0x6F}; //9
uchar aa;
uint qian;
uint c,d,a,e,i,cc;
float bb;
void delay(uint t) {
while(--t);
}
uchar duqu() {
uchar temp;
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);
}
void xianshi()
{
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;
}
void main()
{
while(1)
{
xianshi();
}
}。