深入讲解LCD1602指令集(附上代码演示及现象讲解)

您所在的位置:网站首页 via指令码 深入讲解LCD1602指令集(附上代码演示及现象讲解)

深入讲解LCD1602指令集(附上代码演示及现象讲解)

2024-07-02 03:27| 来源: 网络整理| 查看: 265

前言: 近几天为了写LCD1602显示与运行的深度原理大量翻阅资料,研究到LCD1602指令集时发现碰到硬茬子了—

1.CSDN上关于LCD1602指令集的文章大多为水文,直接Pia的一手就是图一或图二加上一大堆臭长代码再随便和点“水泥”集成一块就草草上传,从中吸收的有用东西很少 。

2.网上所传的指令集(应该就图一二两种没跑了吧)中概念晦涩难懂—LCD的光标,AC等等概念是什么,长什么样,有什么用,操作描述不够清晰—光标,屏幕的移动是怎样移动,移动是什么原理实现的,光标,屏幕,AC之间有什么关系,它们的移动与DDRAM,CGRAM有什么联系?

在今天这篇文章,这些问题将得到一一解决,至于网传指令集上述问题是可以理解的,毕竟它们的来源是某些好心人或厂商对HD44780U芯片进行相应总结概括,从而流传到网上

所以:

我溯源求根,找到了控制LCD1602运行的核心芯片:HD44780U,自己手撕芯片手册,同时往该芯片方向查找资料,力求能对LCD1602指令集有深刻清晰的了解。

通过对LCD1602指令集的深入讲解,我们能进一步LCD1602显示及运行的原理,进而HD44780U这款芯片有一个初步的了解和认识,这样能更好的为阅读我的下一篇博客打下牢固的知识基础。

LCD1602指令集总览: 注意:本文章将基于图一进行讲解,现在你所看到的图一是有经过我修改的,修改的地方在此先点出,避免漏看指令集里面补充的内容:

1.清屏指令除了清除DDRAM和AC,光标复位还有把I/D(指令集第3个输入方式设置的DB1)变为1且进入S的模式不变的效果,同时若清屏前发生了移位,显示屏会恢复原始状态(即会显示消失,光标复位)

2.输入方式设置指令画面的左移还是右移已经标清

同时:图二的显示开关控制指令中光标闪烁的开关颠倒(应该是1闪0不闪)

一般来说:网上指令集图就有以下三种没跑了吧?

图一:所有指令集成一张图 特点:写指令的十六进制值已标出,非常直观简单

但不足的是DB7~DB0对应的符号没给出,不利于交流沟通

图二:普中开发资料中的指令集 特点:写指令的十六进制值没有给出,需自己计算

但DB7~DB0对应的符号有给出,有利于交流沟通

 图三:HD44780U官方指令集 特点:绝对官方权威,真实可靠

 以上就应该是网上流传的三种主流指令集图了,接下来就是进行各个指令的深入讲解了

LCD1602指令集深入讲解: 注意:我不会对所有指令集的所有指令进行讲解(因为没必要),我只挑一些重要且难以理解的指令进行解释(但放心,任何事物都是有联系的,更何况都在同一指令集中的,我在解释挑出来的指令时,会给出一些代码现象,里面的代码有涉及那些没挑出来到的指令,就足够加深你的这部分指令的理解了)

1.清屏指令 就是清除DDRAM和清除AC值,清除了之后光标就会复位。

那么什么是DDRAM,什么是AC,什么是光标,为什么把DDRAM和AC清除后屏幕就能实现清屏的效果呢?这三What一Why待我慢慢展开:

三个What: 1.DDRAM 显示数据随机存储器 (Display Data RAM,简称DDRAM)

通俗地讲:里面存放待显示字符在屏幕位置的信息(地址)(简单地说就是我们告诉DDRAM写入的字符要在屏幕的哪里显示,DDRAM就会根据我们告诉的信息在屏幕相应位置显示字符)

#   那么我们如何告诉DDRAM我们想要在屏幕哪里显示的信息呢?

答案就是指令集的第八个指令

#   如何告诉的问题我们已经解决,那么我们如何向DDRAM表达我们想要在屏幕哪里显示的信息呢?

是不是要在屏幕第一行第一个位置显示字符,就是往DDRAM里面写入0x00呢?按照常理来说确实如此,但是,因为不同指令集要区分的原因,实际并不是写入0x00(这句话怎么理解呢?)

