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

来源:互联网 发布:即刻软件 编辑:程序博客网 时间:2024/05/16 08:39

这次要做的是通过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);//显示开,光标不显示,DCBWrite_Cmd(0x06);//文字不动地址增进,NSWrite_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坐标最高位为1elseWrite_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;//输入IORS=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坐标最高位为1elseWrite_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);//显示开,光标不显示,DCBWrite_Cmd(0x06);//文字不动地址增进,NSWrite_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();//初始化LCD1602Show_Str(0,0,str1);//显示字符串Show_Str(0,1,str2);//显示字符串while(1);}






0 0
原创粉丝点击