ImageVerifierCode 换一换
格式:DOCX , 页数:32 ,大小:257.69KB ,
资源ID:12120431      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12120431.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(单片机课程设计电压表.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

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

1、单片机课程设计电压表单片机原理及接口技术课程设计报告设计题目:电压表设计学 号:姓 名:指导教师: 信息与电气工程学院二零一四年六月电压表设计本文介绍了一种基于单片机的简易数字电压表的设计。该设计主要由A/D转换模块 、数据处理模块及显示模块。A/D转换模块主要由芯片ADC0809来完成,它负责把采集到的模拟量转换为相应的数字量,然后再传送到数据处理模块。数据处理模块则由芯片AT89C51来完成,其负责把ADC0809传送来的数字量经过一定的数据处理,产生相应的显示码送到显示模块进行显示;此外,它还控制着ADC0809芯片的工作。该系统的数字电压表电路简单,所用的元件较少,成本低,且测量精度和

2、可靠性较高。此数字电压表可测量模拟输入电压值,并通过12864液晶显示出来。电压表的设计是采用数字化的测量技术,把连续的模拟量转换成不连续的离散的数字形式并加以显示的仪表。传统的指针式电压表功能单一,精度低,不能满足数字化时代的需求,采用单片机的数字电压表,由于精度高,抗干扰能力强,可扩展性强,集成方便,还可与PC进行实时通信。数字电压表是诸多数字化仪表的核心与基础。以数字电压表为核心可以扩展成各种通用数字仪表,专用数字仪表 及各种非电量的数字化仪表。目前,由各种单片A/D转换器构成的数字电压表已被广泛的用于电子及电工的测量、工业自动化仪表、自动测试系统等智能化测量领域,展示出强大的生命力。新

3、型数字电压表以其高准确度、高可靠性、高分辨率、高性价比等优良特性备受人们的青睐。数字电压表作为数字化仪表的基础与核心,已被广泛的用于电子及电工的测量、工业自动化仪表、自动测试系统等智能化测量领域。它把连续的模拟量转换成不连续的离散的数字形式并加以显示,有别于传统的以指针加刻度盘进行读数的方法,避免了读数的视差和视觉疲劳。目前,数字万用表的内部核心部件是A/D转换器,转换器的精度很大程度上影响着数字万用表的准确度,本设计A/D转换器对输入模拟信号进行转换,控制核心AT89C51再对转换的结果进行运算和处理,最后驱动输出装置显示数字电压信号。1. 设计任务结合实际情况,基于AT89C51单片机设计

4、一个电压表。应满足的功能要求为:按键换量程(小数点的位置),使用ADC0809,串行静态显示(十进制),数值转换(小数运算 BCD转换)。主要硬件设备:单片机实验开发系统:矩阵键盘,开关量输入模块,液晶显示器,ADC0809模数转换芯片2. 整体方案设计电压表设计以AT89C51单片机作为整个系统的控制核心,应用其强大的接口功能,构成整个硬件系统。该系统主要由时钟电路 复位电路 ADC0809模块和12864液晶模块等几部分组成。各模块的主要功能如下:(1) 时钟电路的功能是为单片机提供时钟信号(2) 复位电路的功能是使单片机处于某种确定的初始状态(3) A/D转换器的功能是把需要测量的模拟电

5、压信号转换成0255的数字电压信号,然后送入单片机。系统的整体设计方案设计图如图2-1所示。图2-1 系统的整体方案设计图3. 系统硬件电路设计3.1 时钟电路AT89S51单片机各功能部件的运行都以时钟控制为基准,有条不紊、一拍一拍地工作。因此,时钟频率直接影响单片机的速度,时钟电路的质量也直接影响单片机系统的稳定性。单片机时钟信号产生有两种方式:一是内部时钟电路,二是外部时钟电路,本设计使用内部时钟电路,在单片机的XTAL1和XTAL2引脚接石英晶体,作为单片机内部振荡电路的负载,构成中自激振荡器,可在单片机内部产生时钟脉冲信号,C3和C4可以稳定振荡频率,并使快速起振。本电路选用晶振12

6、MHz,C1=C2=30pF。晶体的频率越高,系统的时间频率越高,单片机的运行速度也就越快。其与单片机的接口电路如图3-1所示。图3-1 时钟电路3.2 复位电路复位是单片机的初始化操作,只需给AT89S51的复位引脚RST加上大于2个机器周期(即24个时钟振荡周期)的高电平就可使AT89S51复位。AT89S51的复位是由外部的复位电路实现的。复位电路通常采用上电自动复位和按钮复位两种方式。本设计采用的是上电复位电路。上电自动复位电路是通过外部复位电路给电容C充电加至RST引脚一个短的高电平信号,信号随着Vcc对电容C的充电过程而逐渐回落,即RST引脚上的高电平持续时间取决于电容C的充电时间

7、。因此,为了保证系统可靠的复位,RST引脚上的高电平必须维持足够长的时间。如图3-2图3-2 复位电路3.3 ADC0809模块本设计所用A/D转换电路采用通用的ADC0809模数转换芯片,它是一种8位数字输出的逐次逼近式A/D转换器件,由单一的+5V电源供电。片内带有锁存功能的8路选1的模拟开关,有CBA的编码来决定所选的通道。ADC0809完成一次转换需100us左右,它具有TTL三态锁存缓冲器,可直接连到AT89C51单片机的数据总线上。通过适当的外接电路,ADC0809可对05V的模拟信号进行转换。ADC0809应用说明:ADC0809内部带有输出锁存器,可以与单片机直接相连。初始化时

8、,使和信号全为低电平。在端给出一个至少有宽的正脉冲信号。是否转换完毕我们根据信号来判断。当变为高电平时,这时给为高电平,转换的数据就输出给单片机了。其与单片机的接口电路如图3-3所示。图3-3 ADC0809与单片机的接口电路3.4 12864液晶显示模块(1) 汉字和英文显示原理在数字电路中,所有的数据都是以0和1保存的,对LCD控制器进行不同的数据操作,可以得到不同的结果。对于显示英文操作,由于英文字母种类很少,只需要8位(一字节)即可。而对于中文,常用却有6000以上,于是我们的DOS前辈想了一个办法,就是将ASCII表的高128个很少用到的数值以两个为一组来表示汉字,即汉字的内码。而剩

9、下的低128位则留给英文字符使用,即英文的内码。 那么,得到了汉字的内码后,还仅是一组数字,那又如何在屏幕上去显示呢?这就涉及到文字的字模,字模虽然也是一组数字,但它的意义却与数字的意义有了根本的变化,它是用数字的各位信息来记载英文或汉字的形状,如英文的A在字模的记载方式如图1所示而中文的“你”在字模中的记载却如图2所示:根据芯片的不同取模的方式不同,有多种取模方式:单色点阵液晶字模,横向取模,字节正序,单色点阵液晶字模,横向取模,字节倒序,单色点阵液晶字模,纵向取模,字节正序,单色点阵液晶字模,纵向取模,字节倒序等等。而PROTUES中的AMPIRE12684为纵向取模,字节倒序液晶(2)

10、图形显示先设页地址再设列地址页地址范围 0xb80xbf列平地址范围 0x400x7f绘图RAM 的地址计数器(AC)只对列地址自动加一,当列地址=0x7F时会重新设为0DDRAM的坐标地址与资料排列顺序如下图:本实验所用12864液晶显示器4. 系统程序设计4.1 主程序流程图系统主程序流程图如图4-1所示。图4-1 主程序流程图5. 系统调试5.1 Proteus软件仿真调试(1) 调试过程启动计算机,打开Proteus仿真软件,进入仿真环境。将写好的程序存入单片机中,点击运行。即可观察程序运行情况,也可以通过暂停键暂停程序,通过结束键随时结束程序。 (2) 调试时遇到的问题及解决方法 1

11、)在第一次调试时,我忘记了给ADC0809的CLK引脚提供时钟信号,结果ADC输出的值都是0,然后我找到ADC0809的时序图进行分析,最终,我发现了我所忽视的问题,然后在proteus的元件库中找到了一个信号发生器用来给ADC0809提供时钟信号。ADC0809输出正常。 2)在第一次调试时,我们的液晶屏显示全部是黑屏,经过仔细排查,最终确定是元件电路图出现的问题,最终我将液晶的数据口的标号去掉,用导线一根一根的与单片机的I/O口相连,才使液晶屏显示正常。原来是我的标号使用错误导致的液晶屏显示不正常。 3)在ADC0809采集正常、12864液晶显示正常以后,我们发现ADC0809采集的数据

