基于51单片机的LCD1602显示

最近工作签了,没啥事,毕业设计题目也没出来,打算重新学一下51单片机,补补功课。今天看着 LCD1602 的
datasheet试着自己编写,proteus仿真软件没有LCD1602,使用LM016来代替,先了解一下LCD1602的各引脚
功能。如下图:

基于51单片机的LCD1602显示_第1张图片

                                                  图1 LCD1602 引脚图

51单片机编程要使用RS、E和D0-D7引脚,由于R/W为对1602读写的引脚,不需要对其进行读,所以接低电平。
然后根据下图的LCD1602时序图写指令和数据。

基于51单片机的LCD1602显示_第2张图片

                                                图2 LCD1602时序图

先写两个函数,写指令和数据(第一次,我注释了“EN=1”后面的延时):

write_com(uchar com)   //写指令 
{
	EN=0;
	RS=0;
	P0=com;
	delayms(1);
	EN=1;
	delayms(1);
	EN=0;
}

write_data(uchar dat)   //写数据 
{
	EN=0;
	RS=1;
	P0=dat;
	delayms(1);
	EN=1;
	delayms(1);
	EN=0;
}

程序如下:

#include 
#include 
#include 
#define uchar unsigned char 
#define uint  unsigned int 

sbit RS=P3^0;        //液晶数据指令选择端
sbit EN=P3^1;        //液晶使能端
sbit led=P2^2;
uchar code table[]="Dear Chenli ,";
uchar code table1[]="I LOVE YOU !";

void delayms(uint a) //延时毫秒
{	
	uint x,y;
	for(x=a;x>0;x--)
		for(y=110;y>0;y--);
}

write_com(uchar com)//写指令
{
	EN=0;
	RS=0;
	P0=com;
	delayms(1);
	EN=1;
	//delayms(1);
	EN=0;
}

write_data(uchar dat)//写数据
{
	EN=0;
	RS=1;
	P0=dat;
	delayms(1);
	EN=1;
	//delayms(1);
	EN=0;
}

void init()
{
	write_com(0x38);//设置16x2显示,5X7点阵,8位数据接口,
	write_com(0x0c);//设置开显示,不显示光标
	write_com(0x06);//写一个字符后,地址指针加1
	write_com(0x01);//显示清0,数据指针清0
}

void main(void)
 { 
	uchar i;
	init();
	write_com(0x80);//+0x10
	for(i=0;i

得到的显示结果如下:

基于51单片机的LCD1602显示_第3张图片

说明仿真结果是正确的。
对上面的程序稍加修改,LCD1602第一行起始地址为0x80+0x10第二行起始地址为0x80+0x40+0x10,由于,仍不
加延时,但是当我想实现以下LCD1602的移屏效果,却得不到想要的结果,如下:

基于51单片机的LCD1602显示_第4张图片

上图的代码如下:

#include 
#include 
#include 
#define uchar unsigned char 
#define uint  unsigned int 

sbit RS=P3^0;        //液晶数据指令选择端
sbit EN=P3^1;        //液晶使能端
sbit led=P2^2;
uchar code table[]="Dear Chenli ,";
uchar code table1[]="I LOVE YOU !";

void delayms(uint a) //延时毫秒
{	
	uint x,y;
	for(x=a;x>0;x--)
		for(y=110;y>0;y--);
}

write_com(uchar com)//写指令
{
	EN=0;
	RS=0;
	P0=com;
	delayms(1);
	EN=1;
	//delayms(1);
	EN=0;
}

write_data(uchar dat)//写数据
{
	EN=0;
	RS=1;
	P0=dat;
	delayms(1);
	EN=1;
	//delayms(1);
	EN=0;
}

void init()
{
	write_com(0x38);//设置16x2显示,5X7点阵,8位数据接口,
	write_com(0x0c);//设置开显示,不显示光标
	write_com(0x06);//写一个字符后,地址指针加1
	write_com(0x01);//显示清0,数据指针清0
}

void main(void)
 { 
	uchar i;
	init();
	write_com(0x80+0x10);//+0x10  第一次修改处,地址由0x80变为0x80+0x10
	for(i=0;i

仔细观察,发现第一行的内容不见了,仿真时发现第一行的显示在0x80~(0x80+0x0F)区域,但是程序是写在
(0x80+0x10)~(0x80+0x1F),我检查了几遍,还是不对,百思不得其解。

最后我修改了一下对1602写数据、指令的延时后(取消程序中延时函数的注释),效果一下就出来了。如下:

基于51单片机的LCD1602显示_第5张图片


基于51单片机的LCD1602显示_第6张图片


基于51单片机的LCD1602显示_第7张图片

由于是图片,所以效果不是很好,仿真时可以看到整个移屏的效果,还不错。
这是为什么呢?为什么添加了延时,显示就正确了?
可能是数据还没有完全写完,所以。。。。。

OVER ^_^ 。

你可能感兴趣的:(单片机)