单片机课程设计电压表.docx

上传人:b****7 文档编号:9250002 上传时间:2023-02-03 格式:DOCX 页数:32 大小:257.67KB
下载 相关 举报
单片机课程设计电压表.docx_第1页
第1页 / 共32页
单片机课程设计电压表.docx_第2页
第2页 / 共32页
单片机课程设计电压表.docx_第3页
第3页 / 共32页
单片机课程设计电压表.docx_第4页
第4页 / 共32页
单片机课程设计电压表.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

单片机课程设计电压表.docx

《单片机课程设计电压表.docx》由会员分享,可在线阅读,更多相关《单片机课程设计电压表.docx(32页珍藏版)》请在冰豆网上搜索。

单片机课程设计电压表.docx

单片机课程设计电压表

单片机原理及接口技术

 

课程设计报告

 

设计题目:

电压表设计

学号:

姓名:

指导教师:

 

信息与电气工程学院

二零一四年六月

电压表设计

本文介绍了一种基于单片机的简易数字电压表的设计。

该设计主要由A/D转换模块、数据处理模块及显示模块。

A/D转换模块主要由芯片ADC0809来完成,它负责把采集到的模拟量转换为相应的数字量,然后再传送到数据处理模块。

数据处理模块则由芯片AT89C51来完成,其负责把ADC0809传送来的数字量经过一定的数据处理,产生相应的显示码送到显示模块进行显示;此外,它还控制着ADC0809芯片的工作。

该系统的数字电压表电路简单,所用的元件较少,成本低,且测量精度和可靠性较高。

此数字电压表可测量模拟输入电压值,并通过12864液晶显示出来。

电压表的设计是采用数字化的测量技术,把连续的模拟量转换成不连续的离散的数字形式并加以显示的仪表。

传统的指针式电压表功能单一,精度低,不能满足数字化时代的需求,采用单片机的数字电压表,由于精度高,抗干扰能力强,可扩展性强,集成方便,还可与PC进行实时通信。

数字电压表是诸多数字化仪表的核心与基础。

以数字电压表为核心可以扩展成各种通用数字仪表,专用数字仪表及各种非电量的数字化仪表。

目前,由各种单片A/D转换器构成的数字电压表已被广泛的用于电子及电工的测量、工业自动化仪表、自动测试系统等智能化测量领域,展示出强大的生命力。

新型数字电压表以其高准确度、高可靠性、高分辨率、高性价比等优良特性备受人们的青睐。

数字电压表作为数字化仪表的基础与核心,已被广泛的用于电子及电工的测量、工业自动化仪表、自动测试系统等智能化测量领域。

它把连续的模拟量转换成不连续的离散的数字形式并加以显示,有别于传统的以指针加刻度盘进行读数的方法,避免了读数的视差和视觉疲劳。

目前,数字万用表的内部核心部件是A/D转换器,转换器的精度很大程度上影响着数字万用表的准确度,本设计A/D转换器对输入模拟信号进行转换,控制核心AT89C51再对转换的结果进行运算和处理,最后驱动输出装置显示数字电压信号。

1.设计任务

结合实际情况,基于AT89C51单片机设计一个电压表。

应满足的功能要求为:

按键换量程(小数点的位置),使用ADC0809,串行静态显示(十进制),数值转换(小数运算BCD转换)。

主要硬件设备:

单片机实验开发系统:

矩阵键盘,开关量输入模块,液晶显示器,ADC0809模数转换芯片

2.整体方案设计

电压表设计以AT89C51单片机作为整个系统的控制核心,应用其强大的接口功能,构成整个硬件系统。

该系统主要由时钟电路复位电路ADC0809模块和12864液晶模块等几部分组成。

各模块的主要功能如下:

(1)时钟电路的功能是为单片机提供时钟信号

(2)复位电路的功能是使单片机处于某种确定的初始状态

(3)A/D转换器的功能是把需要测量的模拟电压信号转换成0~255的数字电压信号,然后送入单片机。