有没有注意到DB7是固定为1,你再好好看看指令集(图一)中九条指令是不是肯定有一位固定为1?哎,恭喜你发现细节所在:LCD1602就是通过对某些位固定为1来区别我们给它的指令是哪一条。

所以,要在屏幕第一行第一个位置显示字符,就要向DDRAM中写入0x80(1000 0000)

要在屏幕第一行第八个位置显示字符,就要向DDRAM中写入0x87(1000 0111),以此类推。

但注意:这个类推仅能推到第一行的第40个位置(即0xa7(1010 0111)),更详细见下一篇博客。

这样你就学会如何告诉DDRAM我们想要在屏幕的哪里显示了。

2.AC 地址计数器(Address Counter,简称 AC)

 通俗地讲:里面存放DDRAM和CGRAM中要显示字符位置(地址)的信息,并且在我们告诉LCD1602指令后,AC会自动为地DDRAM和CGRAM分配地址(加一或减一)

至于加一还是减一,可以通过指令集的第三个输入方式设置进行设置。

3.光标 一般的光标想必大家都见过,就是在聊天框中那个一闪一闪的竖线,而LCD1602的光标长什么样呢?我们翻阅HD44780U可以寻得答案:

从图中我们可以看出光标就是在点阵(就是图中方格组)最下面的一行全亮的方格组,光标的闪烁就是在光标上的方格组进行亮灭循环,而设置光标的显示与闪烁的指令就是指令集第四个显示开关控制。

一个Why: 首先,我再提一个更深的问题:是把DDRAM清除后,AC,光标跟着清除,还是说DDRAM的清除,AC的清除,光标的复位是三个同时进行的互不相干的过程?

下面给出一段代码现象,便于我们巩固上面的内容,引发我们的思考,进而了解DDRAM,AC,光标的关系,以便我们解决这个棘手的Why

代码: #include "regx52.h" #include "LCD1602.h" #include "delay.h"   unsigned char ac_add;//接收AC值的变量 void main() {     //LCD1602的初始化     LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵     LCD_WriteCommand(0x0f);//显示开,光标开,闪烁开     LCD_WriteCommand(0x01);//光标复位,清屏     LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动     while(1)     {             LCD_WriteCommand(0x80);//告诉DDRAM我们要在屏幕的第一行第一个位置显示             LCD_WriteData(0x61);//告诉CGROM要显示的字符,根据ASCII码表,0x61为小写'a'             ac_add=ac_add_read();//接收AC值             LCD_ShowHexNum(1,6,ac_add,2);//显示AC值             while(1);//把程序卡死,避免重复上面代码         /*注:LCD写指令和显示十六进制代码不会的去看江科大                     也可以去看我的下一篇博客                     读取AC值代码内容下面有给出         */                 } }     /*读取AC值(代码原理可先不管,要了解原理的见下一篇博客) unsigned char ac_add_read() {     unsigned char address;     LCD_DataPort=0xff;//清除上一次写指令缓存的数据     LCD_RS=0;     LCD_RW=1;     do{         LCD_EN=1;         LCD_Delay();         address=LCD_DataPort;         LCD_Delay();             LCD_EN=0;         }    while(address&0x80);//等到BF为0跳出     return address;//返回读到的AC数据 } */   代码现象:

LCD1602指令集代码现象一

代码现象解析: 1.首先回忆一下,上面三个What中光标是出现在字符的哪里?是在字符本身的最下面是吧。而我们看到在第一段视频中,光标居然出现在字符a的后面,这究竟是怎么回事呢?

我们先来揭晓DDRAM,AC值和光标的三者关系: 在上面的介绍,我们已经得知:AC存放的值就是DDRAM中的地址信息(当然也有CGRAM的信息),那光标和DDRAM,AC有什么关系呢?

让我们再一次地翻阅HD44780U,从图中可得:

由此我们可以得知:光标位置是于AC中存放的DDRAM的地址信息有关。

那么,按道理来说:我们向DDRAM中写入0x80,那光标位置不应该是在0x80(即第一行第一个字符a的位置)下面吗?怎么会出现在字符a的后一位(0x81)呢?

答案就是在LCD1602的初始化中!

请注意这条指令:LCD_WriteCommand(0x06);//数据读写操作后,AC自动加一,画面不动

