51单片机实现简易数字电压表(液晶显示)仿真图+程序
51单片机简单数字电压表
毕业论文声明本人郑重声明:1.此毕业论文是本人在指导教师指导下独立进行研究取得的成果。
除了特别加以标注地方外,本文不包含他人或其它机构已经发表或撰写过的研究成果。
对本文研究做出重要贡献的个人与集体均已在文中作了明确标明。
本人完全意识到本声明的法律结果由本人承担。
2.本人完全了解学校、学院有关保留、使用学位论文的规定,同意学校与学院保留并向国家有关部门或机构送交此论文的复印件和电子版,允许此文被查阅和借阅。
本人授权大学学院可以将此文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本文。
3.若在大学学院毕业论文审查小组复审中,发现本文有抄袭,一切后果均由本人承担,与毕业论文指导老师无关。
4.本人所呈交的毕业论文,是在指导老师的指导下独立进行研究所取得的成果。
论文中凡引用他人已经发布或未发表的成果、数据、观点等,均已明确注明出处。
论文中已经注明引用的内容外,不包含任何其他个人或集体已经发表或撰写过的研究成果。
对本文的研究成果做出重要贡献的个人和集体,均已在论文中已明确的方式标明。
学位论文作者(签名):年月关于毕业论文使用授权的声明本人在指导老师的指导下所完成的论文及相关的资料(包括图纸、实验记录、原始数据、实物照片、图片、录音带、设计手稿等),知识产权归属华北电力大学。
本人完全了解大学有关保存,使用毕业论文的规定。
同意学校保存或向国家有关部门或机构送交论文的纸质版或电子版,允许论文被查阅或借阅。
本人授权大学可以将本毕业论文的全部或部分内容编入有关数据库进行检索,可以采用任何复制手段保存或编汇本毕业论文。
如果发表相关成果,一定征得指导教师同意,且第一署名单位为大学。
本人毕业后使用毕业论文或与该论文直接相关的学术论文或成果时,第一署名单位仍然为大学。
本人完全了解大学关于收集、保存、使用学位论文的规定,同意如下各项内容:按照学校要求提交学位论文的印刷本和电子版本;学校有权保存学位论文的印刷本和电子版,并采用影印、缩印、扫描、数字化或其它手段保存或汇编本学位论文;学校有权提供目录检索以及提供本学位论文全文或者部分的阅览服务;学校有权按有关规定向国家有关部门或者机构送交论文的复印件和电子版,允许论文被查阅和借阅。
《单片机》教学课件数字电压表例程(C51)
读0809数据
delaynms(2); qianwei=0;
baiwei=1;
P1=table[bai]; delaynms(2); shiwei=1;
baiwei=0;
输出位码 输出段吗
P1=table[shi];
delaynms(2); sable[ge];
delaynms(2); gewei=0;
数字电压表例程
1
程序内容
一 二 三 四
初始化 0809转换 数据处理 七段动态显示
2
0809与单片机接口电路
3
源程序
#include <reg51.h>
#include <absacc.h> #include <intrins.h> #define uchar unsigned char
定义表数据 带小数点/不
while(j--) {for(i=0;i<250;i++) {_nop_(); _nop_(); _nop_(); _nop_(); } }
}
5
/**********显示函数************/
void display(uchar x)
{ unsigned int temp;
uchar ge,shi,bai,qian;
temp=x*196;
//提取电压千位百位十位个位
qian=temp/10000;
bai=temp%10000/1000; shi=temp%10000%1000/100; ge=temp/100%10;
利用除法 提取千百十
基于8051单片机的简易数字电压表设计
基于8051单片机的简易数字电压表设计姓名:吴建亮班级:电信1202 学号:201203090224摘要电压表应用十分广泛,但大部分是模拟电压表,而由于其特性,反应速度慢,读数麻烦并且误差较大,所以为适应不断快速发展的高速信号领域,已经广泛使用数字电压表。
本实验设计是基于51单片机开发板ESDM-3A实现的一种数字电压表系统。
该设计采用8051单片机作为控制核心,以ADC0为模数转换数据采样,实现被测电压的数据采样,外部采用LCD12864液晶显示电压表的电压值。
1.设计任务和要求1.1 设计任务设计制作一个简易直流电压表,该直流电压表能测量直流电压。
各硬件模块如图1.1所示。
输入电压AD转换器8051单片机LCD12864图1.1硬件框图1.2 设计要求(1)ADC0的工作方式设置如下:采用单端输入,模拟输入电压从P2.0输入;选择DDV作为参考电压源;转换时钟频率设置为2MHz;采用写“AD0BUSY”启动A/D转换。
(2)采用定时器中断每隔0.5s启动一次A/D转换;通过ADC0中断服务程序读取转换值。
2.设计方案2.1 硬件电路硬件模块如上图1.1所示。
输入电压由开发板上J8接口的第2脚0~5.0V接跳线至单片机扩展接口J7的第4脚P2.0,调节电位器RP3实现不同电压的输入。
AD转换器、单片机、液晶屏在开发板已经连接好。
下面简单介绍所用的器件。
C8051F360单片机主要模拟和数字资源包括:(1)高速8051微控制器内核。
(2)10位逐次逼近型A/D转换器。
(3)10位电流输出D/A转换器。
(4)两个模拟电压比较器CP1和CP0。
(5)片内锁相环PLL。
(6)扩充中断处理系统。
(7)存储器,256字节内部RAM;1024字节XRAML;32字节闪存存储器。
(8)数字资源,多达39个I/O引脚,全部为三态双向口,允许与5V系统接口。
(9)时钟源,2个内部振荡器;80kHz低频低功耗振荡器。
基于AT89C51单片机的数字电压表的Proteus仿真设计与应用
基于AT89C51单片机的数字电压表的Proteus仿真设计与应用一、本文概述本文旨在深入探讨基于AT89C51单片机的数字电压表的Proteus 仿真设计与应用。
我们将从AT89C51单片机的特点出发,分析其在数字电压表设计中的优势,并详细阐述如何利用Proteus仿真软件进行电路设计与仿真的全过程。
通过本文的阐述,读者将能够对基于AT89C51单片机的数字电压表的设计原理、电路构建、仿真测试等方面有全面的了解,并能在实践中应用所学知识,实现数字电压表的开发与优化。
本文将首先介绍AT89C51单片机的基本特性,包括其内部结构、功能特点以及适用场景。
接着,我们将详细解析数字电压表的设计原理,包括电压信号的采集、处理与转换等关键步骤。
在此基础上,我们将深入探讨如何利用Proteus仿真软件进行电路设计与仿真,包括电路元件的选择、电路连接、仿真参数设置等具体操作。
通过Proteus仿真软件的应用,我们能够在虚拟环境中对数字电压表进行仿真测试,从而验证电路设计的正确性,预测实际运行效果,优化电路设计。
Proteus仿真软件还具有操作简便、可视化程度高、仿真速度快等优点,使得电路设计与调试过程更加高效便捷。
本文将总结基于AT89C51单片机的数字电压表的Proteus仿真设计与应用过程中的经验教训,为读者在实际开发中提供参考与借鉴。
通过本文的学习与实践,读者将能够掌握数字电压表的设计与开发技能,为未来的电子工程设计与实践奠定坚实的基础。
二、AT89C51单片机概述AT89C51是Atmel公司生产的一款8位低功耗、高性能的CMOS微控制器,它属于AT89系列单片机。
AT89C51单片机内部集成了4KB 的可反复擦写的Flash只读程序存储器,这使得它具备了程序存储空间的持久性和可修改性,大大简化了程序的更新和维护过程。
它还拥有128字节的内部RAM,用于程序执行过程中的数据存储和临时变量存储。
AT89C51单片机采用了32个可编程的I/O口线,满足了大多数基本外设的接口需求。
基于51单片机的数字电压表仿真设计(有参考文献)
基于51单片机的数字电压表仿真设计一、引言随着电子科学技术的发展,电子测量成为广大电子工作者必须掌握的手段,对测量的精度和功能的要求也越来越高,而电压的测量甚为突出,因为电压的测量最为普遍。
数字电压表是采用数字化测量技术设计的电压表。
数字电压表与模拟电压表相比,具有读数直观、准确、显示范围宽、分辨力高、输入阻抗大、集成度高、功耗小、抗干扰能力强,可扩展能力强等特点,因此在电压测量、电压校准中有着广泛的应用。
而单片机也越来越广泛的应用与家用电器领域、办公自动化领域、商业营销领域、工业自动化领域、智能仪表与集成智能传感器传统的控制电路、汽车电子与航空航天电子系统。
单片机是现代计算机技术、电子技术的新兴领域。
本文采用ADC0808对输入模拟信号进行转换,控制核心C51单片机对转换的结果进行运算和处理,最后驱动输出装置显示数字电压信号,通过Proteus仿真软件实现接口电路设计,并进行实时仿真。
Proteus软件是一种电路分析和实物模拟仿真软件。
它运行于Windows 操作系统上,可以进行仿真、分析(SPICE)各种模拟器件和集成电路,是集单片机和SPICE分析于一身的仿真软件,功能强大,具有系统资源丰富、硬件投入少、形象直观等优点,近年来受到广大用户的青睐。
二、数字电压表概述1、数字电压表的发展与应用电压表指固定安装在电力、电信、电子设备面板上使用的仪表,用来测量交、直流电路中的电压。
传统的指针式电压表功能单一、精度低,不能满足数字化时代的需求,并且传统的电压表在测量电压时需要手动切换量程,不仅不方便,而且要求不能超过该量程。
目前,由各种单片A/D转换器构成的数字电压表,已被广泛用于电子及电工测量领域,并且由DVM扩展而成的各种通用及专用数字仪器仪表,也把电量及非电量测量技术提高到崭新水平。
2、本次设计数字电压表的组成部分本设计是由单片机AT89C51作为整个系统控制的核心,整个系统由衰减输入电路、量程自动转换电路、交直流转换电路、模数转换及控制电路以及接口电路五大部分构成。
单片机简易电子表方案与仿真
智能仪器及应用实验报告项目名称:基于51单片机的简易电子表设计与仿真专业名称:测控技术与仪器班级:测控0901班学生姓名:指导教师:一、任务要求使用Keil uVision编程软件以及ISIS 7 Professional仿真软件制作一个简易电子表,要求具备电子表基本功能<时间显示、时间调整等)。
二、总体设计方案利用AT89C51作为控制以及1602LCD作为显示,通过6个按键实现出入时间设置状态、出入闹铃设置状态、小时位调整、分钟位调整、开关闹铃等功能。
系统的流程图如下:图1-1 系统仿真流程图三、系统硬件1、AT89C51引脚功能说明:AT89C51芯片如图1-2所示图1-2AT89C51VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏极开路双向I/O口,每脚可吸收8TTL门电流。
当P1口的管脚第一次写1时,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。
P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是因为内部上拉的缘故。
在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。
并因此作为输入时,P2口的管脚被外部拉低,将输出电流。
这是因为内部上拉的缘故。
P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。
在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。
P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
51单片机实现简易数字电压表(液晶显示)仿真图+程序
#define uchar unsigned char
#define uint unsigned int
#defin2;
sbit EOC= P0^3;
sbit OE= P0^4;
sbit CLK= P0^1;
uchar c[6];
LCD_w_com(0x01);//清屏显示
delay(200);
}
//==========光标定位=======================
void gotoxy(uchar x,uchar y) // x表示行,y表示列
{uchar address;
if(x==1)
address=0x80+y;
return result;//返回侧忙结果
}
//==================写指令函数=================
void LCD_w_com(uchar com)
{
while(lcd_bz());
LCD_DB=com;
LCD_RS=0;//指令
LCD_RW=0;//写入
LCD_E=1;
#define uint unsigned int
void main()
{
uchar i;
ADC_init();
LCD_init();
while(1)
{
i=ADC_change();
sepr(i);
disp();
}
}
void clock(void) interrupt 1
{
CLK=~CLK;
}
/***********************0809模数转换(ADC0809.c)***************************/
基于51单片机的ADC0832数字电压表(仿真+程序)
仿真图:#in elude <reg52.h>#in elude vintrin s.h>sbit CS = P3A 5;sbit Clk =卩3人3;sbit DATI = P3A4;sbit DATO = P3A4;sbit P20=P2A0 ;un sig ned char dat = 0x00;un sig ned char count = 0x00;/******************************* ^定义全局变^量 ******************************/** 斗 XT C £J_1XTW2 R^T Pd KI W KUW?PQ pa.&^oo KMW POTrorip?rw P2/WPG£H芒酒r P2.4m;fcA. 旳腳威*2 ma5 P3.IM 沁Pi 1 pg.vwt F3.Z/IOOFts PH M.:州和 P2-4TD P1 6 P16 •"■S.aUtfk P3 &■ 14■和PV1******************************* 包含头文^件 ******************************/********************************* ^端■口定^义 ********************************//AD 值 //定时器计数U2xinjjbn■TBMK ■ & EK ■曲 ■詡 'RP1■ 12 4 'unsigned char CH; // 通道变量unsigned char dis[] = {0x00, 0x00, 0x00}; // 显示数值/*************************共阳 LED 段码表unsigned char codetab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};char code tablewe[]={ 0xfd,0xfb,0xf7,0xef,0xdf,0xfe };/*************************************************************************** * 函数功能 :AD 转换子程序入口参数 :CH 出口参数 :dat**************************************************************************unsigned char adc0832(unsigned char CH) {unsigned char i,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;elseadval |= 0x00;}for (i = 0; i < 8; i++) // 读取后 8 位的值{test >>= 1;if (DATO)test |= 0x80;elsetest |= 0x00;_nop_();Clk = 1;_nop_();Clk = 0;}if (adval == test) // 比较前 8 位与后 8 位的值,如果不相同舍去。
单片机数字电压表(带仿真图C程序)
基于51单片机数字电压表本模块采用ADC0832模数转换芯片,LCD1602液晶显示,测量范围0-5V,精度误差0.01V看了很多网上的课程设计或者毕业论文,得出以下几点:1.数字电压表的方案有很多种,有的采用ADC0809,或者ADC0808等,他们都是8温AD,并口传输数据,具有速率高的优点。
但是硬件复杂,与单片机电路繁琐,焊接起来比较麻烦。
所以本设计采用ADC0832,同样8位AD,特点是串口传输数据,硬件接口简单,且精度误差一致,速率也比较快,对于要求不高的系统非常适合。
2.显示电路,网上采用LED显示居多,本设计采用LCD1602液晶显示,具有硬件搭设简单,显示美观等优点3.本设计方便移植,只需将LCD1602三个控制端口,ADC0832 四个控制端口修改即可。
注意LCD1602数据传输接口是单片机的P0口,如下图,需要接上拉电阻4.程序采用C代码编写,亲测直接可以使用,若需仿真文件,请用E-mail联系邮系。
邮箱:gnsywb@5.网上很多设计数据转换程序有误,不够正确。
在转换过程中,中间变量需设置为int 类型,虽然8位AD输出最高位255,但是余数转换过程中会大于255。
若设计char型,会造成显示输出有误。
void convert(uchar a){ uint temp; //特别注意这里需定义int型(余数将大于255)dis[0]=a/51; //取个位temp=a%51;temp=temp*10; dis[1]=temp/51; //取小数点后第一位temp=temp%51;temp=temp*10; dis[2]=temp/51; //取小数点后第二位}具体电路图如下:1.利用电压表与测量显示电压对比附录:C程序/******************************************** 功能:单片机数字电压表ADC0832+LCD16021,测量范围0-5V2,2路输入电压,可自行设定3,测量精度误差0.01V,LCD液晶显示编写者:小子在西藏gnsywb@编写日期:2012-11-5*********************************************/ #include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit lcdrs=P2^4;sbit lcdrw=P2^5;sbit lcden=P2^6; //1602控制端口sbit DI=P3^4;sbit DO=P3^4; //DI和DO与单片机共接口sbit Clk=P3^3;sbit CS=P3^5;//ADC0832控制端口uchar dis[3]={0x00,0x00,0x00}; //显示缓冲区uchar date=0; //AD值uchar CH; //ADC0832通道值/*****************************************AD0832转换程序******************************************/uchar ADC0832(uchar CH){uchar i,dis0,dis1;Clk=0; //拉低时钟DI=1; //初始化_nop_();CS=0; //芯片选定_nop_();Clk=1; //拉高时钟_nop_();if(CH==0) //通道选择{Clk=0; //第一次拉低时钟DI=1; //通道0的第一位_nop_();Clk=1; //拉高时钟_nop_();Clk=0; //第二次拉低时钟,ADC0832 DI接受数据DI=0; //通道0的第二位_nop_();Clk=1;_nop_();}else{Clk=0;DI=1; //通道1的第一位_nop_();Clk=1;_nop_();Clk=0;DI=1; //通道1的第二位_nop_();Clk=1;_nop_();}Clk=0; //第三次拉低时钟,此前DI两次赋值决定通道DI=1; //DI开始失效,拉高电平,便于DO数据传输for(i= 0;i<8;i++) //读取前8位的值{_nop_();dis0<<= 1;Clk=1;_nop_();Clk=0;if (DO)dis0|=0x01;elsedis0|=0x00;}for (i=0;i<8;i++) //读取后8位的值{dis1>>= 1;if (DO)dis1|= 0x80;elsedis1|= 0x00;_nop_();Clk=1;_nop_();Clk=0;}if(dis0==dis1) //两次结束数据比较,若相等date=dis0; //则赋值给dat_nop_();CS=1; //释放ADC0832DO=1; //拉高输出端,方便下次通道选择DI端有效Clk=1; //拉高时钟return date;}/***********************************************数据转换程序功能:将0-255级换算成0.00-5.00的电压数***********************************************/void convert(uchar a){uint temp; //特别注意这里需定义int型(余数将大于255)dis[0]=a/51; //取个位temp=a%51;temp=temp*10;dis[1]=temp/51; //取小数点后第一位temp=temp%51;temp=temp*10;dis[2]=temp/51; //取小数点后第二位}/***************************************** LCD1602驱动程序******************************************/ void delay(uchar z){uint x,y;for(x=z;x>0;x--)for(y=122;y>0;y--);}void write_cmd(uchar cmd)//lcd1602写命令函数{lcdrs=0;lcdrw=0; //选择指令寄存器lcden=1;P0=cmd; //写数据delay(5);lcden=0; //使能拉低lcden=1;}void write_date(uchar date)//lcd1602写数据函数{lcdrs=1;lcdrw=0; //选择数据寄存器lcden=1;P0=date; //写数据delay(5);lcden=0; //使能拉低lcden=1;}void init_lcd1602()//lcd1602初始化{write_cmd(0x01); //清屏write_cmd(0x38); //功能设置write_cmd(0x0c); //显示设置write_cmd(0x06); //输入方式从左到右delay(1);}/***************************************** 显示函数*****************************************/ void display(void){uchar i;write_cmd(0x80);for(i=0;i<3;i++){if(i==1) write_date('.'); //第二位显示小数点write_date (0x30+dis[i]);delay(5);}write_date('V'); //最后一位后显示字符'V'}/************************************************ 主函数***************************************************/ void main(void){CH=0; //选择通道0或1init_lcd1602();//液晶1602显示初始化while(1) //主循环{date=ADC0832(CH);//启动ADC0832转换并接受数据delay(1);convert(date); //数据转换成BCD码display(); //显示数值}}。
基于51单片机的数字电压表的设计与仿真
电压 信号 .系统 结 构框 图如 图 1所示 .
收 稿 日期 : 0 1— 8—1 21 0 0
相 连 ,当执行 写 片外 数据存 储 器 的指令 时 就可 以启
基 金 项 目 :安 徽 省 高 等 学 校 教 学 质 量 与 教 学 改 革 工 程 重 点 项 目 (0 0 3 6 2 1 15 )
对 P . 时取 反 输 出 5 0k z的 C K信号 ,作 为 2 7定 0 H L A C 89所 需 的 时 钟 信 号 .程 序 流 程 图 如 图 3所 D 00
刁 .
3 2 接 口程 序 .
主程序流程 图
图 3 电压 表 程 序 流 程 图
部分 程 序代码 如 下 MA N: V T D, 0 H; 时 器 工作 在方 式 2 I MO MO # 2 定
LCAL DELAY L S ETB P2. 2
图 2 数 字 电压 表 电路 原 理 图
3 系统 程序 设计
3 1 程序 设计 思路 .
定时 中断程 序流程 图
本 系 统 的程 序 设 计 主 要 包 括 初 始 化 、A D 转 / 换、 E L D显示 和定 时器 中断部 分 .定 时 中断部 分 是
片 机设计 的数 字 电压 表 可 以测 量 0—5 的直 流 电 V
A C 89具有 8路 模 拟量输 入 通道 ,通道 的选 D 00
择 由地址 线 C、 A的值 决定 , 口 A E为 地址 锁 B、 端 L 存 允许 控制 端 口 , 当输 人为 高 电平 时 ,对地 址线 C、 B、A输 人 的 地 址 信 号 进 行 锁 存 ,从 而 决 定 对 哪 路 待 测输 人 电压 值 进 行 A D转 换 .SA T为 转 换 启 / TR 动 信号 , 当输 入 1个 2 宽 的高 电平 脉 冲时 ,开 始 s 进 行 A D转 换.E C为 A D 转 换 结 束 信 号 端 口, / O / 当 A D转 换 结束 时 , 端 口输 出一个 正 脉 冲 , 信 / 该 此
利用51单片机与ADC0809和数码管设计数字电压表
.利用51单片机与ADC0809和数码管设计数字电压表一、课题功能描述:利用单片机AT89C51 芯片与ADC0809 芯片设计一个数字电压表,能够测量0―5V 之间的直流电压,三位数码显示。
二、程序设计本实验采用AT89C51 单片机芯片配合 ADC0809 模/数转换芯片构成一个简易的数字电压表,原理电路如图1-1 所示。
该电路通过 ADC0809 芯片采样输入口AI0 输入的0~5V 的模拟量电压,经过模/数转换后,产生相应的数字量经过其输出通道D0~D7 传送给 AT89C51 芯片的F0口。
AT89C51负责把接收到的数字量经过数据处理,产生正确的7段数码管的显示段码,并通过P1 口传送给数码管。
同时它还通过其三位 I/O 口 P3.0、P3.1、P3.2 产生位片选信号,控制数码管的亮灭。
另外,AT89C51 还控制着 ADC0809 的工作。
其ALE管脚为 ADC0809提供了 1MHZ 工作的时钟脉冲;P2.3 控制 ADC0809 的地址锁存端(ALE); P2.4 控制 ADC0809 的启动端(START); P2.5 控制 ADC0809 的输出允许端(OE); P3.7 控制 ADC0809 的转换结束信号(EOC)。
电路原理图如下:三、器件清单:1 . AT89S51 芯片 1块2 . ADC0809 芯片 1块3 . 74HC245 芯片 1块4 . 数码管 1个资料Word.5 . 6MHZ 晶振 1个6 . 30pF 电容 2个7 . 10uF 电解电容 1个8 . 复位电容 1个9 . 510Ω电阻 8个10. 10KΩ电阻 1个11. 导线若干四、程序设计1、主程序设计由于ADC0809 在进行A/D转换时需要有CKL 信号,而此时的 ADC0809 的CLK 是连接在 AT89C51 单片机的30管脚,也就是要求从30管脚输出CLK 信号供开初始化A/D转化程序调用调用数据处理程序调用显示程序主程序流程图图1-2ADC0809 使用。
基于51单片机的简易数字电压表的方案设计书
班级:智能电网111学生:喻卫湖南铁道职业技术学院电气工程系目录1控制要求2设计目的意义3 系统原理框图4 89C52单片机5 ADC0809 的工作原理6 系统原理图和PCB图7程序流程图8 C语言程序9数字电压表工作原理10设计体会1控制要求利用STC89C52单片机和ADC0809设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码管显示,使用的元器件数目较少。
外界电压模拟量输入到A/D转换部分的输入端,通过ADC0809转换变为数字信号,输送给单片机。
然后由单片机给数码管数字信号,控制其发光,从而显示数字。
2设计目的意义1.通过亲身的设计应用电路,将所用的理论知识应用到实践中,增强实践动手能力,进而促进理论知识的强化。
2.通过数字电压表的设计系统掌握51单片机的应用。
掌握A/D转换的原理及软件编程及硬件设计的方法,掌握根据课题的要求,提出选择设计方案,查找所需元器,设计并搭建硬件电路,编程写入STC89C52单片机并进行调试等。
3 系统原理框图4 89C52引脚资料STC89C52P1 P0P3 P2AD0809D0~D7IN0~IN7VREF+VREF-CLKOEST、ALE四位数码管位选段选控制线数据待测电压系统原理框图89C51引脚图总线型DIP40引脚封装电源引脚(2个)VCC:接+5V电源。
GND:接地端。
外接晶体引脚(2个)XTAL1:外接晶振输入端(采用外部振荡器时,此引脚接地)。
XTAL2:外接晶振输入端(采用外部振荡器时,此引脚作为外部振荡信号输入端)。
并行输入/输出引脚(32个)P0.0~P0.7:通用I/O引脚。
P1.0~P1.7:通用I/O引脚。
P2.0~P2.7:通用I/O引脚或数据低8位地址总线复用引脚。
P3.0~P3.7:通用I/O引脚或第二功能引脚(RXD、TXD、INT0、INT1、T0、T1、WR 、RD)。
控制引脚(4个)RST/VPD:复位信号输入引脚/备用电源输入引脚。
基于51单片机的电压监测+液晶LCD1602显示程序源代码
基于51单片机的电压监测+液晶LCD1602显示程序源代码/*******************电压监测+液晶LCD1602显示程序源代码********************单片机型号:STC15W4K56S4,内部晶振:22.1184M。
功能:电压监测+液晶LCD1602显示功能测试。
操作说明:监测电池电压,并将电池电压值显示在液晶LCD1602上。
**************************************************************************/#include "stc15.h" //包含头文件stc15.h#include <intrins.h> //包含头文件intrins.h#define ADC_POWER 0x80 //将0x80宏定义成ADC_POWER #define ADC_FLAG 0x10 //将0x10宏定义成ADC_FLAG#define ADC_START 0x08 //将0x08宏定义成ADC_START #define ADC_SPEEDLL 0x00 //将0x00宏定义成ADC_SPEEDLL #define ADC_SPEEDL 0x20 //将0x20宏定义成ADC_SPEEDL #define ADC_SPEEDH 0x40 //将0x40宏定义成ADC_SPEEDH #define ADC_SPEEDHH 0x60 //将0x60宏定义成ADC_SPEEDHH#define Busy 0x80 //LCD忙sbit LCD_D0 = P0^0; //LCD_D0对应P0.0sbit LCD_D1 = P0^1; //LCD_D1对应P0.1sbit LCD_D2 = P0^2; //LCD_D2对应P0.2sbit LCD_D3 = P0^3; //LCD_D3对应P0.3sbit LCD_D4 = P0^4; //LCD_D4对应P0.4sbit LCD_D5 = P0^5; //LCD_D5对应P0.5sbit LCD_D6 = P0^6; //LCD_D6对应P0.6sbit LCD_D7 = P0^7; //LCD_D7对应P0.7sbit LCD_RS = P1^0; //LCD_RS对应P1.0sbit LCD_RW = P1^1; //LCD_RW对应P1.1sbit LCD_EN = P3^4; //LCD_EN对应P3.4void delay(unsigned int t); //delay延时函数void delay_us(unsigned int t); //delay_us延时函数void delay_ms(unsigned int t); //delay_ms延时函数void Delay5Ms(void); //5Ms延时函数void GPIO_1602_Configuration(void); //LCD1602液晶IO口初始化void WriteDataLCD(unsigned char WDLCD); //LCD写数据函数void WriteCommandLCD(unsigned char WCLCD,BuysC); //LCD写命令函数unsigned char ReadDataLCD(void); //LCD读数据函数unsigned char ReadStatusLCD(void); //LCD读状态函数void LCDInit(void); //LCD初始化void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData);//LCD显示一个字符void DisplayListChar(unsigned char X,unsigned char Y,unsigned char code *DData); //LCD显示一个字符串void DY_INIT(void); //AD初始化unsigned char GetDYResult(unsigned char ch); //获取AD值unsigned char code welcome[] = {"DY JIANCE"};unsigned char code Voltage[] = {"Voltage: . V"}; //LCD显示内容V:void delay(unsigned int t) //delay延时函数{while(t--);}void delay_us(unsigned int t) //delay_us延时函数{unsigned char i;while(t--){i=3;while(i--) delay(1);}}void delay_ms(unsigned int t) //delay_ms延时函数{while(t--){delay_us(t);}}void Delay5Ms(void) //5ms延时函数{unsigned int TempCyc = 3552;while(TempCyc--);}void DY_INIT(void) //AD初始化{P1ASF = 0x20; //P1.5作为ADADC_RES = 0;ADC_CONTR = ADC_POWER|ADC_SPEEDLL;}unsigned char GetDYResult(unsigned char ch) //获取AD值{ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ch|ADC_START;delay(4);while(!(ADC_CONTR&ADC_FLAG));ADC_CONTR&=~ADC_FLAG;return ADC_RES;}void DY_JianCe(void) //电压监测函数{u8 AD_RESULT;float temp;unsigned int tempA;unsigned char disbuff[4]={0,0,0,0};AD_RESULT = GetDYResult(0x05); //读取电压值temp =((float)AD_RESULT/256)*5*2; //数值转换tempA = temp*1000;disbuff[3]=tempA/10000;disbuff[2]=tempA/1000%10;disbuff[1]=tempA/100%10;disbuff[0]=tempA/10%10;DisplayOneChar(8,1,(0x30+disbuff[3])); //显示电压值delay_ms(10); //延时DisplayOneChar(9,1,(0x30+disbuff[2])); //显示电压值delay_ms(10); //延时DisplayOneChar(11,1,(0x30+disbuff[1])); //显示电压值delay_ms(10); //延时DisplayOneChar(12,1,(0x30+disbuff[0])); //显示电压值delay_ms(10); //延时}void GPIO_1602_Configuration(void) //LCD1602液晶IO口初始化{P0M1 = P3M1&0x00;P0M0 = P3M0&0x00;P1M1 = P3M1&0xfc;P1M0 = P3M0&0xfc;P3M1 = P4M1&0xef;P3M0 = P4M0&0xef;}unsigned char ReadStatusLCD(void) //测试LCD忙碌状态{LCD_D7 = 1; //LCD的D7置1LCD_RS = 0; //LCD管脚RS设置成低电平 LCD_RW = 1; //LCD管脚RW设置成高电平 LCD_EN = 0; //LCD管脚E设置成低电平 LCD_EN = 0; //LCD管脚E设置成低电平 LCD_EN = 1; //LCD管脚E设置成高电平 while(LCD_D7); //检测忙信号return(Busy); //表示当前忙}void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测{if(BuysC) ReadStatusLCD(); //根据需要检测忙LCD_EN = 0; //LCD管脚E设置成低电平 _nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_RS = 0; //LCD管脚RS设置成低电平 LCD_RW = 0; //LCD管脚RW设置成低电平 _nop_(); //空操作,延时_nop_(); //空操作,延时P0 = WCLCD; //将数据送入P0口_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 1; //E置高电平_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 0;//当E由高电平跳变成低电平时,液晶模块开始执行命令}void WriteDataLCD(unsigned char WDLCD) //LCD写数据函数{ReadStatusLCD(); //读取LCD状态LCD_EN = 0; //LCD管脚E设置成低电平 _nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_RS = 1; //LCD管脚RS设置成高电平 LCD_RW = 0; //LCD管脚RW设置成低电平 P0 = WDLCD; //将数据送入P0口_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 1; //E置高电平_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 0;//当E由高电平跳变成低电平时,液晶模块开始执行命令}void LCDInit(void) //LCD初始化{WriteCommandLCD(0x38,0); //三次显示模式设置Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); //显示光标移动设置WriteCommandLCD(0x0C,1); //显示开及光标设置}void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCD(X,0); //这里不检测忙信号,发送地址码WriteDataLCD(DData); //发送数据}void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1 while (DData[ListLength]>=0x20) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}void main(void){GPIO_1602_Configuration(); //LCD1602液晶IO口初始化delay_ms(10); //延时LCDInit(); //LCD1602初始化delay_ms(10); //延时DisplayListChar(3,0,welcome); //LCD1602显示Hello My Friendsdelay_ms(10); //延时DisplayListChar(0,1,Voltage);delay_ms(10); //延时DY_INIT(); //AD初始化delay_ms(10);while(1){DY_JianCe(); //电压监测函数delay_ms(200);}}程序源代码是编译通过的电压监测接口电路图该程序的实际运行效果。
液晶屏显示数字电压表
1 引言数字电压表的基本工作原理是利用A/D转换电路将待测的模拟信号转换成数字信号,通过相应换算后将测试结果以数字形式显示出来的一种电压表。
较之于一般的模拟电压表,数字电压表具有精度高、测量准确、读数直观、使用方便等优点。
电压表的数字化测量,关键在于如何把随时连续变化的模拟量转化成数字量,完成这种转换的电路叫模数转换器]1[(A/D)。
数字电压表的核心部件就是A/D转换器,由于各种不同的A/D转换原理构成了各种不同类型的DVM。
一般说来,A/D 转换的方式可分为两类:积分式和逐次逼近式。
积分式A/D转换器是先用积分器将输入的模拟电压转换成时间或频率,再将其数字化。
根据转化的中间量不同,它又分为U-T(电压-时间)式和U-F(电压-频率)式两种。
逐次逼近式A/D转换器分为比较式和斜坡电压式,根据不同的工作原理,比较式又分为逐次比较式及零平衡式等。
斜坡电压式又分为线性斜坡式和阶梯斜坡式两种。
在高精度数字电压表中,常采用由积分式和比较式相结合起来的复合式A/D转换器。
本设计以AT89C51单片机为核心,以逐次比较型A/D转换器ADC0808、液晶显示器LCD1602为主体,构造了一款简易的数字电压表,能够测量1路0~5V 直流电压,最小分辨率0.02V。
2 仿真软件介绍2.1 仿真软件简介2.1.1 Proteus 6 ProfessionalISIS 6 Professiona软件是它不仅具有其它EDA工具软件的仿真]2[功能,还能仿真单片机及外围器件。
它是目前最好的仿真单片机及外围器件的工具。
虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。
它从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。
是目前将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、A VR、ARM、8086和MSP430等,2010年即将增加Cortex和DSP系列处理器,并持续增加其他系列处理器模型。
单片机课程设计 数字电压表 程序和电路图
功能:电压报警5V直流测量0.02V 误差LCD显示名字程序COM EQU 50H ;指令寄存器DAT EQU 51H ;数据寄存器RS EQU P2.1 ;LCD寄存器选择信号RW EQU P2.2 ;LCD读/写选择信号E EQU P2.3 ;LCD使能信号ORG 0000HLJMP MAIN ;主程序入口地址ORG 000BHLJMP BT0 ;T0中断入口ORG 0030H ;主程序,初始化MAIN:MOV SP,#60HLCALL INTMOV 30H,#30H ;电压整数位MOV 31H,#0A5H ;小数点位MOV 32H,#30H ;小数个位MOV 33H,#30H ;小数十位MOV 34H,#30H ;小数百位MOV 35H,#56H ;字符"V"MOV R7,#30HLCALL STR0 ;显示字符串0LCALL DELAYLCALL STR1 ;显示字符串1LCALL DELAYLCALL N2 ;显示V oltage=0.000V;***********定时器初始化程序***********MOV TMOD,#00H ;定时器T0设为方式0MOV TH0,#00H ;装入定时常数定时100usMOV TL0,#00HSETB TR0 ;启动T0MOV 24H,#08H;装入T0中断次数MOV IE,#82H ;开中断LP:MOV R7,#30H ;显示缓冲区首地址LCALL DISPL YSJMP LP ;循环显示LED1:CLR P3.0RET;********************************************************************;定时器T0中断服务子程序,读取ADC0809第0通道的A/D转换结果并化为显示值* ;********************************************************************BT0:PUSH ACCPUSH PSWMOV PSW,#08HCLR TR0MOV TH0,#00H ;重新装入初值MOV TL0,#00HDEC 24HMOV A,24HJNZ RTN1MOV 24H,#08HLCALL ADCRTN1: SETB TR0POP PSWPOP ACCRETIADC:MOV DPTR,#0F6FFHMOV A,#0 ;选择通道0MOVX @DPTR,A ;启动AD转换MOV A,#40HDJNZ ACC,$MOVX A,@DPTRMOV 22H,AMOV 21H,#0CCHCJNE A,21H,BJ0BJ0:JNC LEDSJMP LL0LL0:SETB P3.0SJMP LLLED:LCALL LED1LL: MOV A,22HMOV B,#05H ;A/D转换结果化为显示值MUL AB ;(AD*5)/256MOV 30H,B ;AD*5的高字节为整数部分MOV B,#0AHMUL AB ;AD*5的低字节为/256的结果,为小数部分MOV 32H,B ;二进制小数换为10进制数MOV B,#0AHMUL ABMOV 33H,BMOV B,#0AHMUL ABMOV 34H,BMOV A,30HMOV DPTR,#TABMOVC A,@A+DPTRMOV 30H,AMOV A,32HMOVC A,@A+DPTRMOV 32H,AMOV A,33HMOVC A,@A+DPTRMOV 33H,AMOV A,34HMOVC A,@A+DPTRMOV 34H,ARETDISPL Y: ;LCD显示子程序MOV COM,#0CAHLCALL PR1MOV DAT,30HLCALL PR2MOV DAT,31HLCALL PR2MOV DAT,32HLCALL PR2MOV DAT,33HLCALL PR2MOV DAT,34HLCALL PR2MOV DAT,35HLCALL PR2RETSTR0:MOV COM,#01HLCALL PR1MOV COM,#06HLCALL PR1MOV COM,#090H ;设置DDRAM地址LCALL PR1 ;调写指令代码子程序MOV DPTR,#TAB4MOV R2,#16MOV R3,#00HWRIN0:MOV A,R3MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R3DJNZ R2,WRIN0MOV COM,#0D0HLCALL PR1MOV DPTR,#TAB5MOV R2,#16MOV R3,#00HWRIN1:MOV A,R3MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R3DJNZ R2,WRIN1MOV R3,#10HZUOYI:MOV COM,#18HLCALL PR0DJNZ R3,ZUOYILCALL DELAY00LCALL DELAY00LCALL DELAY00LCALL DELAY00RETRETSTR1:MOV COM,#01H ;LCD清0命令LCALL PR1 ;调写指令代码子程序MOV COM,#06H ;输入方式命令,光标右移LCALL PR1 ;调写指令代码子程序MOV COM,#40HLCALL PR1MOV R5,#20HMOV DPTR,#ZIMOV R4,#0LOOP1:MOV A,R4MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R4DJNZ R5,LOOP1MOV COM,#80HLCALL PR1MOV DPTR,#TAB2MOV A,#00HMOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV A,#01HMOV DPTR,#TAB2 MOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV A,#02HMOV DPTR,#TAB2 MOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV A,#03HMOV DPTR,#TAB2 MOVC A,@A+DPTR MOV DAT,ALCALL PR2MOV R1,#00HMOV R0,#0dHMOV DPTR,#TAB3 LOOP2:MOV A,R1MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R1DJNZ R0,LOOP2RETN2: MOV COM,#0C0HLCALL PR1MOV DPTR,#TAB1MOV R2,#10MOV R3,#00HWRIN:MOV A,R3MOVC A,@A+DPTRMOV DAT,ALCALL PR2INC R3DJNZ R2,WRINRETTAB: DB "0123456789"TAB1: DB "VOLTAGE = "TAB2: DB 00HDB 01HDB 02HDB 03HDB 04HDB 05HZI: DB 01FH,008H,00EH,00AH,00AH,00AH,012H,000H DB 00EH,00EH,019H,00EH,01DH,00DH,00FH,000H DB 00FH,01EH,00EH,01DH,01DH,00EH,014H,000H;*****************************************;****LCD间接控制方式下的初始化子程序******;*****************************************INT:LCALL DELAYMOV COM,#38H ;设置工作方式LCALL PR1MOV COM,#01HLCALL PR1MOV COM,#06HLCALL PR1MOV COM,#0EHLCALL PR1RETDELAY: ;延时子程序MOV R6,#0FHMOV R7,#00HDELAY1:NOPDJNZ R7,DELAY1DJNZ R6,DELAY1RETDELAY00: ;延时子程序MOV R6,#0FFHMOV R7,#0FFHDELAY0:NOPDJNZ R7,DELAY1DJNZ R6,DELAY1RET;1 读BF和AC值PR0: PUSH ACCMOV P0,#0FFH ; P0置位, 准备读CLR RS ; RS=0SETB RW ; R/W=1SETB E ; E=1LCALL DELAYMOV COM,P0 ; 读BF和AC6-4值CLR E ; E=0POP ACCRET;********************************************* ;*******LCD间接控制方式下的驱动子程序********* ;********************************************* ;2 写指令代码子程序PR1:PUSH ACCCLR RSSETB RWPR11:MOV P0,#0FFHSETB ELCALL DELAYNOPMOV A,P0CLR EJB ACC.7,PR11CLR RWMOV P0,COMSETB ECLR EPOP ACCRET;3 写显示数据子程序PR2:PUSH ACCCLR RSSETB RWPR21:MOV P0,#0FFHSETB ELCALL DELAYMOV A,P0CLR EJB ACC.7,PR21SETB RSCLR RWMOV P0,DATSETB ECLR EPOP ACCRET;4 读显示数据子程序PR3: PUSH ACCCLR RS ; RS=0SETB RW ; R/W=1PR31: MOV P0,#0FFH ; P0置位, 准备读SETB E ; E=1LCALL DELAYMOV A,P0 ; 读BF和AC6-4值CLR E ; E=0JB ACC.7,PR31SETB RS ; E=1SETB RW ; R/W=1MOV P0,#0FFH ; 读数据SETB E ; E=1MOV DA T,P0CLR E ; E=0POP ACCRETEND。
AT89C51单片机电压表制作
1.实验任务利用单片机AT89S51与ADC0809设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示,但要求使用的元器件数目最少。
2.电路原理图图1.28.13.系统板上硬件连线a) 把“单片机系统”区域中的P1.0-P1.7与“动态数码显示”区域中的ABCDEFGH端口用8芯排线连接。
b) 把“单片机系统”区域中的P2.0-P2.7与“动态数码显示”区域中的S1S2S3S4S5S6S 7S8端口用8芯排线连接。
c) 把“单片机系统”区域中的P3.0与“模数转换模块”区域中的ST端子用导线相连接。
d) 把“单片机系统”区域中的P3.1与“模数转换模块”区域中的OE端子用导线相连接。
e) 把“单片机系统”区域中的P3.2与“模数转换模块”区域中的EOC端子用导线相连接。
f) 把“单片机系统”区域中的P3.3与“模数转换模块”区域中的CLK端子用导线相连接。
g) 把“模数转换模块”区域中的A2A1A0端子用导线连接到“电源模块”区域中的GND端子上。
h) 把“模数转换模块”区域中的IN0端子用导线连接到“三路可调电压模块”区域中的VR 1端子上。
i) 把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“模数转换模块”区域中的D0 D1D2D3D4D5D6D7端子上。
4.程序设计内容i. 由于ADC0809在进行A/D转换时需要有CLK信号,而此时的ADC0809的CLK是接在AT89S51单片机的P3.3端口上,也就是要求从P3.3输出CLK信号供ADC0809使用。
因此产生CLK信号的方法就得用软件来产生了。
ii. 由于ADC0809的参考电压VREF=VCC,所以转换之后的数据要经过数据处理,在数码管上显示出电压值。
实际显示的电压值(D/256*VREF)5.汇编源程序(略)6.C语言源程序TH1=(65536-4000)/256;TL1=(65536-4000)%256;P1=dispcode[dispbuf[dispcount]];P2=dispbitcode[dispcount];if(dispcount==7){P1=P1 | 0x80;}dispcount++;if(dispcount==8){dispcount=0;}}基于单片机的数字多用表的设计2011-01-18 21:24:18 来源:仪表技术河南科技学院李国厚杨青杰陈艳锋关键字:单片机数字多用表1DS1629的结构特性与工作原理DS1629是专为温度的数字化测量而设计的一种芯片,同时还兼有实时时钟/日历的功能。
数字电压表程序及仿真图
//************************************************//**用adc0809进行电压测量,lcd1602显示,精度0.001v**//************************************************#include "reg51.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned intuchar code table []="ID: " ; //欢迎显示,包括空格在内<=16 uchar code table1 []="Name: " ;//欢迎显示,包括空格在内<=16//************管脚定义************************sbit ADC_OE = P3^0; //ADC输入允许信号端口sbit ADC_EOC = P3^1; //ADC转换结束信号输出端sbit ADC_START= P3^2; //ADC启动转换信号输入端sbit ADC_CLK = P3^3; //ADC时钟输入端sbit lcd_rs = P3^4; //液晶数据命令选择端sbit lcd_en = P3^5; //液晶使能//************参数定义************************uchar num; //LCD1602开机显示数组数uchar AD_data; //AD转换原始数据uchar dis1[] = " Current Voltage";uchar dis2[] = {' ',' ',' ',' ','V','=','0','.','0','0','0','v',' ',' ',' ',' ',}; //初始化数组,用来保存电压显示//************子函数定义************************void delay(uchar z); //delay延时子程序void init_lcd(); //LCD1602初始化函数void InitTimer0(); //定时器0初始化函数void write_com(uchar com); //LCD1602写指令函数void write_data(uchar date); //LCD1602写数据函数void write_welcome(); //LCD1602开启显示欢迎函数void init_ADC(); //ADC初始化函数void AD_covert(); //AD转换子程序void ADC_change(); //ADC转换函数void write_adc(); //ADC显示函数//************主函数************************void main(){init_lcd(); //LCD1602初始化write_welcome(); //LCD1602开启显示欢迎InitTimer0(); //定时器0初始化init_lcd(); //LCD1602初始化init_ADC(); //ADC初始化while(1){AD_covert(); //AD转换ADC_change(); //ADC转换函数write_adc(); //ADC显示}}//************delay延时子程序************************void delay(uchar z){uchar x,y;for(x=0;x<z;x++)for(y=0;y<114;y++);}//************LCD1602初始化函数************************void init_lcd(){lcd_en = 0; // 将使能端置0write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口write_com(0x08); //写一个字符后地址指针加1write_com(0x01); //显示清零,数据指针清零write_com(0x06); //写一个字符后地址指针加1write_com(0x0c); //关显示,光标不显示不闪烁}//************定时器0初始化函数************************void InitTimer0(){TMOD = 0x02; //定时器0工作方式2TH0 = 0x14; //初值位20TL0 = 0x14;EA = 1; //开总中断ET0 = 1; //允许T0中断TR0 = 1; //启动T0}//************LCD1602写指令函数************************void write_com(uchar com){lcd_rs = 0; // 选择写指令P2 = com; // 将要写的命令送到数据总线上delay(5); // 延时5ms,待数据稳定lcd_en = 1; // 由于初始化已将lcd_en置为0,使能端给一个高脉冲,delay(5); // 延时5ms,待数据稳定lcd_en = 0; // 将使能端置0以完成脉冲}//************LCD1602写数据函数************************void write_data(uchar date){lcd_rs = 1; // 选择写数据P2 = date; // 将要写的数据送到数据总线上delay(5); // 延时5ms,待数据稳定lcd_en = 1; // 由于初始化已将lcd_en置为0,使能端给一个高脉冲,delay(5); // 延时5ms,待数据稳定lcd_en = 0; // 将使能端置0以完成脉冲}//************LCD1602开启显示欢迎函数******************void write_welcome(){write_com(0x80); // 现将数据指针定位到第一行第一个字处for(num=0;num<16;num++) //做简短延时{write_data(table[num]);delay(5);}write_com(0x80+0x40); // 现将数据指针定位到第二行第一个字处for(num=0;num<16;num++) //做简短延时{write_data(table1[num]);delay(20);}delay(50000);}//************中断函数************************void Timer0()interrupt 1{ADC_CLK = ~ADC_CLK; //时钟不断取反}//***********ADC初始化函数************************void init_ADC(){ADC_OE = 0; //ADC输入允许信号端口置1ADC_EOC = 1; //ADC转换结束信号输出端置1ADC_START= 1; //ADC启动转换信号输入端置1ADC_CLK = 1; //ADC时钟输入端置1}//***********AD转换子程序***********************void AD_covert(){ADC_START= 0;ADC_CLK = 0;_nop_(); //延时空循环,一个机器指令的时间ADC_START= 1;ADC_CLK = 1;_nop_(); //延时空循环,一个机器指令的时间ADC_START= 0;ADC_CLK = 0; //在START上产生一个正脉冲while(ADC_EOC); //等待上次转换完成_nop_();delay(100);while(ADC_EOC == 0){ADC_CLK = 1;delay(1);ADC_CLK = 0;delay(1);}P1 = 0xff;_nop_();ADC_OE = 1;_nop_();AD_data = P1;ADC_OE = 0;}//***********ADC转换函数************************void ADC_change(){double v;uchar val_integer;uint val_decimal;v = AD_data*0.0196078; //5v时输出的数字量是2.55,为使5v时输出5.00 val_integer = (uchar)v; //电压整数部分val_decimal = (uint)((v-val_integer)*1000);//将电压小数点后三位转换为整数(dis2[6]) = val_integer+0x30; //电压整数转换为ASSII(dis2[8]) = val_decimal/100+0x30; //电压小数第一位转换为ASSII(dis2[9]) = val_decimal/10%10+0x30; //电压小数第二位转换为ASSII(dis2[10]) = val_decimal/10%10+0x30; //电压小数第三位转换为ASSII}//************LCD1602显示adc函数******************void write_adc(){write_com(0x80); // 现将数据指针定位到第一行第一个字处for(num=0;num<16;num++)//做简短延时{write_data(dis1[num]);delay(1);}write_com(0x80+0x40); // 现将数据指针定位到第二行第一个字处for(num=0;num<16;num++)//做简短延时{write_data(dis2[num]);delay(1);}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{uchar address;
if(x==1)
address=0x80+y;
else
address=0xc0+y;
LCD_w_com(address);
}
//=========显示一个字符串==================
液晶显示,89C51实现简易电压表
用keil C51软件编译,主函数中包含了两个c文件,即lcd.c、ADC0809.c
0809的仿真芯片用的是ADC0808进行代替。注意高低位的接法
程序如下:
/**************************************主函数*******************************/
void delay(uint x)
{uint i,j;
for(i=x;i>0;i--)
for(j=0;j<2;j++);
}
/****************侧忙函数************************/
unsigned lcd_bz()
{
unsigned result;
LCD_RS = 0;
#include <reg51.h>
#include <lcd.c>
#include <ADC0809.c>
#define uchar unsigned char
#define uint unsigned int
void main()
{
uchar i;
ADC_init();
LCD_init();
while(1)
#define uchar unsigned char
#define uint unsigned int
#define LCD_DB P2//定义LCD的数据端口
sbit LCD_RS=P0^5;
sbit LCD_RW=P0^6;
sbit LCD_E =P0^7;
//===========延时子函数========================
#define uchar unsigned char
#define uint unsigned int
#define ADC_DB P1
sbit ST= P0^2;
sbit EOC= P0^3;
sbit OE= P0^4;
sbit CLK= P0^1;
uchar c[6];
void sepr(uchar i);
gotoxy(2,5);
LCD_display(c);
}
void sepr(uchar i)
{
uint ch;ቤተ መጻሕፍቲ ባይዱ
ch=i;
c[0]='0'+ch/51;
c[1]='.';
c[2]='0'+(ch%51)*10/51;
c[3]='0'+((ch%51)*10%51)*10/51;
c[4]='V';
c[5]='\0';
void disp();
voidADC_init();
ucharADC_change();
ucharADC_change()
{
ST=0;
ST=1;
ST=0;
while(EOC==0);
ADC_DB=0xff;
OE=1;
return(ADC_DB);
}
void disp()
{
gotoxy(1,1);
LCD_display("The Output is:");
}
voidADC_init()
{
TMOD=0x02;
TH0=10;
TL0=10;
EA=1;
ET0=1;
TR0=1;
}
/***********************************液晶(lcd.c)****************************/
#include<reg51.h>
#include <INTRINS.H>//库函数头文件,代码中引用了_nop_()函数
void LCD_display(uchar *dat)
{
while(*dat!='\0')
{LCD_w_data(*dat);
dat++;
}
}
{LCD_w_com(0x38);//设置8位格式,2行,5*7
LCD_w_com(0x0c);//整体显示,关光标,不闪烁
LCD_w_com(0x06);//设定输入方式,增量不移位
LCD_w_com(0x01);//清屏显示
delay(200);
}
//==========光标定位=======================
void LCD_w_data(uchar dat)
{LCD_DB=dat;
LCD_RS=1;//数据寄存器
LCD_RW=0;//写入数据
LCD_E=1;
LCD_E=0;
delay(1);//等待程序执行完毕。。。
}
//===========初始化函数=============
void LCD_init(void)
LCD_RW = 1;
LCD_E = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (unsigned)(LCD_DB & 0x80);//检测P2最高位是否为1
LCD_E = 0;
return result;//返回侧忙结果
}
//==================写指令函数=================
{
i=ADC_change();
sepr(i);
disp();
}
}
void clock(void) interrupt 1
{
CLK=~CLK;
}
/***********************0809模数转换(ADC0809.c)***************************/
#include <reg51.h>
void LCD_w_com(uchar com)
{
while(lcd_bz());
LCD_DB=com;
LCD_RS=0;//指令
LCD_RW=0;//写入
LCD_E=1;
LCD_E=0;
delay(1);//等待执行完毕。。。
}
//===================写数据函数=================