系统的整体设计方案设计图如图2-1所示。

图2-1系统的整体方案设计图

3.系统硬件电路设计

3.1时钟电路

AT89S51单片机各功能部件的运行都以时钟控制为基准,有条不紊、一拍一拍地工作。

因此,时钟频率直接影响单片机的速度,时钟电路的质量也直接影响单片机系统的稳定性。

单片机时钟信号产生有两种方式:

一是内部时钟电路,二是外部时钟电路,本设计使用内部时钟电路,在单片机的XTAL1和XTAL2引脚接石英晶体,作为单片机内部振荡电路的负载,构成中自激振荡器,可在单片机内部产生时钟脉冲信号,C3和C4可以稳定振荡频率,并使快速起振。

本电路选用晶振12MHz,C1=C2=30pF。

晶体的频率越高,系统的时间频率越高,单片机的运行速度也就越快。

其与单片机的接口电路如图3-1所示。

图3-1时钟电路

3.2复位电路

复位是单片机的初始化操作,只需给AT89S51的复位引脚RST加上大于2个机器周期(即24个时钟振荡周期)的高电平就可使AT89S51复位。

AT89S51的复位是由外部的复位电路实现的。

复位电路通常采用上电自动复位和按钮复位两种方式。

本设计采用的是上电复位电路。

上电自动复位电路是通过外部复位电路给电容C充电加至RST引脚一个短的高电平信号,信号随着Vcc对电容C的充电过程而逐渐回落,即RST引脚上的高电平持续时间取决于电容C的充电时间。

因此,为了保证系统可靠的复位,RST引脚上的高电平必须维持足够长的时间。

如图3-2

图3-2复位电路

3.3ADC0809模块

本设计所用A/D转换电路采用通用的ADC0809模数转换芯片,它是一种8位数字输出的逐次逼近式A/D转换器件,由单一的+5V电源供电。

片内带有锁存功能的8路选1的模拟开关,有CBA的编码来决定所选的通道。

ADC0809完成一次转换需100us左右,它具有TTL三态锁存缓冲器,可直接连到AT89C51单片机的数据总线上。

通过适当的外接电路,ADC0809可对0~5V的模拟信号进行转换。

  ADC0809应用说明:

ADC0809内部带有输出锁存器,可以与AT89C51单片机直接相连。

初始化时,使ST和OE信号全为低电平。

在ST端给出一个至少有100ns宽的正脉冲信号。

是否转换完毕我们根据EOC信号来判断。

当EOC变为高电平时,这时给OE为高电平,转换的数据就输出给单片机了。

其与单片机的接口电路如图3-3所示。

图3-3ADC0809与单片机的接口电路

3.412864液晶显示模块

(1)汉字和英文显示原理

在数字电路中,所有的数据都是以0和1保存的,对LCD控制器进行不同的数据操作,可以得到不同的结果。

对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即可。

而对于中文,常用却有6000以上,于是我们的DOS前辈想了一个办法,就是将ASCII表的高128个很少用到的数值以两个为一组来表示汉字,即汉字的内码。

而剩下的低128位则留给英文字符使用,即英文的内码。

  那么,得到了汉字的内码后,还仅是一组数字,那又如何在屏幕上去显示呢?

这就涉及到文字的字模,字模虽然也是一组数字,但它的意义却与数字的意义有了根本的变化,它是用数字的各位信息来记载英文或汉字的形状,如英文的'A'在字模的记载方式如图1所示

而中文的“你”在字模中的记载却如图2所示:

根据芯片的不同取模的方式不同,有多种取模方式:

单色点阵液晶字模,横向取模,字节正序,单色点阵液晶字模,横向取模,字节倒序,单色点阵液晶字模,纵向取模,字节正序,单色点阵液晶字模,纵向取模,字节倒序等等。

而PROTUES中的AMPIRE12684为纵向取模,字节倒序液晶