而且还要注意:光标位置是由AC中的DDRAM地址信息决定,而不是由DDRAM中的地址信息决定

(这是一个很细微的差别)

所以:在写0x80指令后,AC自动加一,AC中DDRAM地址信息变为0x81,光标就自然而然地跑到字符a后一位了。

为了回答这个棘手的Why问题,我们还要注意:AC不仅能存放地址信息,还能分配地址信息。

这样:我们就可以回答这个棘手的Why问题:

清屏指令会先把AC里面DDRAM的地址信息置0,从而使DDRAM里面的地址信息为0,同时因为AC里面DDRAM的地址信息为0,光标也就会跟着复位。

顺便提一嘴:其实在HD44780U中,清屏指令并不是像最上面的图一这般描述,我们可以去看图三,官方的说法是:清除整个显示器并把AC中DDRAM的地址置0.刚才我只是回答了清屏函数如何使光标复位,还没有回答是怎么清除显示屏。(鉴于篇幅问题,我这里就简单的说:实现原理是对屏幕的每一个位置都显示空格(即告诉DDRAM所有位置都要显示,告诉CGRAM所有位置都显示空格(ASCII码值为0x20)))

在HD44780U同样有相应介绍:

我们也可以来验证这三者的关系: 那么如何验证呢?那就要用到指令集的第九条读忙标志和AC值指令了。

那么该指令的AC读取是读取什么时候的AC值呢?翻阅HD44780U,我们可得:

所以:读取的AC值是读取前的上一条指令执行后AC中DDRAM的地址信息。

根据第二段视频(加入了读取和显示AC值),我们可以得到DDRAM里面的值为0x00,写指令后AC自动加一,AC中DDRAM地址信息变为0x01,所以视频中显示出01,同时因为LCD_ShowHexNum函数有设置DDRAM地址再加上写完AC自动加一,光标最后就在01后面。

与归位指令的区别 这里注意:清屏和归位指令是存在差别的,前者是清除整个显示器并把AC中DDRAM的地址置0,后者是仅把AC中DDRAM的地址置0。

下面是在代码最后加上LCD_WriteCommand(0x02)效果:光标跑到字符a下面

好了,终于终于把清屏指令相关细节到此就告一段落了!!!

2.输入方式模式指令 引入: 先别急着开始深入的讲解,让我们再看看指令集,有没有惊奇地发现:指令集第五个光标,画面位移指令好像也是对AC和画面进行操作,那么两者本质是否有相同呢?两者显示效果是否一样呢?

然后光标和移屏分别作用是什么样的?同时作用又是怎么样的?

为了解决这些问题,我们必须先了解屏幕和光标移动的原理。

屏幕和光标移动原理: 1.光标的移动原理上面都介绍过了,相必大家经过上面的学习,都了解了一二,简单地讲,AC中DDRAM的地址信息变化(加一减一)则光标就会相应地右移左移。

2.而关于屏幕的移动原理,都看到这里了,也应该知道要干嘛了吧—对,让我们再次翻阅HD44780U资料,从中我们可得:

由图我们可以看出:本来屏幕第一二行的第一个位置是对应DDRAM的0x00和0x40的地址的,屏幕第一二行最后一个位置是对应DDRAM的0x27和0x67的地址的,但经过左移后,屏幕位置对应的DDRAM地址发生移位!由此我们可得:其屏幕移动原理是对屏幕对应的DDROM地址的固定位置进行相应的移动

步入正题: 由上一段代码的现象视频,我们已经初步了解AC自动加一的显示效果(AC自动减一的效果类推可得),那么屏幕的移动和AC自动加减一同时作用的显示效果究竟是怎么样的呢?

以下给出代码及其现象,我们可以从中了了解输入方式模式和清屏指令中的细节所在。(对,在此还涉及到清屏指令)

代码: #include "regx52.h" #include "LCD1602.h" #include "delay.h"   unsigned char ac_add;//接收AC值的变量 void main() {     //LCD1602的初始化     LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵     LCD_WriteCommand(0x0f);//显示开,光标开,闪烁开     LCD_WriteCommand(0x07);//数据读写操作后,AC自动加一,画面左移     //LCD_WriteCommand(0x05);//数据读写操作后,AC自动减一,画面右移     //第二段视频LCD_WriteCommand(0x05)注释取消,对LCD_WriteCommand(0x07)进行注释     LCD_WriteCommand(0x01);//光标复位,清屏     while(1)     {             LCD_WriteCommand(0x84);//告诉DDRAM我们要在屏幕的第一行第五个位置显示             LCD_WriteData(0x61);//向DDRAM第五个位置写入'a'             Delay(1000);             LCD_WriteData(0x62);//向DDRAM第六个位置写入'b'             Delay(1000);             ac_add=ac_add_read();             LCD_ShowHexNum(1,10,ac_add,2);             while(1);//把程序卡死,避免重复上面代码                 } } 代码现象:

LCD1602指令集代码现象二

代码现象解析: 看完三段视频,我们可以得出屏幕的移动和AC自动加减一同时作用的显示效果就是:

光标"固定"不动而显示的内容相应移动。

运用原理回答现象: 让我们把目光放在第一段视频(输入方式为AC加一,画面左移)上,根据前面学习的知识,我们来探讨一下,为什么光标为保持"固定"不动呢?光标不动的话,其AC值是否会改变呢?

下面我给出一个场景,你可能就了解为什么光标不动了:

站点就代表屏幕的位置,车厢序号相当于DDRAM中的地址信息,(一般站点和序号是相对应的)字符a相当于上车的a人,光标相当于一条狗,它会跟随在最后一个上车人的后一节车厢(这个跟随相当于AC自动加一),而在人上车后火车向前移动一节车厢的距离(相当于屏幕的移动)

所以第一段视频可解读为a人在5车厢上车,狗就在6车厢,此时火车前移,a人(5车厢)就跑到站点4(屏幕第四位置),狗(6车厢)就跑到站点5(屏幕第五位置)了;然后b人就在6车厢上车,狗就跑到7车厢,火车再前移,a人(5车厢)就跑到站点3(屏幕第三位置),b人(6车厢)就跑到站点4(屏幕第四位置),狗(7车厢)就跑到站点5(屏幕第5位置),然后c人在7车厢上车,狗到8车厢,火车前移,最后发现狗依旧是呆在站点5的位置(即屏幕第5位置)

这就是为什么光标不动的原理,而且根据上面的解读·,我们可以知道虽然光标不动,但其AC值是在变化的。而且我们可以在读取AC值那里得到验证:视频中显示AC值为0x06(即在DDRAM的第七个位置,则对应7车厢)

清屏指令的隐藏效果: 让我们把目光放在第二段视频上,经过我们上面的学习,按道理来说,第二段视频的显示效果不应该是光标不动,而显示内容向右移动吗?怎么实际情况却是跟第一段视频一样呢?

我苦寻许久,终于发现问题出现在清屏指令的隐藏效果上:清屏指令除了清除DDRAM和AC,光标复位还有把I/D(指令集第3个输入方式设置的DB1)变为1,进入S的模式不变的效果(这个就是我上面指令集补充的内容)。

再看看之前的代码,你就会发现在LCD1602初始化中,输入方式模式代码执行是先于清屏指令的,这就会导致你设置完AC减一和画面右移后,被后执行的清屏指令重新设置成AC加一和画面左移!!!

所以解决方法是:把清屏指令放在输入方式模式前!就有了第三段视频所示现象。

3.光标画面位移 引入: 接下来就是光标画面位移部分了,了解完它,我们就才可以回答输入方式模式的"引入"中所提的问题。我们先来看看光标画面位移有什么效果:AC加减一(光标位移)以及移屏且光标不动。那么这里光标不动是否意味着就是AC值不变呢?经过上面的学习,我们已经知道光标就是于AC有关,光标不动AC就不变,但事实是否如我们推测的这般呢?本着大胆推测,小心求实的态度,那就让我们再来看一段代码和代码现象,从而解决这些问题,深入了解这一指令。

