在单片机的开发设计中,人机界面常常需要用到。这里本人总结了一些基于单片机的对单色点阵型液晶的经验。也许对各位同仁有点帮助,如有什么不对之处,还请各位同仁提出,学习快乐!
本人这里是以128*64的LCD(ks0108控制器,6800的时序)为例子来介绍的。
图1
如上图是128*64LCD的显示区示意图。液晶显示区上的每个点都对应着控制器内部显示缓存区RAM中的一个位。对于读写RAM的最小单位应该是字节(byte),即读写是以字节为单位的。整个显示区是被分为了8个PAGE(页),每个页中有128列,即128个byte。可见1个PAGE中有128*8个像素点。对于有的液晶把整个显示区分为了左右俩边。其对应着有要有两个片选CS1,CS2。其原理与上图是一样的。把其当成两个64*64的组合在一起就行。
下面是个显示区与显示RAM的像素点映射图。
显然要想打亮液晶上的某个像素点,把其对应的显示RAM的值置1即可。其实在液晶上显示的字符就是这么一个个的点组合而成的。
下面要解决的问题是如何利用液晶控制器来进行显示区的收放自如的控制。也就是说编写驱动程序来让任意某点打亮。这就要对控制器中的一些相关的寄存器进行操作。必然这要涉及到时序的问题。本人这里主要讲比较典型的6800时序的LCD,液晶的DATASHEET中一般给出了其相关控制器的时序图。一般我们都是用I/O口来模拟其时序。比较简单这里就不分析其时序了。其读写数据和寄存器的时序驱动代码一般如下:
写命令到寄存器:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
从寄存器中读数据(注意哦:有些廉价的液晶中数据读不出来):
写数据到寄存器:
看着上面的代码,将其与具体的时序图相对就很容易理解了。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
一般的LCD模块,都有显示区开、关,设置起始页地址,设置列地址等的寄存器操作。有的比较好的LCD则有更多的更方便的寄存器操作,如正/反向显示设置,全屏点黑等。
下面就以显示一个16*16大小的汉字的函数来讲解一下如何用字模提取工具来做汉字的显示。前面已经提到了,在LCD上显示字符,其实就是把字符在其上用一个个的像素点组合的画出来。当然这样的事情一般是由字模提取软件来实现的。字模提取软件有很多,网上到处有下。
上图就是一个字模提取软件的界面了。把自己想要的字符输入,即可得到其相应的字模数据。字模提取时特别要注意取模是横向还是纵向的,字节是正序还是倒序。前面说过(图1),把要显示的数据写入LCD的数据RAM中是以字节(8个位点)为单位来写的。纵向还是横向是指以纵的8个位点,还是以横的8个位点为单位来记录数据。下面俩副图很好的表示了俩者的区别。这个取模的方式在取模软件中可以设置,根据自己的LCD的显示方式来确定取模的方式即可。我这里的LCD是纵向显示的,所以我的取摸软件是设置为纵向取摸。至于字节正序与倒序,是指这8个位点组成一个字节数据的方向,在字节全些完的情况下这个无关紧要。
本人用纵向取摸字节倒序的方式提取出16*16大小的“捷”字的数据如下,这是用一个一唯数组来存放的。
/*------------------------------------------------------------------------------
源文件 / 文字 : 捷
宽×高(像素): 16×16
------------------------------------------------------------------------------*/
Jie[]={
0x18,0x18,0xFF,0xFF,0x98,0x06,0x56,0x56,0x56,0xFF,0xFF,0x56,0xF6,0xF6,0x46,0x00,
0x03,0x63,0x7F,0x3F,0x41,0x60,0x3D,0x1D,0x31,0x3F,0x7F,0x65,0x65,0x65,0x60,0x00
};
显然0x18就是字模图中从左边起的第一列(8位),这样一列列的从左至右16列的数据就列了出来。接着从0x03开始列出了下一行的16列,这样32字节数据就保存在了数组中。
下面来看把它写入LCD RAM中(也就是让它显示出来)的代码。
void hz_disp16(unsigned char pag,unsigned char col, unsigned char code *hzk)
{
unsigned char j="0",i=0;
for(j=0;j<2;j++)
{
write_com(Page_Add+pag+j);//写命令到寄存器,确定起始页地址
write_com(Col_Add+col); //写命令到寄存器,确定起始列地址
for(i=0;i<16;i++)
write_data(hzk[16*j+i]); //把数据一个一个字节的写入
}
}
Pag ,col,分别是指要显示的坐标的页地址和列地址。*hzk就是存放字符数据的数组的首地址。代码中用了俩重循环来把数据写入,先把第一行的16个数据连续写入一页接着借用变量J使显示的数据换了一页,跳到了其下一页,这样又把16个数据连续写入,上下俩页组合起来1个“捷”字就显示到了屏幕上了,就如字模提取工具中的一样!对于128*64的LCD,若想在第2行第5列开始显示一个“捷”字,在代码中这样调用上面那个函数即可:
hz_disp16(2,5,jie);
上面这种显示方法其实是一种比较笨的显示发,他不能显示任意大小的字符(长宽必须是8的整数倍),且不能在任意点显示。其实只要解决在任意坐标显示一个点的函数,即可很灵活的用显示点的函数来构成在任意坐标显示任意大小的字符的函数。时间不早了,明天继续。。。。。。。。。。。。。。。。。。。。。。。。。。。。
用户1825482 2015-1-6 22:13
用户169648 2009-5-25 09:34
用户461316 2008-8-18 08:29
用户1708619 2008-8-16 10:44
用户161601 2008-8-15 08:37
用户1453845 2008-8-14 22:19