(2)图形显示

先设页地址再设列地址

页地址范围0xb8~0xbf

列平地址范围0x40~0x7f

绘图RAM的地址计数器(AC)只对列地址自动加一,当列地址=0x7F时会重新设为0

DDRAM的坐标地址与资料排列顺序如下图:

本实验所用12864液晶显示器

4.系统程序设计

4.1主程序流程图

系统主程序流程图如图4-1所示。

 

图4-1主程序流程图

 

5.系统调试

5.1Proteus软件仿真调试

(1)调试过程

启动计算机,打开Proteus仿真软件,进入仿真环境。

将写好的程序存入单片机中,点击运行。

即可观察程序运行情况,也可以通过暂停键暂停程序,通过结束键随时结束程序。

(2)调试时遇到的问题及解决方法

1)在第一次调试时,我忘记了给ADC0809的CLK引脚提供时钟信号,结果ADC输出的值都是0,然后我找到ADC0809的时序图进行分析,最终,我发现了我所忽视的问题,然后在proteus的元件库中找到了一个信号发生器用来给ADC0809提供时钟信号。

ADC0809输出正常。

2)在第一次调试时,我们的液晶屏显示全部是黑屏,经过仔细排查,最终确定是元件电路图出现的问题,最终我将液晶的数据口的标号去掉,用导线一根一根的与单片机的I/O口相连,才使液晶屏显示正常。

原来是我的标号使用错误导致的液晶屏显示不正常。

3)在ADC0809采集正常、12864液晶显示正常以后,我们发现ADC0809采集的数据不正常,会出现大幅度波动,并且显示的测得电压有时候不正确。

这是因为ADC0809是逐次比较型AD,所以它的精度是不准确的,一般情况下逐次比较型AD是不能用作仪表用AD的,仪表级运放一般都是运用双积分型AD。

但是因为硬件外设的限制,我们只能用ADC0809。

因此,我们在算法上进行了优化,采用连续取样三次取平均的平均值算法。

在我们采用了平均值算法以后,ADC的采样值稳定了许多也准确了许多。

(3)调试运行结果

 

  档位4

档位3

档位2

  档位1

5.2硬件调试

(1)调试过程

安装好仿真器,用串行数据通信线连接计算机与仿真器,把仿真头插到模块的单片机插座中,打开模块电源,插上仿真器电源插头。

将写好的.C文件通过Keil软件生成.hex文件。

打开STC-ISP软件,打开程序文件,改变和电脑相适应的COM口,点击下载,将hex文件考入单片机中。

观察测试结果。

(2)调试时遇到的问题及解决方法

1)在我们连接好硬件线路开始硬件仿真时,发现液晶屏没有显示,于是开始排查软件问题,结果调试了很久还是没有显示,这时才怀疑是硬件问题,我们将实验箱提供的12864的例程烧写进去,结果还是没有显示。

我们才知道原来是液晶坏了,于是我们换了一个实验箱,液晶才显示正常。

2)这个实验箱的P0口没有接上拉电阻,所以不能当做通用I/O使用,于是我们自行焊接了一个上拉电阻,接在了P0口上。

在我们连接好硬件线路开始硬件仿真后,我们的ADC输出全为0,于是我编写了一个用P0口驱动LED灯的小程序来测试经过我们上拉以后的P0口的推动能力,我们用电压表测量了P0口的输出,发现P0口输出的低电平正常,为0.07V,而P0口的高电平只能上拉到0.5V。

所以我们怀疑由于P0口的其他连线,将P0口的输出拉低了,所以我们放弃了P0口,将P3口进行分时复用,既作为ADC0809的数据输入口,又作为12864液晶屏的数据口。

最终我们的液晶屏的显示和ADC0809的采集全部正常,完美地完成了所有功能。

6.程序清单

#include

#include"ascii.h"

#defineucharunsignedchar

#defineuintunsignedint

#defineNULL0

#defineLCD_DATAP3