代码: #include "regx52.h" #include "LCD1602.h" #include "delay.h"   unsigned char ac_add;//接收AC值的变量 void main() {     //LCD1602的初始化     LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵     LCD_WriteCommand(0x0e);//显示开,光标开,闪烁关     LCD_WriteCommand(0x01);//光标复位,清屏     LCD_WriteCommand(0x06);//数据读写操作后,AC自动加一,画面不动          while(1)     {             LCD_WriteCommand(0x89);//告诉DDRAM我们要在屏幕的第一行第十个位置显示             LCD_WriteData(0x61);//向DDRAM第五个位置写入'a'             while(1)//把程序卡死,避免重复上面代码                 {                 Delay(300);                 //LCD_WriteCommand(0x14);//光标右移                 LCD_WriteCommand(0x1c);//画面右移,光标不动             }                          /*验证AC值部分代码             LCD_WriteCommand(0x80);//告诉DDRAM我们要在屏幕的第一行第十个位置显示             LCD_WriteData(0x61);//向DDRAM第五个位置写入'a'             Delay(300);             LCD_WriteCommand(0x1c);             Delay(300);             LCD_WriteCommand(0x1c);             Delay(300);             LCD_WriteCommand(0x1c);             ac_add=ac_add_read();             LCD_ShowHexNum(1,10,ac_add,2);             while(1);//把程序卡死,避免重复上面代码*/                 } }

代码现象:

LCD1602指令集代码现象三

代码现象解析: 引入的答案: 由第一段视频,我们可以看出在画面连续移动三次后,AC的值依旧为0x01,这就说明我们的推测是正确的,光标不动则AC值不变(当然这里的不动是指AC中DDRAM地址不变),由视频可以看出移屏且光标不动指令的显示效果是显示内容和光标一块移动

隐藏的细节: 通过第二三段视频,你们有没有发现光标是移动到第一行的尽头就跳到第二行,而画面是两行同时移动,那么输入方式模式下的光标画面移动是在两行还是在所在行呢?我们可以看看第四段视频,发现怎么有点看不懂是怎么回事,而且翻阅HD44780U也没有相应说明,所以我就谈谈我的推测:

输入方式模式下的光标画面移动其实是同光标画面移位指令的,因为写入四个a后光标已经经过0x00,跳到下一行的0x40(这时候就是在屏幕的第五位置),然后在第二行开始写入a直到又跳到第一行。

如果有大佬知道相关的确切信息,恳请大佬赐教!

这样想必你已经对输入方式模式的引入中的问题已经有了答案,那么这篇文章就到处结束了。

笔者有话: 1.这篇文章肝了我四天时间,每每想到有些文章随便一水,就有不少的阅读量点赞量,而自己呕心沥血铸成的文章却无人问津,实属心痛!恳请大家不要吝啬手中的点赞(能点点关注就更好了)

2.写到现在8000字,我想引用我翻阅过的一篇文章末尾让我会有感触的一段话:

“我感觉网上很多资料介绍得不够详实,而且千篇一律,作者写文章仿佛有个前提,就是假设读者已经具备一定的基础知识和概念了,所以介绍得就不是特别细致,其实进行学习的人往往就是没什么基础才来看这些文章,导致最后稀里糊涂。看了很多国外的书籍,作者把读者看做“小白”,从基础讲起,使得读者的理解“渐入佳境”,达到自学而且学会的目的,希望咱们国内的同道有所借鉴”

http://news.eeworld.com.cn/mcu/ic622204.html ————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/m0_73964304/article/details/132531136

学习单片机少不了用到液晶显示模块,说到液晶显示模块想必一定要学习1602这款,1602只是个显示模块的代号,并不是指具体哪一个厂商的哪一款产品。“16”的意思是显示屏上“每一行显示16个字符”,“02”的意思是显示屏上可以显示2行。

1602的控制芯片,也就是MCU(Microcontroller Unit)是HD44780,只有通过MCU,1602才能按照我们的设计进行显示。

在学习1602之初,对于如何操作这款液晶显示模块不甚了解,网上的文章查了不少,但感觉还是一知半解,大部分资料存在两个问题:第一是不够完整,有很多名词和概念解释得不够清楚,内容节选自某些芯片厂商的数据手册,厂商是按照一定顺序和逻辑编写的技术文档,如果仅是节选,就无法以正常的思维方式了解全部;第二是缺乏细节,对某一点解释得不够透彻。所以看完之后我就进入了“半瓶子”状态,说自己会不能说错,的确也知道一些,说不会也不冤枉,因为真的不会实际操作。为了学得彻底,我还是决定老老实实、认认真真的从最基本的知识和概念入手,进行学习和研究。既然1602是由MCU控制的,那咱们就来学习HD44780这款MCU的知识。网上下载了HITACHI生产的HD44780U的资料,一起看看。

一. 总体介绍

HD44780U是一款“点阵式(dot-matrix)液晶(liquid crystal)显示控制器”

能够配合4位或者8位微处理器驱动点阵式液晶显示模块