12、不正常,会出现大幅度波动,并且显示的测得电压有时候不正确。这是因为ADC0809是逐次比较型AD,所以它的精度是不准确的,一般情况下逐次比较型AD是不能用作仪表用AD的,仪表级运放一般都是运用双积分型AD。但是因为硬件外设的限制,我们只能用ADC0809。因此,我们在算法上进行了优化,采用连续取样三次取平均的平均值算法。在我们采用了平均值算法以后,ADC的采样值稳定了许多也准确了许多。(3) 调试运行结果 档位4档位3 档位2档位15.2 硬件调试(1) 调试过程 安装好仿真器,用串行数据通信线连接计算机与仿真器,把仿真头插到模块的单片机插座中,打开模块电源,插上仿真器电源插头。将写好的.C文

13、件通过Keil软件生成.hex文件。打开STC-ISP软件,打开程序文件,改变和电脑相适应的COM口,点击下载,将hex文件考入单片机中。观察测试结果。(2) 调试时遇到的问题及解决方法 1)在我们连接好硬件线路开始硬件仿真时,发现液晶屏没有显示,于是开始排查软件问题,结果调试了很久还是没有显示,这时才怀疑是硬件问题,我们将实验箱提供的12864的例程烧写进去,结果还是没有显示。我们才知道原来是液晶坏了,于是我们换了一个实验箱,液晶才显示正常。 2)这个实验箱的P0口没有接上拉电阻,所以不能当做通用I/O使用,于是我们自行焊接了一个上拉电阻,接在了P0口上。在我们连接好硬件线路开始硬件仿真后,

