您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 酒店餐饮 > 学习笔记:LCD12864的卷动显示
↓过路者↑第1页共7页学习笔记:LCD12864的屏幕卷动显示首先,先来介绍下与卷动显示相关的存储器:DDRAM(DataDisplayRam)。DDRAM(DataDisplayRam):数据显示RAM,往里面写啥,屏幕就会显示啥,与GDRAM不同的是,这里存储的是字符的编码。也就是显示字符用的RAM。字符的显示是先到CGROM(存储了中文字库)或HCGROM(存储了ASCII码)找到对应编码的字模,再显示到屏幕上。笔者使用的这块12864内部有4行×32字节的DDRAM空间。但是任一时刻,屏幕只能显示2行×32字节的空间,那么剩余的这些空间呢?它们可以用于缓存,在实现卷屏显示时这些空间就派上用场了。DDRAM结构如下所示:80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FHA0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFHB0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH地址与屏幕显示对应关系如下:第一行:80H、81H、82H、83H、84H、85H、86H、87H第二行:90H、91H、92H、93H、94H、95H、96H、97H第三行:88H、89H、8AH、8BH、8CH、8DH、8EH、8FH第四行:98H、99H、9AH、9BH、9CH、9DH、9EH、9FH说明:红色部分的数据归上半屏显示,黑色部分的数据归下半屏显示。一般屏幕的显示用的是上面两行的空间,也就是80H~8FH,90H~9FH,也就是说屏幕显示的内容是存储在80H~8FH,90H~9FH。每个地址的空间是2个字节,也就是1个字,所以DDRAM中可以用于存储字符编码的空间总共是128字节。因为每个汉字的编码是2个字节,所以每个地址需要使用2个字节来存储一个汉字。汉字的编码的高字节和低字节必须连续且要存储在同一个地址中,这样存储的汉字编码才是正确的,才能正常显示,所以一行最多能显示8个汉字,整个屏幕最多能显示32个汉字。当然如果将同一个地址中的2个字节拆开来使用也可以,那就是显示2个半宽字符(数字或字母,就是ASCII码)。这里顺便说明一下:汉字的分辨率是16*16像素,半宽字符分辨率为16*8像素。所以可以认为一个地址管理着屏幕上的16*16个像素点,所以一个地址可显示一个汉字或两个半宽字符。DDRAM数据的读/写:所有的数据读/写都是先送地址,然后进行读/写。对DDRAM写数据时,确保在基本指令集下(使用指令0x30开启),然后写入地址,之后连续写入2个字节的数据。读数据时,在基本指令集下先写地址,然后假读(dummy)一次,之后再连续读2个字节的数据。需要说明的是,每次读/写完一个字节数据后,地址指针会自动增加一个字节。所以读/写完一个字节数据后,地址会自动跳到下一个字节处,所以连续读/写两个字节即可完成对字的操作。这里的假读需要注意,不光是读CGRAM需要假读,读其他的GDRAM、DDRAM都需要先假读一次,之后的读才是真读,假读就是读一次数据,但不存储该数据,也就是说送地址之后第一次读的数据是错误的,之后的数据才是正确的。↓过路者↑第2页共7页关于编码在DDRAM中的存储需要说明事项如下:1)、每次对DDRAM的操作单位是一个字,也就是2个字节,当往DDRAM写入数据时,首先写地址,然后连续送入2个字节的数据,先送高字节数据,再送低字节数据。读数据时也是如此,先写地址,然后读出高字节数据,再读出低字节数据(读数据时注意先假读一次)。2)、显示ASCII码半宽字符时,往每个地址送入2个字节的ASCII编码,对应屏幕上的位置就会显示2个半宽字符,左边的为高字节字符,右边的为低字节字符。3)、显示汉字时,汉字编码的2个字节必须存储在同一地址空间中,不能分开放在2个地址存放,否则显示的就不是你想要的字符。每个字中的2个字节自动结合查找字模并显示字符。所以,如果我们往一个地址中写入的是一个汉字的2字节编码就会正确显示该字符。如果汉字编码高字节存放在前一地址低字节,编码低字节存放在后一地址高字节,显然控制器就不会这样结合起来查找字模,而是与各地址相应的字节结合查找字模。DDRAM卷动功能:DDRAM结构如下所示:80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FHA0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFHB0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH在此说明下,红色部分地址属于上半屏,黑色部分地址属于下半屏,卷动时上下半屏是各自卷动互不干扰的。而无论是上半屏还是下半屏,一行只能对应八个地址,16个字节。所以上半屏和下半屏都是分别总共能够显示16个地址,也就是32个字节。地址与屏幕显示对应关系如下:(上半屏)第一行显示:80H、81H、82H、83H、84H、85H、86H、87H(上半屏)第二行显示:90H、91H、92H、93H、94H、95H、96H、97H(上半屏)第三行不显示:A0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H(上半屏)第四行不显示:B0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H↓过路者↑第3页共7页(下半屏)第一行显示:88H、89H、8AH、8BH、8CH、8DH、8EH、8FH(下半屏)第二行显示:98H、99H、9AH、9BH、9CH、9DH、9EH、9FH(下半屏)第三行不显示:A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFH(下半屏)第四行不显示:B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH那么不显示的地址怎么办呢?这里要说明一个概念:屏幕上每一行每一列并不是固定对应某一个地址不变的!用与存储显示数据的地址对于屏幕来说是可以改变的,屏幕的作用只不过是把某地址上存储的数据显示出来,而这个地址是可以改变的,而地址上存储的数据是不会改变的。就上半屏显示打个比方:有一个四行的柜子,柜子的每一行都放着不同的东西,这个四行的柜子就相当与上半屏的地址了,每一行放着的东西就是地址存储的数据了。现有一个摄像机拍摄柜子放着的东西,摄像机的显示屏就是12864的屏幕了,拍摄柜子上放着的东西就是显示地址存储的数据了。由于拍摄距离和摄像机屏幕大小的限制,摄像机每次只能拍摄柜子的两行,也就是显示屏上每次只能显示柜子的其中两行放着的东西。而要拍摄另外两行怎么办?很简单,就是上下移动摄像机,这样就能拍摄到另外两行了。虽然只能拍摄两行,但只要移动摄像机就能把四行放着的东西依次显示在屏幕上了。这就是卷动显示的原理:令不同地址存储的数据依次显示在屏幕上。开启卷动功能的步骤为:打开扩展指令(写指令0x34)--允许输入卷动地址指令(写指令0x03)--设置卷动地址(写指令0x40+地址)--回到基本指令(写指令0x30)。这里的地址需要注意:前面的比方是以行为最小单位来显示在屏幕上的。而实际上,是把行地址分成16小行,每一小行就是一行像素点(在前面也说过,可以认为一个地址管理着屏幕上16*16个像素点),而半屏中每行地址的16行像素点的编号是连续的,比如,在上半屏中,第一行地址的16行像素编号分别分别为0~15行,第二行地址的16行像素点编号就是16~31,而32~47指的是上半屏的第三行地址的16行像素编号,而不是下半屏的第一行的16行像素,这点要注意,而上半屏的第四行地址的16行像素编号就是48~63。同理,下半屏中第一行地址到第四行地址的行像素编号也为0~63,这里的编号就是上一段步骤中的地址。下面我也把编号称为地址。把某一行地址写入进去,对应的行就会显示在当前半屏的首行,而后面的行会整体跟着平移,而上半屏和下半屏的行地址都是一样的,都是0~63,所以此时下半屏也是同样的情况:对应的行显示在下半屏的首行,后面的行整体平移。所以这个设置卷动地址指令,实际上是同时给上下半屏设置相同的卷动地址的,只不过上下半屏各自卷动,互不干扰。另外要说明的是,地址0~63是循环的,什么意思?比如你把写入设置地址(0x40+63),把最后一行放在了首行,那么后面31行的内容呢?这时从第二行开始到最后一行地址分别是0~30,也就是63行地址后面跟着0行地址,这样的绕圈循环。下面讲述程序实现的思路:因为上下半屏原理一样,所以就以上半屏为例说明。首先,上半屏卷动模型图如下图所示:↓过路者↑第4页共7页如图,每一次向上卷动的单位为一行像素点,在开始卷动前将第一行地址、第二行地址、第三行地址写入字符,之后每卷动一行,往第四行地址写入一个字数据(也就是一个汉字),等卷完八行后,第四行地址已经写满八个字了,这时顶部第一行字符往上卷出了一半,底部第三行字符往上卷出了一半,这时上半屏第四行地址已经写满了八个字。然后还要卷动八行后才轮到第四行显示,那剩下的卷动八行的时间用来干什么呢?当然是把下半屏的第四行地址写满八个字啦。这样总共卷动了十六次后,上下半屏的第四行地址都写满了八个字,此时刚好轮到第四行字符从底部出来即将显示,并且此时第一行字符已经显示完毕了。此时,同理,每卷动一行往第一行地址写入一个字,这样卷动了十六次后,上下半屏的第一行地址都写满了将要显示的八个字。此时,第一行字符从底部出来即将显示,并且第二行字符已经显示完毕。此时每卷动一行,往第二行地址写入一个字,等到卷动了十六行后,上下半屏的第二行地址都写入了八个字,接着第二行字符从底部出来即将显示,此时第三行字符已经显示完毕。之后卷动时往上下半屏的第三行地址写入字......就这样,卷动了64次了,第一行到第四行字符已经全部卷动完毕了,并且第一行字符已经回到了上下半屏的顶部。然后执行新的一轮循环。下面是程序实现屏幕卷动显示一首诗:/*******************************************************************函数名:Roll()功能:测试12864的滚动效果参数:无返回值:无补充说明:1、要开启卷动,首先开启扩展指令集,然后允许卷动地址设置,再设置卷动地址。wrtcom_12864(0x34);//打开扩展指令↓过路者↑第5页共7页wrtcom_12864(0x03);//允许输入卷动地址wrtcom_12864(0x40+地址)//设置卷动地址wrtcom_12864(0x30);//回到基本指令卷动地址就是行地址,也就是垂直地址,从00到63*******************************************************************/voidRoll(){unsignedcharcode*poemstring[]={--月下独酌--,花间一壶酒,,独酌无相亲,,举杯邀明月,,对影成三人,,月既不解饮,,影徒随我身,,暂伴月将影,,行乐须及春,,我歌月徘徊,,我舞影零乱,,醒时同交欢,,醉后各分散,,永结无情游,,相期邈云汉.,----完----};uchari,j,row,rollflag=0;//rollflag用于标志滚动了多少行ucharrowaddr=0x80,flag=0;//flag用于标志写到了诗的那一行Write_Cmd(0x08);//设置显示、光标、闪烁全关。for(i=0;i2;i++)//此循环的作用是将诗词前四句诗写入屏
本文标题:学习笔记:LCD12864的卷动显示
链接地址:https://www.777doc.com/doc-5217369 .html