能够显示1行或者2行,每行8个字符的信息

可以显示5X8点阵字符,也可以显示5X10点阵字符

扩展了“字符生成器(charator generator )ROM”,也被称为“CGROM”,使之可以显示208个字符(使用5X8点阵字符显示),或者32个字符(使用5X10点阵字符显示),总共240个不同的字符显

二. 功能介绍

寄存器选择标志 Register Selector(RS)

a. 芯片包括2个8位寄存器,一个是指令寄存器(instruction register,简称 IR),另一个是数据寄存器(data register,简称 DR)

b. IR存储指令,例如“清屏”指令,“光标移动”指令等,除此之外,IR还存储用于显示数据的地址信息,这里的“地址”指的是“显示数据随机存储器(DDRAM)”或者“字符生成随机存储器(CGRAM)”中存储的地址信息,DDRAM和CGRAM在后面介绍

c. DR存储数据,当需要传输数据到显示模块时,数据是需要传送给MCU中的DDRAM或者CGRAM这样的存储器中,在这个过程中,数据先存储在DR当中,在传送到DDRAM或者CGRAM中。同理,从显示模块的MCU中读取数据时,也需要使用DR充当中转站,需要注意的是,DR和DDRAM或者CGRAM的传输是自动完成的。另外,既然写入和读取都与DDRAM或者CGRAM有关系,那么如何知道数据写入或者读取DDRAM或者CGRAM中的哪个位置呢,这就要用到IR中存储的相关地址信息。还有一点需要说明,在进行读取操作时,当前一个地址中的数据读取完毕后,位于DDRAM或者CGRAM中的下一个地址中的数据会被自动发送到DR中等待MCU的下一次读取。想一想,写入数据时候,地址会不会自动转移到下一位呢?

d. MCU设置了“寄存器选择标志 (Register Selector)”来判断应该使用哪个寄存器,使用者需要设置RS的电平用以实现相关寄存器的选择。

读写操作选择标志 Read/Write (R/W)

通过设置“读写操作选择标志”为高、低电平通知MCU应该进行“读”或者“写”哪一种操作

R/W与RS配合设置可以实现多种操作,如下图

忙标志(Busy Flag)

当Bush Flag,简称BF为1时,MCU处于“忙”状态,所谓“忙”的意思是说MCU还处于内部操作当中,你也可以认为是MCU“发呆”了,此时,MCU不接受任何指令。只有BF为0时才意味着MCU“清醒”了,这时才能和外界通讯,从而接受指令。注意,当设置R/W和RS实现读取指令时,MCU在DB7位(也就是读出的二进制数列的最高位)读取BF的状态值(0或者1),这样,就可以根据BF的值判断MCU的“清醒的”还是“正在发呆”。

地址计数器(Address Counter,简称 AC)

地址计数器,简称AC,是用来存储地址信息的,当IR中写入了一个地址信息,它就被发送给AC,AC既可以存储DDRAM的地址信息,也可以存储CGRAM的地址信息,至于如何区分,则是写入IR时通过指定的一些格式进行实现的。在读出(或者写入)DDRAM或者CGRAM后,AC中的值会自动加1或者减1。

显示数据随机存储器 (Display Data RAM,简称DDRAM)

a. DDRAM可以被认为是“显存”,存储在其中的内容就会被显示屏显示,DDRAM是随机存储器,意味着我们可以向其中写入信息,写入什么信息就显示什么信息,但断电后DDRAM中的信息就被“释放”了。其中一共可以存储并显示80个字符,每个字符有一个地址,这个地址用8位二进制数表示。其中有几点需要注意。

b. 第一点:显示屏上能够显示的字符不足80个,1602显示模块每行最多能显示16个字符,其余的字符是无法同时在屏幕上显示的,为何要设置如此多的又不能同时显示的字符呢,其实是为了能做到“滚屏”,在此不做展开,请自行想象。而不同的芯片显示的字符长度是不同的,使用时需要查看数据手册。1602可以设置成同时显示2行,每行16个字符,地址如下图,发现其中第一行最后一个字符的地址和第二行第一字符的地址并不连续,使用时需要注意。

c. 第二点:你会发现在使用DDRAM地址的时候,指令格式的范例中都是7位,不是8位吗?怎么变成7位了呢,原因是HD4478U芯片中设置了最多80个字符,也就意味着最多有80个地址,最大地址用十六进制表示为4F,用二进制表示就是1001111,所以最大就是7位二进制数,那么第8位即最高位用做什么呢?在设置DDRAM地址的时候第8位要预先设定为1,这一点后面还会提及。

