AT89C51单片机毕业设计.docx
《AT89C51单片机毕业设计.docx》由会员分享,可在线阅读,更多相关《AT89C51单片机毕业设计.docx(15页珍藏版)》请在冰豆网上搜索。
AT89C51单片机毕业设计
AT89C51单片机-毕业设计
1.绪论
1.1课程设计要求
使用单片机AT89C51和ADC0832设计一个数字电压表,能够测量0-5V之间的直流电压值,两位数码显示。
在单片机的作用下,能监测两路的输入电压值,用8位串行A/D转换器,8位分辨率,逐次逼近型,基准电压为5V;能用两位LED进行轮流显示或单路选择显示,显示精度0.1伏。
1.2数字电压表介绍
数字电压表简称DVM,数字电压表基本原理是将输入的模拟电压信号转化为数字信号,再进行输出显示。
而A/D转换器的作用是将连续变化的模拟信号量转化为离散的数字信号,器基本结构是由采样保持,量化,编码等几部分组成。
因此AD转换是此次设计的核心元件。
输入的模拟量经过AD转换器转换,再由驱动器驱动显示器输出,便得到测量的数字电压。
2.硬件单元电路设计
2.1数字电压表结构框图
结构如(图1)所示
图1
2.1.1AT89C51单片机简介
AT89C51是一个低功耗,高性能CMOS 8位单片机,片内含4kBytes ISP(In-systemprogrammable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,AT89C51在众多嵌入式控制应用系统中得到广泛应用。
51单片机内包含以下几个部件:
1)8位微处理器(CPU)。
2)数据存储器(128BRAM)。
3)程序存储器(ROM/EPROM)。
4)4个8位可编程并行I/O口(P0口,P1口,P2口,P3口)。
5)1个全双工的异步串行口。
6)2个16定时器/计数器。
7)中断系统。
8)特殊功能寄存器(SFR)。
图2
单片机片内结构如(图2)所示:
2.1.2ADC0832转换器简介
ADC0832是美国国家半导体公司生产的一种8位分辨率、双通道A/D转换芯片。
由于它体积小,兼容性强,性价比高而深受单片机爱好者及企业欢迎,其目前已经有很高的普及率。
学习并使用ADC0832可是使我们了解A/D转换器的原理,有助于我们单片机技术水平的提高。
芯片如下(图3)所示:
图3
芯片接口说明如下:
CS_片选使能,低电平芯片使能。
CH0模拟输入通道0,或作为IN+/-使用。
CH1模拟输入通道1,或作为IN+/-使用。
GND芯片参考0电位(地)。
DI数据信号输入,选择通道控制。
DO数据信号输出,转换数据输出。
CLK芯片时钟输入。
Vcc/REF电源输入及参考电压输入(复用)。
工作原理如下:
正常情况下ADC0832与单片机的接口应为4条数据线,分别是CS、CLK、DO、DI。
但由于DO端与DI端在通信时并未同时有效并与单片机的接口是双向的,所以电路设计时可以将DO和DI并联在一根数据线上使用。
当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用,CLK和DO/DI的电平可任意。
当要进行A/D转换时,须先将CS使能端置于低电平并且保持低电平直到转换完全结束。
此时芯片开始转换工作,同时由处理器向芯片时钟输入端CLK输入时钟脉冲,DO/DI端则使用DI端输入通道功能选择的数据信号。
在第1个时钟脉冲的下沉之前DI端必须是高电平,表示启始信号。
在第2、3个脉冲下沉之前DI端应输入2位数据用于选择通道功能。
当此2位数据为“1”、“0”时,只对CH0进行单通道转换。
当2位数据为“1”、“1”时,只对CH1进行单通道转换。
当2位数据为“0”、“0”时,将CH0作为正输入端IN+,CH1作为负输入端IN-进行输入。
当2位数据为“0”、“1”时,将CH0作为负输入端IN-,CH1作为正输入端IN+进行输入。
到第3个脉冲的下沉之后DI端的输入电平就失去输入作用,此后DO/DI端则开始利用数据输出DO进行转换数据的读取。
从第4个脉冲下沉开始由DO端输出转换数据最高位DATA7,随后每一个脉冲下沉DO端输出下一位数据。
直到第11个脉冲时发出最低位数据DATA0,一个字节的数据输出完成。
也正是从此位开始输出下一个相反字节的数据,即从第11个字节的下沉输出DATD0。
随后输出8位数据,到第19个脉冲时数据输出完成,也标志着一次A/D转换的结束。
最后将CS置高电平禁用芯片,直接将转换后的数据进行处理就可以了。
2.1.3时钟电路
XTAL1是片内振荡器的反相放大器输入端,XTAL2则是输出端,使用外部振荡器时,外部振荡信号应直接加到XTAL1,而XTAL2悬空。
内部方式时,时钟发生器对振荡脉冲二分频,如晶振为12MHz,时钟频率就为6MHz。
晶振的频率可以在1MHz-24MHz内选择。
电容取30PF左右。
系统的时钟电路设计是采用的内部方式,即利用芯片内部的振荡电路如下(图4)所示:
图4
2.1.4复位电路
由电容串联电阻构成,由图并结合"电容电压不能突变"的性质,可以知道,当系统一上电,RST脚将会出现高电平,并且,这个高电平持续的时间由电路的RC值来决定.典型的51单片机当RST脚的高电平持续两个机器周期以上就将复位,所以,适当组合RC的取值就可以保证可靠的复位.一般教科书推荐C取10u,R取8.2K.当然也有其他取法的,原则就是要让RC组合可以在RST脚上产生不少于2个机周期的高电平.至于如何具体定量计算,可以参考电路分析相关书籍.复位电路如下(图5)所示。
图5
2.1.5LED显示电路
本项目所用显示屏为4位LED显示屏。
本LED显示器为8段(DP为小数点段),每一段为一个发光二极管。
发光二极管有共阳极和共阴极两种。
本显示器的发光二极管为共阳极数码管。
发光二极管的阳极连接在一起,通常在此共阳极接正电压,当某个发光二极管的阴极接低电平时,发光二极管被点亮,相应的段被显示。
通过给LED显示器提供不同的代码,是这些不同的LED显示器相应的段发光显示不同的字型,这些代码称为段码。
本项目所用段码值如下(表1)所示:
显示字符
0
1
2
3
4
5
6
7
8
9
共阳极段码
0x03
0x9f
0x25
0x0d
0x99
0x49
0x41
0x1f
0x01
09
表1
3.软件单元电路设计
3.1主程序流程图
主程序流程图如下(图6)所示:
图6
3.2显示子程序流程图
显示子程序流程图如下(图7)所示:
图7
3.3A/D转换子程序流程图
A/D转换子程序流程图如下(图8)所示:
图8
3.4数据处理子程序流程图
数据处理子程序流程图,如下(图9)所示:
图9
4.数字电压表仿真设计图与实物图
4.1仿真图
如下(图10)所示:
图10
4.2器件清单
表2
如下(表2)所示
所用器件名称
型号及大小
个数
单片机开发板
AT89C51
一个
滑动变阻器
10K
两个
A\D转换器
ADC0832
一个
LED
共阳
一个
跳线插口
--
若干
跳线
--
若干
4.3硬件电路实物图
图11
电路实物图如下(图11)所示:
图12
电路实物图如下(图12)所示:
5.程序代码
#include
#include
/*********************************端口定义**********************************/
sbitCS=P3^5;
sbitClk=P3^3;
sbitDATI=P3^4;
sbitDATO=P3^4;
sbitP20=P2^4;
/*******************************定义全局变量********************************/
unsignedchardat=0x00;//AD值
unsignedcharcount=0x00;//定时器计数
unsignedcharCH;//通道变量
unsignedchardis[]={0x00,0x00,0x00};//显示数值
/*******************************共阳LED段码表*******************************/
unsignedcharcodetab[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};
charcodetablewe[]={0xfd,0xfb,0xf7,0xef,0xdf,0xfe};
/****************************************************************************
函数功能:
AD转换子程序
入口参数:
CH
出口参数:
dat
****************************************************************************/
unsignedcharadc0832(unsignedcharCH)
{
unsignedchari,test,adval;
adval=0x00;
test=0x00;
Clk=0;//初始化
DATI=1;
_nop_();
CS=0;
_nop_();
Clk=1;
_nop_();
if(CH==0x00)//通道选择
{
Clk=0;
DATI=1;//通道0的第一位
_nop_();
Clk=1;
_nop_();
Clk=0;
DATI=0;//通道0的第二位
_nop_();
Clk=1;
_nop_();
}
else
{
Clk=0;
DATI=1;//通道1的第一位
_nop_();
Clk=1;
_nop_();
Clk=0;
DATI=1;//通道1的第二位
_nop_();
Clk=1;
_nop_();
}
Clk=0;
DATI=1;
for(i=0;i<8;i++)//读取前8位的值
{
_nop_();
adval<<=1;
Clk=1;
_nop_();
Clk=0;
if(DATO)
adval|=0x01;
else
adval|=0x00;
}
for(i=0;i<8;i++)//读取后8位的值
{
test>>=1;
if(DATO)
test|=0x80;
else
test|=0x00;
_nop_();
Clk=1;
_nop_();
Clk=0;
}
if(adval==test)//比较前8位与后8位的值,如果不相同舍去。
若一直出现显示为零,请将该行去掉
dat=test;
nop_();
CS=1;//释放ADC0832
DATO=1;
Clk=1;
returndat;
}
/****************************************************************************
函数功能:
延时子程序
入口参数:
出口参数:
****************************************************************************/
voiddelay(void)
{
intk;
for(k=10;k<500;k++);
}
/****************************************************************************
函数功能:
将0-255级换算成0.00-5.00的电压数值
入口参数:
i
出口参数:
****************************************************************************/
voidconvdata(unsignedchari)
{
dis[0]=i/51;//个位
dis[1]=(i%51)*10/51;//小数点后第一位
dis[2]=((i%51)*10%51)*10/51;//小数点后第二位
}
/****************************************************************************
函数功能:
数码管显示子程序
入口参数:
出口参数:
****************************************************************************/
voiddisplay(void)
{
P2=0xff;
P0=tab[dis[0]]&0xfe;//显示个位和小数点11111110
delay();
P2=0xdf;//11011111
delay();
P2=0xff;
P0=tab[dis[1]];//显示小数点后第一位
delay();
P2=0xbf;//10111111
delay();
P2=0xff;
P0=tab[dis[2]];//显示小数点后第二位
delay();
P2=0x7f;//01111111
delay();
P2=0xff;
P0=0xff;//显示小数点后第二位
delay();
P2=0xef;//11101111
delay();
}
/****************************************************************************
函数功能:
主程序
入口参数:
出口参数:
****************************************************************************/
voidmain(void)
{
P2=0xff;//端口初始化
P0=0xff;
delay();//延时
CH=0x00;//在这里选择通道0x00或0x01
TMOD=0x01;//设置中断
TH0=(65536-50000)/256;//定时器1初值定时50ms
TL0=(65536-50000)%256;
IE=0x82;
TR0=1;
while
(1)//主循环
{dat=adc0832(CH);
convdata(dat);//数据转换
display();//显示数值
}
}/****************************************************************************
函数功能:
定时器中断延时程序这一段的作用时隔一段时间抽样一次否侧显示的最后一位会不稳定
入口参数:
出口参数:
****************************************************************************/
voidtimer0(void)interrupt1
{
TMOD=0x01;
TH0=(65536-50000)/256;//定时器1初值定时50ms
TL0=(65536-50000)%256;
IE=0x82;
TR0=1;
count++;
if(count==0x01)
{
count=0x00;
dat=adc0832(CH);
}
}
6.项目设计总计
通过这次设计,使我深入了解了AT89C51单片机和ADC0832(A\D转换器)的结构和特点及数字电压表的工作原理,加深了对课本理论知识的理解,锻炼了实践动手能力,理论知识与实践设计相结合,培养了创新开发的思维。
在此次课程设计中,收获知识的同时,我还收获了阅历。
在此过程中,我们通过查找资料,请教老师,以及不懈的努力,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。
7.参考文献
[1]陈朝元,鲁五一.Proteus软件在自动控制系统仿真中的应用[J].系统仿真学报,2008
(1):
318-320.
[2]毛谦敏.单片机原理及应用设计系统[M].北京:
国防工业出版社,2008:
22-26.
[3]康华光.电子技术基础(数字部分)[M].5版.北京:
高等教育出版,2005:
290-293.
评语
成绩
指导教师
(签字)
年月日