基于51单片机和 ADC0808 ADC0809的自动数字电压表proteus仿真程序设计

前言:

附:http://www.jh-tec.cn/archives/7315

之前讲过基于数码管显示的自动数字电压表,接下来讲一下基于LCD1602显示的相关设计,分别利用的是TI公司的ADC0808和ADC0809。

硬件和软件设计

基于51单片机+ADC0808+LCD1602 测试电压范围为2.1~25V(超出这个范围,程序会卡死),精度<0.05

仿真图如下:
在这里插入图片描述
在这里插入图片描述
部分代码如下:

#include <AT89X52.H> 

#define LEDDATA P0
#define v20_on {s3=0;s2=0;s1=1;} //宏定义不同量程,不同的开关状态
#define v2_on {s3=0;s2=1;s1=0;}
#define v02_on {s3=1;s2=0;s1=0;}
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
unsigned char dispbuf[8]={0,0,0,0,0,0,0,0};
unsigned char getdata;
unsigned long temp;
unsigned char i,k,l,m;
unsigned char code  mytable0[]=" Welcome to use  ";
unsigned char code  mytable1[]="Auto Voltmeter!";
unsigned char code line0[]="  Voltmeter   ";    //初始化显示 
unsigned char code line1[]=" Value:     V ";
//引脚定义
sbit lcdrs=P2^0;
sbit lcden=P2^1;							
sbit s3=P3^7;  
sbit s2=P3^6;
sbit s1=P3^5;
sbit OE=P3^0; 
sbit EOC=P3^1;
sbit ST=P3^2;

void delay(unsigned int z)      //延时子函数  z*1ms 
{
	unsigned int x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
void write_com(unsigned char c)   //写命令子函数 
{
	lcdrs=0;                //低电平选择为 写指令 
	lcden=0;                
	LEDDATA=c;                   //把指令写入P0口 
	delay(5);               //参考时序图 
	lcden=1;                //开使能 
	delay(5);               //读取指令 
	lcden=0;                //关闭使能	 
} 

void write_data(unsigned char d)  //写数据子函数 
{
	lcdrs=1;             //高电平选择为 写数据 
	LEDDATA=d;                //把数据写入P0口 
	delay(5);            //参考时序图 
	lcden=1;             //开使能 
	delay(5);            //读取数据 
	lcden=0;	         //关闭使能 
} 
void initialize()      //LCD初始化函数 
{   
    unsigned char num;
	lcden=0;
	write_com(0x38);   //设置16x2显示,5x7点阵显示,8位数据接口 
	write_com(0x0c);   //00001DCB,D(开关显示),C(是否显示光标),B(光标闪烁,光标不显示) 
	write_com(0x06);   //000001N0,N(地址指针+-1)
	write_com(0x01);      //清屏指令  每次显示下一屏内容时,必须清屏            
	write_com(0x80+0x10);           //第一行,顶格显示  			 
	for(num=0;num<17;num++)        
	{
		write_data(mytable0[num]); 
		delay(10);
	}
	write_com(0x80+0x50);           //第二行,从第一格开始显示 
	for(num=0;num<15;num++)       
	{
		write_data(mytable1[num]); 
		delay(10); 
	}
		for(num=0;num<16;num++)
	{
		write_com(0x1c);   //0001(S/C)(R/L)**;  S/C:高电平移动字符,低电平移动光标;  R/L:高电平左移,低电平右移 
		delay(300);
	}
	   delay(1000); 
	             
	write_com(0x01);      //清屏指令  每次显示下一屏内容时,必须清屏 
	write_com(0x80);            			
	for(num=0;num<14;num++)     
	{
		write_data(line0[num]);
		delay(10);
	}

	write_com(0x80+0x40);         
	for(num=0;num<15;num++)        
	{
		write_data(line1[num]);
		delay(10);
	} 	
} 

.
基于51单片机+ADC0809+LCD1602 测试电压范围为0~5V,精度约为0.01
以AT89C51单片机为核心,起着控制作用。系统包括LCD1602液晶显示电路、复位电路、时钟电路、模数转换电路电路。设计思路分为五个模块:复位电路、晶振电路模块、AT89C51、LCD1602液晶显示电路、模数转换器电路这五个模块。在这里插入图片描述
在这里插入图片描述
部分代码如下:

//<程序名>:数字电压表																 		 **
//<功能>:使用LCD显示被检测电压,精度为0.05V,范围是0~5V。									 **
#include"includes.h"
#define TIME0H 0x3C
#define TIME0L 0xB0
uchar uc_Clock=0;		//定时器0中断计数
bit b_DATransform=0;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<把电压显示在LCD上>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vShowVoltage(uint uiNumber)
{
	uchar ucaNumber[3],ucCount;
	if(uiNumber>999)					
		uiNumber=999;
	ucaNumber[0]=uiNumber/100;								//把计算数字的每个位存入数组。
	ucaNumber[1]=(uiNumber-100*(int)ucaNumber[0])/10;							
	ucaNumber[2]=uiNumber-100*(int)ucaNumber[0]-10*ucaNumber[1];
	for(ucCount=0;ucCount<3;ucCount++)
	{
		vShowOneChar(ucaNumber[ucCount]+48);				//从首位到末位逐一输出。
		if(ucCount==0)
			vShowOneChar('.');
	}
}
//*************************************************************************************************
//*																								  *
//*			  ********************************主函数******************************				  *
//*																								  *
//*************************************************************************************************
void main()
{
	TMOD=0x01;			//定时器0,模式1。
	TH0=TIME0H;
	TL0=TIME0L;
	TR0=1;				//启动定时器。
	ET0=1;				//开定时器中断。
	EA=1;				//开总中断
	vdInitialize();
	vWriteCMD(0x84);	   //写入显示起始地址(第一行第4个位置)
	vShowChar("voltage");
	vWriteCMD(0xC9);     
	vShowChar("(V)");
	while(1)
	{
		if(b_DATransform==1)
		{
			b_DATransform=0;
			vWriteCMD(0xC4);
			vShowVoltage(uiADTransform());
		}
	}
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器0中断函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void t0() interrupt 1
{
	if(uc_Clock==0)
	{
		uc_Clock=5;
		b_DATransform=1;
	}
	else
		uc_Clock--;
	TH0=TIME0H;		   //恢复定时器0。
	TL0=TIME0L;
}



  • 19
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值