14、我们的ADC输出全为0,于是我编写了一个用P0口驱动LED灯的小程序来测试经过我们上拉以后的P0口的推动能力,我们用电压表测量了P0口的输出,发现P0口输出的低电平正常,为0.07V,而P0口的高电平只能上拉到0.5V。所以我们怀疑由于P0口的其他连线,将P0口的输出拉低了,所以我们放弃了P0口,将P3口进行分时复用,既作为ADC0809的数据输入口,又作为12864液晶屏的数据口。最终我们的液晶屏的显示和ADC0809的采集全部正常,完美地完成了所有功能。6. 程序清单#include #include ascii.h#define uchar unsigned char#define ui

15、nt unsigned int#define NULL 0#define LCD_DATA P3sbit RS = P22;sbit RW = P21;sbit LCD_EN = P20;sbit LCD_CS1 = P25;sbit LCD_CS2 = P24;sbit CLK = P14;sbit ST = P15;sbit OE = P16;sbit EOC = P10;sbit SW1 = P26;sbit SW2 = P27;void delay(unsigned char time) /延时 unsigned char i,j; for(i = 0;i time;i+) for(j

16、 = 0;j 110;j+); void init()/ 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;uint adin0() uint value; OE = 1; ST = 1; P1& = 0xf1; P1| = 0x06; delay(1); ST = 0; delay(1); ST = 1; while(!EOC);

17、 delay(1); OE = 0; delay(1); P0 = 0xff; Value = P0; OE=1; return value;uint adin1() uint value; 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; return value;uchar SW() uchar flag = 0; if(SW1

18、= 0) if(SW2 = 0) Flag = 1; else Flag = 2; if(SW1 = 1) if(SW2 = 0) Flag = 3; else Flag = 4; return flag;unsigned char LCD_CheckBusy(void);void lcd_delay(void) unsigned char i = 10; while(i -);void LCD_WriteData(unsigned char dat) /while(LCD_CheckBusy(); LCD_DATA = dat; RW = 0; RS = 1; LCD_EN = 0; LCD

19、_EN = 1; /lcd_delay(); LCD_EN = 0; RW = 1; RS = 1;unsigned char LCD_ReadData(void) unsigned char dat; /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; return LCD_DATA;void LCD_WriteCommand(unsigned char cmd_code) while(LCD_C

20、heckBusy(); 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;void KS0108_ChipSelect(unsigned char part) if(part = 1) LCD_CS1 = 0; LCD_CS2 = 1; else LCD_CS1 = 1; LCD_CS2 = 0; unsigned char LCD_CheckBusy(void) unsigned char status; LCD_D

21、ATA = 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) return 1; else return 0; void LCD_Init(void) KS0108_ChipSelect(1); LCD_WriteCommand(0x3f); KS0108_ChipSelect(2); LCD_WriteCommand(0x3f); LCD_Writ

22、eCommand(0xc0 | 0) ;/起始行为0 LCD_WriteCommand(0xB8 | 0) ;/起始页为0 void LCD_SetCol(unsigned char col) LCD_WriteCommand(0x40 | col);void LCD_SetPage(unsigned char page) LCD_WriteCommand(0xb8 | page);void LCD_DisplayChar(char c,unsigned char row,unsigned char col) unsigned short i; unsigned char temp; LCD_

23、SetPage(row); LCD_SetCol(col); for(i=0;i8;i+) temp=ascii_tableci; LCD_WriteData(ascii_tableci); void LCD_ClearAll(void) unsigned char page,col; KS0108_ChipSelect(1); for(page=0;page8;page+) LCD_SetPage(page); LCD_SetCol(0); for(col=0;col64;col+) /LCD_SetCol(col); LCD_WriteData(0x00); KS0108_ChipSele

24、ct(2); for(page=0;page8;page+) LCD_SetPage(page); LCD_SetCol(0); for(col=0;col=64) return; if(col_end=64) col_end=63; LCD_SetPage(row); LCD_SetCol(col_start); for(i=col_start;i64-8) col=0; row+; if(row=8) return; s+; void NumtoString(uint in0,uint in1,uchar flag,char *buf,char *buf2,char *buf3) uint

25、 dec=0; uint num1=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(in1in0) *buf+=+; dec=(in1-in0)*625/32; num4=dec/1000; num3=dec%1000/100; num2=dec%100/10; num1=

26、dec%10; if(num40&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+=.; *

27、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(in0in1) *buf+=-; dec=(in0-in1)*625/32; num4=dec/1000; num3=dec%1000/100; num2=dec%100/10; num1=dec%10; if(num40&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