前言:
附: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;
}