d. 第三点:当设置了“滚屏”功能时,显示屏可以显示DDRAM中被隐藏的其他储存单元中的字符,而显示内容按照储存单元“首尾相接”的顺序进行排布,并且两行同时滚动。例如上、下两行显示完最后两个字符(上图中地址27和67),滚动后接着显示的就是第一个字符(上图中地址00和40)。

字符生成只读存储器(Character Generator ROM,简称CGROM)

a. CGROM存储了240个已经被定义好的字符,其中包括208个5X8点阵的字符,32个5X10点阵的字符。

b. CGROM其实就是一个“字符表”,每个字符都有一个标识,以二进制表示的8位数字表示,这个标识被称为 Character Codes,即“字符码”,想要显示哪个字符直接向DDRAM中写入这个“字符码”就可以了。

c. CGROM为只读存储器,不能修改。

字符生成随机存储器(Character Generator RAM,简称CGRAM)

a. CGRAM是随机存储器,意味着可以写入和修改信息,但是在断电后就CGRAM中的内容就释放了。我们可以用CGRAM编写CGROM中没有的字符。

b. 对于5X8点阵显示方式,可以编写总共8个自定义字符,对于5X10点阵显示方式,可以编写总共4个自定义字符。

c. 与CGROM的设计相同,CGRAM中的每个“自定义”字符也有一个标识,以二进制表示的8位数字表示,与CGROM中的字符的“字符码”不同的是,CGRAM中的每一个字符的字符码其高4位二进制数值都是0,低4位二进制数值的前三位即第0、1、2位用来表示不同的字符,对于5X8点阵显示方式,这三位的字符码从“000”到“111”。低4位的第4位是“无效”位,意思是可以被设置为0,也可以被设置为1。

d. 与每个字符码相对应的是字符的“地址码”,地址码由6位二进制(0~5)表示,对于不同的显示方式,设定是不同的。对于5X8点阵显示方式,这个6位地址码的高3位与“字符码”的第三位相同,而低3位则表示8个不同的字节单元的地址(000~111)。这8个字节是用来构建字符形状的,这也就“点阵”概念的具体实现方式,还记得5X8吗?这8个字节就代表了点阵中的8行。那么5又是什么呢?5就是点阵中一行内的每个点,也就是对应每个字节的各个位,由于每个字节是8位,所以在设置的时候每个字节只用其中的低5位,即0~4,高3位即5~7是无效位,一般置0。在设置时,8个字节的最后一个字节是光标位置,可以置0或者1。通过这种方法组成的字形被称为“字模”(Character Pattern)。5X10显示方式稍有不同,顾名思义,其用到11个字节表示字形,而其地址码仍然由6位组成,所以必须用低4位表示不同的字节单元地址(0000~1010),高2位与“字符码”的低2位相同以表示不同的字符码,同样,地址的最后一位地址即1010对应的字节是光标位置。5X10显示方式的字符码同样是8位的,但第0位和3位是无效位。两种显示方式的字模表如下图

 

DDRAM、CGROM、CGRAM三者之间的关系

DDRAM用来存储需要显示的符号,所以被称为显存,需要显示什么符号,就必须把相应的符号放在DDRAM中;CGROM用来存储标准的符号,这些标准符号是预先存放在CGROM中的,使用时需要把需要的字符的字符码写入DDRAM就可以显示了。大部分字符都可以在CGROM中找到,对于找不到的字符则需要自定义,这时就用到CGRAM了,在使用前需要把字符用字模编辑的方式存储在CGRAM中,再把CGRAM的字符的字符码写入DDRAM中就可以显示了。

三. 初始化与指令

初始化

HD44780U这款芯片带有内部的“上电自动初始化”功能,例如设置“清屏”、“功能设置”、“显示控制”等,当某些情形不能使芯片实现内部初始化时,就必须使用在线的“指令”初始化进行设置,在线的“指令”初始化就是我们使用各个指令通过MPU(Microprocessor Unit)来实现。

在线指令初始化

MPU可以控制HD44780U的指令寄存器(IR)、数据寄存器(DR),MPU发送各种信号用以设置各种功能,例如寄存器选择(RS)、读/写选择(R/W)、数据总线(DB0~DB7)

