代码随笔——点阵汉字在LCD上的显示

代码随笔——点阵汉字在LCD上的显示

注:本文约在半年到一年前写的。

其实我以前从没想过写Framebuffer的代码,网上流传较多的是LCD的移植(主要改参数),之后没下文了。不过,曾经兴致冲冲地想搞Qtopia移植,在这过程中碰到过一个叫Tslib的东西。后来Qtopia没搞成功,倒研究起Tslib来了——对它的底层原理还没看明白,对于一些代码技巧及代码结构组织还是研究了一点。这个过程,与前几个月研究u-boot,一年前研究rtp以及曾经研究过的enc28j60等等代码很是相似。我这个有个毛病,喜欢研究些小东西,一些有意思的东西。比如说,人家移植u-boot,就是移植到开发板上,出结果就行了,而我,会去看看那些内存地址啊,看看里面的代码啊什么的。——不务正业,从这里可见一斑。

 

Tslib研究了一点点后,又对多通道的ADC感兴趣。经过查资料,发现网上也有很多人问怎么实现多通道采集数据,而且有些资料出奇的一致,都是转来转去的。我移植ADC驱动时是完全照抄别人的文章的,一般说来,ADC的移植跟TS的驱动差不多要一起搞,需要的文件有三个,其中一个是头文件,后来我才知道,那个头文件是“历史遗留”的,因此在2.4版本的内核中,ADC的驱动包括了read接口以及write接口,write函数就用到那个头文件的几个宏,里面的write接口正是多通道控制的关键——我们可以通过应用程序中调用write来指定哪一个通道,而这个应用程序也需要用到那个头文件的宏。但不知道怎么搞的,后来就把write给去掉了,而保留了头文件。或许有人觉得无需这样做。

当时我就一心地写个多通道的代码出来。于是搞了两种版本,一个是使用“正宗”的接口:ioctl——这个接口更名副其实一点,另一个是write接口。经过曾经,两种版本都是可行的。但是,由于内核版本变化实在太快,很多接口函数和宏定义都发生变化,因此有人问我怎么不能编译通过,怎么不能XXX,这些问题我也不知道,因为内核不是我开发的,我也没深入研究过驱动。另外,我最怕别人动不动就问人,连最基本的自学技能(若干年后,我们大家都会知道,无论在大学还是工作,自学才是王道)都不知道。我高中时候英语很好,经常有人问我单词,我都劝他们先查字典,字典的解释是最权威的,但很多人不听。因为有个大活人在,方便快速。到大学后期,我慢慢地不想说什么的,都以“不知道”为由,拒绝很多问题。假如直接给别人源代码,别人会问你程序是怎么运行的,里面代码是什么意思,老师问到该怎么回答,怎么改进这些东西,等等。其实我挺喜欢帮助别人的,别人的一句“谢谢”就能满足我的虚荣心。

 

后来,不知道怎么搞的,实然想在屏幕上显示汉字。于是乎,又去研究字库文件,研究别人的代码。我这个人比较笨,有些东西要慢慢地理解。比如说在屏幕上显示一个点阵汉字,我就从字库中找一个汉字,将那些十六进制数据一一改成二进制,再理解。当看到那些“1”组成了一个熟悉的汉字时,心情是非常激动的。当然,在研究区号、位号及汉字分布时,脑海中那些十六进制的知识又被复习了一遍。一开始是在Linux终端下使用printf打印的,但只能竖着打印,不能横着打印。我甚至想过要定位出坐标来,但是普通的C语言没这功能。后来某一天早上,实然看到自己买的一本关于ncurses编程的书,顿时大悟,何不用这个库来显示?这个库我很早就有耳闻了,只是现在应用场合不多(但在终端上,它具体非常强的优势),没去了解。后来一切似乎很顺利,显示完16点阵,再研究24点阵显示,研究完汉字显示,再研究中英混合显示,等等,似乎都很成功。当然前面所有这些都是在PC上模拟的,还没有真正在触摸屏上实现显示。不过,正是有了前面的基本知识,将那些东西搞到触摸屏上很简单。这个过程便是传说中的“移植”了,我只是简单修改了一下打印的函数。在PC上,可以用printf,可以用mwprintf,在LCD上就用画像素的函数。不过,有一个致命缺点:没有脱离Tslib的环境,而且就在ts_test.c文件中添加,因为我还没研究过auto tool(我已经下载了英文教程,还没看)。另外,对于Tslib画像素的流程还不了解。当然,经过自己的努力,最终还是能脱离了Tslib,形成自己独立的库文件。

 

这个过程也在不断修改自己的代码,由于自己对代码的优化研究不深,因此谈不上速度的优化,只是在代码组织上作了调整。不过我还是对比了一下移位和乘除的差别。另外,将英文字符存放在数组中,汉字则采用字库文件。其实我很早就注意代码的组织了,用现在很流行的话,就是很注意代码的复用、重构。这些习惯使得有些函数不用修改,直接能使用。

 

当显示出汉字时,觉得自己似乎也很成功,其时也不时注意周边的汉字字体,甚至还留意移动门口上方的点阵屏和公车的点阵屏。不过它们都是移动的,而我的是静止的。于是乎,又在想怎么让屏幕上的字也能移动。同样地,我也是先在PC上使用ncurses库来测试。在PC上测试没什么问题,可是到了屏幕上,就出现问题了:原来位置的像素还在,这样,汉字移动时,就看不清是什么字了。原来,我并没有清除屏幕。屏幕原来有什么,依然还有什么。到后来,找到一个ripple小项目,里面有与framebuffer相关操作的代码,于是就借鉴里面的代码(后来的代码都是在它的基础上修改添加的)。这才实现了清屏功能,或曰“刷新”。其它刷新很简单,就是将framebuffer所映射的某个内存(块)写0。在RGB中,全0是黑色。全F是白色。ripple项目原来的清屏函数是清除整个屏幕,后面我改进了一下,可以在指定行、列清除指定大小的屏幕。

你可能感兴趣的:(代码生活)