做一台网络收音机——3控制1602液晶显示

这次要做的是通过1602液晶屏幕显示一串英文Hot Display Char LCD Test

1602液晶虽然不够经济,但外观质量和背光都要比lcd5110强得多,所以这次选择使用它当作显示屏幕。

首先打开1602液晶的说明书,查看各个引脚的定义说明。










它有16个引脚。

1——GND 4——传递的是数据/命令选择(RS)                                          

2——VCC 5——读/写选择(RW)

3——显示对比度控制  6——使能(E)

15——背光正极 7-14——D0-D7通信通道(DB)

16——背光负极

可以写出管脚定义代码代码:

/*管脚定义*/
sbit RS=P2^6;//数据与指令选择,高电平选择数据寄存器

sbit RW=P2^5;//读写选择,高电平进行读

sbit E=P2^7;//使能,由高到低液晶模块执行命令

sfr DB=0x80;//8位双向数据

然后继续查看器件说明手册。了解一下是否需要初始化,如果需要初始化,初始化时又需要做哪些动作?

从说明书中了解到,1602在显示前是需要先初始化的,初始化的目的是,告诉液晶主控芯片显示的方式是如何的。

最简单的初始化步骤是:

1设置显示模式——>2是否打开显示和是否显示光标——>3以何种方式显示多个字符?——>4清空显示缓存


1.因为1602液晶的每个小格子点阵是宽5高7的(5*7)所以要设定主控芯片的显示模式,来和液晶显示屏相匹配。

2.只有打开显示时屏幕上才会有字符显示,关闭光标屏幕上才不会出现不需要的光标

3.当显示多个字符时有两种方式,一种是类似于街边的流动广告。一种类似于KTV下面的歌词字幕。

4.如果不清空缓存刚启动时缓存里面可能会有残留数据。


了解了初始化的步骤后,继续查看说明书。了解一下1602主控芯片支持的指令有哪些。毕竟通过发送具体的指令才能初始化它。

1602液晶内部的控制器共能识别11条指令。





















现在知道了主控芯片可以识别的指令,还有初始化的步骤。剩下的就是如何给主控芯片传送指令或数据了。

继续查阅1602的使用手册。

了解到,读1602内部数据的过程如下:

















同是了解到,1602液晶显示模块是一个慢显示器件, 在执行每条指令之前一定要确认模块的忙标志为低电平(表示不忙)否则此指令失效。

要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符。

所以参照上面的时序图可以写出读取lcd1602是否是忙碌状态的函数。

代码如下:

/*读取LCD状态*/
void Read_State()
{
	unsigned char state;
	
	DB=0xff;//IO变输入状态

	RS=0;//选择指令寄存器

	RW=1;//读(参照第9条指令)

	do
	{	
		E=1;//使能
		state=DB;//读取数据
		E=0;
	}

	while( state&0x80 );//state最高位是1表示忙碌,0表示空闲
}


接下来是将数据写入1602内部的过程。


















当写的是指令时,RS=0,当写的是数据时,RS=1。每次写之前都要先检查忙碌状态。

所以根据上面的时序图,可以写出两个函数。

代码如下:

/*写指令*/
void Write_Cmd(unsigned char cmd)//cmd为待写入的指令
{
	Read_State();//LCD忙判断

	RS=0;//选择指令寄存器
	RW=0;//写
	DB=cmd;//数据准备
	E=1;//高电平
	E=0;//低电平
}

/*写数据*/
void Write_Dat(unsigned char dat)//dat为待写入的数据
{
	Read_State();//LCD忙判断

	RS=1;//选择数据寄存器
	RW=0;//写
	DB=dat;//数据准备
	E=1;//高电平
	E=0;//低电平
}


现在有了这上面这几段代码,我们终于可以写出初始化函数了。

还记得初始化的步骤吗?

1设置显示模式——>2是否打开显示和是否显示光标——>3以何种方式显示字符——>4清空显示缓存

1.显示模式设定,查阅指令6:功能设置命令 

DL:高电平时为4位总线,低电平时为8位总线 

N:低电平时为单行显示,高电平时双行显示 

F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。

所以,设定显示模式时cmd=0x28

2.查阅指令4,指令4:显示开关控制 
D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 
C:控制光标的开与关,高电平表示有光标,低电平表示无光标
B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。
所以cmd=0x0c

3.查阅指令3,指令3:光标和显示模式设置 
I/D:光标移动方向,高电平右移,低电平左移 
S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。
所以cmd=0x06

4.查阅指令1,cmd=0x01。