a. 清屏(Clear Display):

    格式:0  0  0  0  0  0  0  0  0  1

    作用:清除整个屏幕并且设置DDRAM的地址为0x00

b. 归位(Return Home):

    格式:0  0  0  0  0  0  0  0  1  -(“-”代表无效位,可以置0)

    作用:设置DDRAM的地址为0x00,将显示内容回归至最初位置,DDRAM中的内容保持不变(不清屏)

c. 模式设置(Entry Mode Set)

    格式:0  0  0  0  0  0  0  1  I/D  S

    作用:设置光标的移动方向(也就是DDRAM地址值),指定显示内容是否滚动

    说明:I/D = 1:光标自动增1(DDRAM地址值自动增1);I/D = 0:光标自动减1(DDRAM地址值自动减1);S = 1:显示内容滚动(看起来像是光标不动而显示的内容移动,注意:读取DDRAM内容时显示内容不滚动,读取或者写入CGRAM时显示内容也不滚动)

d. 显示开关控制(Display On/Off Control)

    格式:0  0  0  0  0  0  1  D  C  B

    作用:设置显示开或者关,光标开或者关,光标位置是否闪烁

    说明:D = 0 显示关闭;D = 1 显示开启;C = 1 显示光标;C = 0 不显示光标;B = 1 光标处的字符闪烁;B = 0 光标处的字符不闪烁

e. 光标移动/显示滚动 (Cursor or Display Shift)

    格式:0  0  0  0  0  1  S/C  R/L  -  -(“-”代表无效位,可以置0)

    作用:设置光标移动或者显示滚动

    说明:S/C = 1 显示滚动;S/C = 0 光标移动;R/L = 1 向右移动;R/L = 1 向左移动;此功能设置在没有读/写操作时光标或者显示的移动,主要用于搜索或者修正显示内容,其功能不同于指令c中的显示滚动,设置显示滚动时光标跟随内容一同移动

f. 功能设置(Function Set)

    格式:0  0  0  0  1  DL  N  F  -  -

    作用:设置信息长度,显示行数,字符点阵类型

    说明:DL = 1 总线为8位;DL = 0 总线为4位;N = 1 显示2行;N = 0 显示1行;F = 1 点阵为5X10;F = 0 点阵为5X8

g. 设置CGRAM地址(Set CGRAM Address)

    格式:0  0  0  1  ACG  ACG  ACG  ACG  ACG  ACG

    作用:设置CGRAM的地址,注意此指令执行后需要执行传输CGRAM中数据的指令

h. 设置DDRAM地址(Set DDRAM Address)

    格式:0  0  1  ADD  ADD  ADD  ADD  ADD  ADD  ADD

    作用:设置DDRAM的地址,注意此指令执行后需要执行传输DDRAM中数据的指令

i. 读取“忙状态”以及地址(Read Busy Flag & Address)

    格式:0  1  BF  AC  AC  AC  AC  AC  AC  AC

    作用:读取“忙状态”并且读取地址计数器(Address Counter)中的地址

j. 向DDRAM或者CGRAM中写入数据

    格式:1  0  字符码

    注意:写入数据后地址计数器(Address Counter)中的地址自动加1

k. 读取DDRAM或者CGRAM中的数据

    格式:1  1  字符码

    注意:读取数据后地址计数器(Address Counter)中的地址自动加1

指令列表如下图

通过以上的介绍相信大家对1602这款显示模块有了进一步的了解,在使用中还需要注意很多注意事项,建议大家仔细研读厂商的MCU控制芯片数据手册。

说句题外话,如我在文章开头讲到的,我感觉网上很多资料介绍得不够详实,而且千篇一律,作者写文章仿佛有个前提,就是假设读者已经具备一定的基础知识和概念了,

所以介绍得就不是特别细致,其实进行学习的人往往就是没什么基础才来看这些文章,导致最后稀里糊涂。看了很多国外的书籍,作者把读者看做“小白”,从基础讲起,

使得读者的理解“渐入佳境”,达到自学而且学会的目的,希望咱们国内的同道有所借鉴,当然,有些文章的起点比较高,介绍的就是“高起点,深层次”的知识,那另当别论。

关键字:液晶显示模块  HD44780引用地址:1602 液晶显示模块 + HD44780 控制芯片 使用指北



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3