sbitRS=P2^2;

sbitRW=P2^1;

sbitLCD_EN=P2^0;

sbitLCD_CS1=P2^5;

sbitLCD_CS2=P2^4;

sbitCLK=P1^4;

sbitST=P1^5;

sbitOE=P1^6;

sbitEOC=P1^0;

sbitSW1=P2^6;

sbitSW2=P2^7;

voiddelay(unsignedchartime)//延时

{

unsignedchari,j;

for(i=0;i

for(j=0;j<110;j++);

}

voidinit()

{

//P2=0xff;

EA=1;//开总中断

TMOD=0x02;//设定定时器T0工作方式

TH0=0xd8;//利用T0中断产生CLK信号

TL0=0xd8;//定时40us频率25K

TR0=1;//启动定时器T0

ET0=1;

ST=1;

OE=1;

//P1=0x06;

}

uintadin0()

{

uintvalue;

OE=1;

ST=1;

P1&=0xf1;

P1|=0x06;

delay

(1);

ST=0;

delay

(1);

ST=1;

while(!

EOC);

delay

(1);

OE=0;

delay

(1);

P0=0xff;

Value=P0;

OE=1;

returnvalue;

}

uintadin1()

{

uintvalue;

OE=1;

EOC=1;

ST=1;

P1&=0xf1;

P1|=0x00;

delay

(1);

ST=0;

delay

(1);

ST=1;

while(!

EOC);

delay

(1);

OE=0;

delay

(1);

P0=0xff;

Value=P0;

OE=1;

returnvalue;

}

ucharSW()

{

ucharflag=0;

if(SW1==0)

{

if(SW2==0)

Flag=1;

else

Flag=2;

}

if(SW1==1)

{

if(SW2==0)

Flag=3;

else

Flag=4;

}

returnflag;

}

unsignedcharLCD_CheckBusy(void);

voidlcd_delay(void)

{

unsignedchari=10;

while(i--);

}

voidLCD_WriteData(unsignedchardat)

{

//while(LCD_CheckBusy());

LCD_DATA=dat;

RW=0;

RS=1;

LCD_EN=0;

LCD_EN=1;

//lcd_delay();

LCD_EN=0;

RW=1;

RS=1;

}

unsignedcharLCD_ReadData(void)

{

unsignedchardat;

//while(LCD_CheckBusy());

LCD_DATA=0xff;

RW=1;

RS=1;

LCD_EN=0;

Dat=LCD_DATA;

LCD_EN=1;

LCD_EN=0;

RW=0;

RS=1;

returnLCD_DATA;

}

voidLCD_WriteCommand(unsignedcharcmd_code)

{

while(LCD_CheckBusy());

RW=0;

RS=0;

LCD_DATA=cmd_code;

LCD_EN=0;

LCD_EN=1;

lcd_delay();

LCD_EN=0;

//LCD_EN=1;

RW=1;

RS=1;

}

voidKS0108_ChipSelect(unsignedcharpart)

{

if(part==1)

{

LCD_CS1=0;

LCD_CS2=1;

}

else

{

LCD_CS1=1;

LCD_CS2=0;

}

}

unsignedcharLCD_CheckBusy(void)

{

unsignedcharstatus;

LCD_DATA=0XFF;

RW=1;

RS=0;

lcd_delay();

LCD_EN=0;

LCD_EN=1;

lcd_delay();

LCD_EN=0;

LCD_EN=1;

Status=LCD_DATA;

RW=1;

RS=1;

if(status&0x80)

return1;

else

return0;

}

voidLCD_Init(void)

{

KS0108_ChipSelect

(1);

LCD_WriteCommand(0x3f);

KS0108_ChipSelect

(2);

LCD_WriteCommand(0x3f);

LCD_WriteCommand(0xc0|0);//起始行为0

LCD_WriteCommand(0xB8|0);//起始页为0

}

voidLCD_SetCol(unsignedcharcol)

{

LCD_WriteCommand(0x40|col);

}

voidLCD_SetPage(unsignedcharpage)

{

LCD_WriteCommand(0xb8|page);

}

voidLCD_DisplayChar(charc,unsignedcharrow,unsignedcharcol)

{

unsignedshorti;

unsignedchartemp;

LCD_SetPage(row);

LCD_SetCol(col);

for(i=0;i<8;i++)

{

temp=ascii_table[c][i];

LCD_WriteData(ascii_table[c][i]);

}

}

voidLCD_ClearAll(void)

{

unsignedcharpage,col;

KS0108_ChipSelect

(1);

for(page=0;page<8;page++)

{

LCD_SetPage(page);

LCD_SetCol(0);

for(col=0;col<64;col++)

{

//LCD_SetCol(col);

LCD_WriteData(0x00);

}

}

KS0108_ChipSelect

(2);

for(page=0;page<8;page++)

{

LCD_SetPage(page);

LCD_SetCol(0);

for(col=0;col<64;col++)

{

//LCD_SetCol(col);

LCD_WriteData(0x00);

}

}

}

voidLCD_ClearRegion(unsignedcharrow,unsignedcol_start,unsignedcharcol_end)

{

unsignedchari;

if(col_start>=64)

return;

if(col_end>=64)

col_end=63;

LCD_SetPage(row);

LCD_SetCol(col_start);

for(i=col_start;i<=col_end;i++)

LCD_WriteData(0x00);

}

voidLCD_DisplayString(char*s,unsignedcharrow,unsignedcharcol)

{

while(*s)

{

LCD_DisplayChar((*s)-0x20,row,col);

col+=8;

if(col>64-8)

{

col=0;

row++;

if(row>=8)

return;

}

s++;

}

}

voidNumtoString(uintin0,uintin1,ucharflag,char*buf,char*buf2,char*buf3)

{

uintdec=0;

uintnum1=0,num2=0,num3=0,num4=0;

*buf2++=(in0/100+0x30);

*buf2++=(in0%100/10+0x30);

*buf2++=(in0%10+0x30);

*buf2='\0';

*buf3++=(in1/100+0x30);

*buf3++=(in1%100/10+0x30);

*buf3++=(in1%10+0x30);

*buf3='\0';

if(in1>in0)

{

*buf++='+';

dec=(in1-in0)*625/32;

num4=dec/1000;

num3=dec%1000/100;

num2=dec%100/10;

num1=dec%10;

if(num4>0&&flag==1)

flag=2;

if(flag==1)

{

*buf++='.';

*buf++=(0x30+num3);

*buf++=(0x30+num2);

*buf++=(0x30+num1);

*buf++='0';

*buf++='0';

*buf++='0';

}

if(flag==2)

{

*buf++=(0x30+num4);

*buf++='.';

*buf++=(0x30+num3);

*buf++=(0x30+num2);

*buf++=(0x30+num1);

*buf++='0';

*buf++='0';

}

if(flag==3)

{

*buf++='0';

*buf++=(0x30+num4);

*buf++='.';

*buf++=(0x30+num3);

*buf++=(0x30+num2);

*buf++=(0x30+num1);

*buf++='0';

}

if(flag==4)

{

*buf++='0';

*buf++='0';

*buf++=(0x30+num4);

*buf++='.';

*buf++=(0x30+num3);

*buf++=(0x30+num2);

*buf++=(0x30+num1);

}

}

if(in0>in1)

{

*buf++='-';

dec=(in0-in1)*625/32;

num4=dec/1000;

num3=dec%1000/100;

num2=dec%100/10;

num1=dec%10;

if(num4>0&&flag==1)

flag=2;

if(flag==1)

{

*buf++='.';

*buf++=(0x30+num3);

*buf++=(0x30+num2);

*buf++=(0x30+num1);

*buf++='0';

*buf++='0';

*buf++='0';

}

if(flag==2)

{

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1