所以可以写出初始化代码:
/*初始化LCD*/
void Init_Lcd()
{
	Write_Cmd(0x38);//显示模式5*7,使LCD控制模块和显示屏匹配

	Write_Cmd(0x0c);//显示开,光标不显示,DCB

	Write_Cmd(0x06);//文字不动地址增进,NS

	Write_Cmd(0x01);//清屏
} 

下面就剩下如何让1602显示指定字符了。
继续查阅手册。



















如图,第二行第一个字符的地址是 40H,那么是否直接写入 40H 就可以将光标定位在第二行第一个字符的位置呢?
这样不行,因为写入显示地址时要求最高位 D7 恒定为高电平 1 所以要实际写入的数据应该是 01000000B40H+10000000B(80H)=11000000B(C0H)

在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预。
每次输入指令前都要判断液晶模块是否处于忙的状态。

1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,每一个字符都有一个固定的代码,比如大写的英文字母A的代码是01000001B41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母A


如上图的lcd显示地址,了解到,要在指定位置显示字符必须先将光标移动到指定的位置。
所以可以写出设定显示位置的函数
代码如下:
/*设置显示位置*/
void Set_ShowPos(unsigned char x,unsigned char y)//y表示行号,0/1
{
	if(y==0)

	Write_Cmd( x|0x80 );//第一行的x坐标最高位为1

	else

	Write_Cmd( (x+0x40)|0x80 );//第二行的x坐标最高位为1
}

在这个基础上可以写出指定位置显示字符串的函数。
代码如下:
/*显示字符串*/
void Show_Str(unsigned char x,unsigned char y,unsigned char *str)//显示位置,字符串指针
{
	Set_ShowPos( x,y );//设置显示坐标
	while( *str!='\0' )
	{
		Write_Dat( *str++ );
	}
}

最终完整的代码如下:

lcd1602.c
#include<reg52.h>


/*管脚定义*/
sbit RS=P2^6;//数据与指令选择,高电平选择数据寄存器
sbit RW=P2^5;//读写选择,高电平进行读
sbit E=P2^7;//使能,由高到低液晶模块执行命令
sfr DB=0x80;//8位双向数据,要注意定义方法!!!!!!!!

/*全局变量定义*/

/*读取LCD状态*/
void Read_State()//这里发现问题
{
	unsigned char state;
	
	DB=0xff;//输入IO
	RS=0;//选择指令寄存器
	RW=1;//读
	do
	{	
		E=1;//使能
		state=DB;//读取数据
		E=0;
	}
	while( state&0x80 );
}
/*写指令*/
void Write_Cmd(unsigned char cmd)
{
	Read_State();//LCD忙判断
	RS=0;//选择指令寄存器
	RW=0;//写
	DB=cmd;//数据准备
	E=1;//高电平
	E=0;//低电平
}
/*写数据*/
void Write_Dat(unsigned char dat)
{
	Read_State();//LCD忙判断
	RS=1;//选择数据寄存器
	RW=0;//写
	DB=dat;//数据准备
	E=1;//高电平
	E=0;//低电平
}
/*设置显示位置*/
void Set_ShowPos(unsigned char x,unsigned char y)
{
	if(y==0)
	Write_Cmd( x|0x80 );//第一行的x坐标最高位为1
	else
	Write_Cmd( (x+0x40)|0x80 );//第二行的x坐标最高位为1
}
/*显示字符串*/
void Show_Str(unsigned char x,unsigned char y,unsigned char *str)
{
	Set_ShowPos( x,y );//设置显示坐标
	while( *str!='\0' )
	{
		Write_Dat( *str++ );
	}
}
/*初始化LCD*/
void Init_Lcd()
{
	Write_Cmd(0x38);//显示模式5*7,使LCD控制模块和显示屏匹配
	Write_Cmd(0x0c);//显示开,光标不显示,DCB
	Write_Cmd(0x06);//文字不动地址增进,NS
	Write_Cmd(0x01);//清屏
} 

lcd1602.h
//初始化函数
extern void Init_Lcd(void);
//显示字符串函数
extern void Show_Str(unsigned char x,unsigned char y,unsigned char *str);
//设置显示位置
extern void Set_ShowPos(unsigned char x,unsigned char y);
//写数据
extern void Write_Dat(unsigned char dat);
//写指令
extern void Write_Cmd(unsigned char cmd);
//读状态
extern void Read_State();

main.c
#include<reg52.h>
#include"lcd1602.h"


/*LCD1602显示字符*/
/*测试主函数*/

/*全局变量定义*/
unsigned char *str1="  HOT Display";
unsigned char *str2=" Char LCD Test";


void main()
{
	Init_Lcd();//初始化LCD1602

	Show_Str(0,0,str1);//显示字符串
	Show_Str(0,1,str2);//显示字符串
		
	while(1);
}






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值