基于ADC0809的数字电压表.docx
《基于ADC0809的数字电压表.docx》由会员分享,可在线阅读,更多相关《基于ADC0809的数字电压表.docx(17页珍藏版)》请在冰豆网上搜索。
基于ADC0809的数字电压表
南京信息工程大学
单片机课程设计
题目:
基于ADC0809的数字电压表
***********************
学号:
***********
所在学院:
电子与信息工程学院_
专业:
电子信息工程
****:
邹应全
二0一一年十二月十九日
摘要关键词……………………………………………………3
前言……………………………………………………3
硬件电路设计……………………………………………………3
软件设计……………………………………………………8
调试过程……………………………………………………8
实物图……………………………………………………9
结束语……………………………………………………10
附系统程序……………………………………………………11
基于ADC0809的数字电压表
南京信息工程大学电子与信息工程学院乔冬春南京210044
摘要:
本文主要介绍了一个基于STC89C52单片机的数字电压表,描述了利用ADC089进行电压采集转换,同时通过1602液晶显示的过程。
关键词:
STC89C52;ADC089;1602;电压表;单片机
一、前言
随着时代的进步和发展,单片机技术已经普及到我们生活、工作、科研、各个领域,已经成为一种比较成熟的技术,同时各种电子器件技术的发展,为我们的生产生活带来了许许多多的便利,从最初的数码管到如今的液晶,人们的视觉体验得到了极大的提高。
同时AD转换技术发展,将人类从模拟时代带入了数字时代,极大地简化了人类的工作量,对生产力的发展起到了巨大的推动作用。
二、硬件电路设计
单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能集成到一块硅片上构成的一个小而完善的计算机系统。
系统方框图
2.电路各模块分析
2.1STC89C52特性分析
STC89C52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
使用STC公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
STC89C52具有以下标准功能:
8k字节Flash,256字节RAM,32位I/O口线,看门狗定时器,2个数据指针,2个16位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。
另外,STC89C52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
2.2时钟电路
2.3复位电路
2.4串口模块
2.5AD转换模块
ADC0809引脚分布
1.IN0-IN7为模拟量输入端
2.CLOCK为外部时钟输入端
3.OUTPUTENABLE为输出使能端
4.ADDA/ADDB/ADDC为地址端
5.ADC0-ADC7为数字量输出端
6.EOC为转换结束信号段
7.VREF+为正参考电压端(一般接VCC)
8.VREF-为负参考电压输入端(一般接地)
9.VCC电源输入端(接+5V)
10.GND为接地端
2.6液晶显示模块
1602液晶各引脚
1.VSS为接地端
2.VDD接+5V
3.V0为液晶显示偏压信号
4.RS为数据/命令选择端
5.R/W为读/写信号选择端一般接地
6.E使能信号
7.DB0-DB7为数据/命令输入端
8.BLA为背光源正极
9.BLK为背光源负极
2.7电压采集处理模块
为扩展量程,故在AD模拟量输入端,采用电阻串联分压,再用软件处理的方法将电压表5V量程扩展至15V。
2.7元器件清单
名称
数量
STC89C52
1
ADC0809
1
MAX232
1
1602液晶
1
11.0592晶振
1
按键
1
排针
3排
10uf电解电容
1
30pf瓷片电容
6
510K电阻
3
10K电阻
1
自锁开关
1
USB母口
1
串口母口
1
10K电位器
1
各芯片底座
3
三、软件设计
四、调试过程
一开始现根据自身水平,选择题目,考虑到测温等题目选择的同学较多,同时,同时自己对ADC0809和1602液晶已经比较熟悉的现状,故决定选择这两个器件作为,题目的主要元器件。
现根据自身想法,开始画电路图,在用altiumdesigner画好图之后,便开始着手买元器件,进行焊接工作,在焊接时,主要考虑到布线不相互干扰,同时尽量美观,所以在焊接上花了一些时间,不过在此过程中也犯了一些错误,在ADC0809和STC89C52的连接电路中,由于一开始未能正确理解数字量输出端高位和低位的,这给接下来的软件设计部分带来较大麻烦。
在进行软件设计时,先设计整个执行流程图,由于过程并不复杂,所以在程序设计时,总体较顺利,出了上面提到的由于硬件焊接错误所造成的迟滞,还有一个就是对字符的定义上出了问题,在AD转换完之后,进行数据处理,一个变量被定义成unsignedchar型,最高只有65536,而在运算过程中,是超过这个值的,所以一开始显示的数值始终不正确,后来经过严密审查,终于发现问题所在。
在整个设计过程中,很多同学的热心帮忙也为设计工作带来了许多方便,故因要多交流,很多困扰的问题便迎刃而解了。
五、实物图
正面
反面
六、结束语
通过本次设计,让我对单片机以及液晶和AD有了更深刻的认识,同时明白一个道理,在做设计的时候一定要做到有条不紊,尽量将所有东西拆分成各个小模块进行处理,最后进行组合拼接,调试,这样不仅可以节约成本,而且方便扩展,同时要注意他人交流,闭门造车是没有出路的,在坚持独立自主的基础上,增强与他人交流,学习他人经验,以人之长补己之短,最终实现共赢。
附件:
系统程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineDataP0
#defineadcdatP1//adc数据口,接单片机P1,可根据硬件连接进行修改
sbitrs=P2^1;
sbite=P2^0;
sbitale_start=P2^2;//alesrart两个引脚因时序要求可接在一起,节约引脚
sbitoe=P2^4;
sbiteoc=P2^3;
sbitclk=P2^5;//adc采样时钟信号,由定时器产生,大约500k
longvalue;
longtt;
ucharcodetip[]="CURRENTVOLTAGE:
";
uchar*ptr1=tip;
ucharcodedisp_table[]={"0123456789.V"};
uchardisp_buf[6];//可用来显示电压
/******************************************************************
微秒延时函数
******************************************************************/
voiddelayus(uchari)
{
while(i--);
}
/******************************************************************
毫秒延时函数
******************************************************************/
voiddelayms(uintz)
{
uinti,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
/******************************************************************/
/*写入命令函数*/
/******************************************************************/
voidWriteCommand(unsignedcharc)
{
delayms(5);//操作前短暂延时,保证信号稳定
e=0;
rs=0;
_nop_();
e=1;
Data=c;
e=0;
}
/******************************************************************/
/*写入数据函数*/
/******************************************************************/
voidWriteData(unsignedcharc)
{
delayms(5);//操作前短暂延时,保证信号稳定
e=0;
rs=1;
_nop_();
e=1;
Data=c;
e=0;
rs=0;
}
/******************************************************************/
/*写入字节函数*/
/******************************************************************/
voidShowChar(unsignedcharpos,unsignedcharc)
{
unsignedcharp;
if(pos>=0x10)
p=pos+0xb0;//是第二行则命令代码高4位为0xc
else
p=pos+0x80;//是第二行则命令代码高4位为0x8
WriteCommand(p);//写命令
WriteData(c);//写数据
}
/******************************************************************/
/*写入字符串函数*/
/******************************************************************/
voidShowString(unsignedcharline,char*ptr,ucharnum)
{
unsignedcharl,i;
l=line<<4;
for(i=0;iShowChar(l++,*(ptr+i));//循环显示16个字符
}
/******************************************************************/
/*初始化函数*/
/******************************************************************/
voidInitLcd()
{
delayms(15);
WriteCommand(0x38);//displaymode
WriteCommand(0x38);//displaymode
WriteCommand(0x38);//displaymode
WriteCommand(0x06);//显示光标移动位置
WriteCommand(0x0c);//显示开及光标设置
WriteCommand(0x01);//显示清屏
}
/******************************************************************/
/*AD转换*/
/******************************************************************/
voidadc0809()
{
oe=0;
delayus(20);
ale_start=0;
delayus(20);
ale_start=1;
delayus(20);
ale_start=0;//ale和start正脉冲,锁存地址,同时启动AD转换
while(!
eoc);//等待转换结束
oe=1;//输出使能
delayus(20);
value=adcdat;//value采集到的电压值的数字量范围0~255
delayms(50);
oe=0;
delayms(300);
}
/**************************************
AD转换后进行数据处理比较
***************************************/
voidcompare(void)
{
adc0809();
tt=value*1500/255;
delayms(10);
}
/**************************************
刷新当前显示
***************************************/
voidnew_disp_buf(void)
{
compare();
disp_buf[0]=disp_table[tt/1000];//'1'
disp_buf[1]=disp_table[tt%1000/100];//'2'
disp_buf[2]=disp_table[10];//'.'
disp_buf[3]=disp_table[tt%100/10];//'du'
disp_buf[4]=disp_table[tt%10];//
disp_buf[5]=disp_table[11];//V
}
/**************************************
当前电压显示
***************************************/
voiddisplaycurrent(void)
{
new_disp_buf();//显示前先刷新缓冲区
ShowString(0,ptr1,16);//在第一行显示
ShowString(1,disp_buf,6);//第二行显示
}
voidmain()
{
InitLcd();
EA=1;
ET0=1;
TMOD=0x01;//定时器0,工作方式1
TH0=0xff;//频率500k
TL0=0x00;
TR0=1;
while
(1)
{
displaycurrent();
}
}
/**************************************
时钟子程序
***************************************/
voidtimint(void)interrupt1//定时器0中断服务函数,用以产生ADC0809的时钟信号
{
TH0=0xff;
TL0=0x00;
clk=~clk;
}