基于液晶模块的动态曲线显示设计
扫描二维码
随时随地手机看文章
摘要: 以中文液晶显示模块CM320240-7为例, 给出了使用LCD显示模块CM320240-7来实现文本、图形和实时曲线显示的系统设计方法。
0 引言
为了提高显示程序的可读性和可维护性, 软件程序通常采用C语言来编写。从总体上说, 液晶显示软件的编程主要分为主程序、液晶显示模块、键盘输入模块和通信模块等。其中主程序主要完成初始化、键盘扫描等; 键盘输入模块主要完成各功能键的按键响应; 液晶模块主要完成菜单界面的切换显示; 通信模块主要实现数据的接收与发送。本文重点介绍液晶显示部分的内容。
液晶显示的内容主要是一些用户关心的实时参数和状态, 其基本操作流程为: 初始化、清屏、显示。初始化主要是复位液晶, 等待对液晶进行操作; 清屏主要是清除掉液晶屏上所显示的内容, 为下一次显示的内容做准备; 显示主要是显示当前想要显示的内容。
1 中文液晶显示模块CM320240-7
中文液晶显示模块CM320240-7是一个中英文文字与绘图模式的点矩阵液晶显示模块, 其内建有12Kbyte的ROM字型码, 可以显示中文字型,数字符号, 英日欧文等字母。同时, 该模块还内建双图层的显示内存, 可支持文字与绘图两种混合显示模式。并可提供全角(16×16) 与半角(×8)文字显示模式。CM320240-7的最大特点就是在强光照射下, 用户依然可以清晰地看到屏幕上显示的内容, 因而非常适合在户外使用。
CM320240-7可以很方便地与ARM9相连接。它具有24个管脚, 其中有8位数据线(DB0~DB7),6 位控制线(RS-数据/命令控制, WR-读写控制,CS2-片选2, CS1-片选1, EN-使能端, /RST-复位端, ) , 4 位电源线( AVSS, AVDD, VSS,VDD), 2位状态线(BUSY-用以回应模块内部的执行使用状况, INT-用以回应模块内部的中断状况), 同时包括背光源正、负端(LED+、LED-),LCD驱动电源输入端和输出端(V0、VEE)。
2 字符和汉字的显示
对于点阵液晶显示器来说, 汉显菜单的设计就是如何通过编程将汉字按一定的格式在屏幕上显示出来。
在LCD上显示字符和汉字之前, 通常都需要先提取点阵码。由于要显示的汉字和字符非常多, 而且它们是任意的, 因而必须要有常用的字符和汉字字库。由于ASCⅡ字符字库比较小, 一般的字模软件就可以生成, 故笔者使用的软件是任意点阵字体生成器, 其操作界面如图1所示。
图1 任意点阵字体生成器的操作界面
任意点阵字体生成器软件界面风格简洁, 操作简便。常用汉字和字符的ASCⅡ码保存在以.dat为后缀的文件里。故以打开文件的方式就可取得汉字和字符的ASCⅡ码, 其操作语句如下:
fp_ST_16_08_ASC =fopen ( " /mnt/Nand1/ST_16_08_ASC.Dat" ," r")
有关在文本和图形显示方式下写入字符和汉字的方法, 在与显示有关的相关资料中已经介绍得很清楚。这里给出的是一个在本程序中用到的显示汉字的函数。通过这个函数, 可以将想要显示的任意汉字和字符显示在液晶屏幕的任意位置上。具体如下:
static void HanZi ( U32 x, U8 y, U8 *data, U8size, U8 reverse_log)
其中, x为横坐标, y为纵坐标, *data为数据内容, size为字体, reverse_log为反白标记。
3 图形曲线的显示
3.1 描点
对屏幕上每一个点进行绘制是绘图的基本条件。在用液晶显示器显示图形曲线时, 首先要给屏幕上的每一个点分配一个二维的坐标。对于CM320240-7所用的320×240点阵液晶, 其左上角第一个点的坐标为(0, 0), 右下角最后一个点的坐标为(319, 239)。这样, 根据二维坐标就可以计算出各点所对应的内存单元, 并给其赋值“1”。而中文液晶显示模块在显示图形的时候,一般是以字符映像(Bit Map) 的方式写入RAM,若RAM的某个位置被填满为“1”, 其LCD面板相对应的位置就会被显示出黑点。因此, 在RAM上所存储的像素资料, 就会对应到显示屏幕(LCD)上, 从而构成文字、符号或图形等显示效果。为了便于运算, 可将每8个点的状态存放在一个字节的内存单元中, 图2给出了显示数据从RAM到LCD显示的映射方式。由此可见, 全屏的320×240个点的状态将存放在(320 / 8) ×240=40×240个字节的内存单元中。
图2 显示数据从RAM到LCD显示的映射方式
填充某一矩形区域的函数为Box_full (U16x_1, U16 y_1, U16 x_2, U16 y_2) , 其中,(x_1, y_1), (x_2, y_2) 为所填充的矩形区域的左上角和右下角的坐标。描一个点就相当于填充一个点阵区域。
清除某矩形区域的函数为Box_eraser (U16x_1, U16 y_1, U16 x_2, U16 y_2) , 其中,(x_1, y_1), (x_2, y_2) 分别为所清除的矩形区域的左上角和右下角的坐标。消除一个点即清除一个点阵区域。通过这个函数可以很方便地清空某个矩形区域的内容, 例如清除图形区域, 或清除需要改变的数据区域等。
3.2 画线
曲线可以视为是由若干直线段首尾相连而成。绘制直线是绘制曲线的基础, 所以首先考虑直线的绘制方法。一般的斜线段也可以看作是由若干水平或垂直的线段首尾连接而成的, 而对于水平直线和垂直直线这两种特殊情况, 则相当于填充某矩形区域, 这可以用前面提到的Box_full() 函数来完成。因此, 曲线的绘制全部都可以转换为直线的绘制, 而其关键就在于确定各个水平或垂直线段首尾两个端点的坐标。下面将重点介绍绘制直线的算法。
处理曲线段首尾两个端点的方法相对比较简单, 即每个端点都沿X轴正向绘制2个相同Y值的像素点, Y为当前点所对应的纵坐标。对于两端点之间剩余的3个像素点, 可分以下三种情况进行讨论。
首先, 当y_0等于y_past时, 很显然, 两端点之间是一条水平线, 其线形如图3 (1) 所示。其函数描述为: Box_full (x_0-3,y_0,x_0+1,y_0)。
图3 几种情况下线段的绘制情形
其次, 如果y_0大于y_past, 此时将分为以下4种情况进行讨论:
第一, 当y_0-y_past=1时, 其情形如图3 (2)所示。其函数描述为:
Box_full (x_0-1,y_0,x_0+1,y_0) ;
Box_full (x_0-3,y_past,x_0-2,y_past) ;
第二, 当y_0-y_past=2时, 其情况如图3 (3)所示。函数描述为:
Box_full (x_0,y_0,x_0+1,y_0) ;
Box_full (x_0-3,y_0+1,x_0-1,y_0+1) ;
第三, 当y_0-y_past=3时, 其情况如图3 (4)所示。函数描述为:
Box_full (x_0-1,y_0+1,x_0-1,y_0+1) ;
Box_full ( x_0 -3,y_past -1,x_0 -2,y_past -1) ;
Box_full (x_0,y_0,x_0+1,y_0) ;
第四, 当y_0-y_past=4时, 其情况如图3 (5)和(6) 所示。函数描述为:
Box_full (x_0,y_0,x_0+1,y_0) ;
Box_full (x_0-1,y_0+1,x_0-1,y_0+1) ;
Box_full ( x_0 -3,y_past -1,x_0 -3,y_past -1) ;
Box_full (x_0-2,y_0+2,x_0-2,y_past-2) ;
而当y_0小于y_past时, 其分析方法与y_0大于y_past时相似, 这里不再重复。
3.3 动态曲线的显示
图4所示是实现动态曲线显示的显示界面。
图4 动态曲线的界面显示
实际上, 该界面可划分为以下3种显示区域: 文本区、数字区、图形区。文本区是指图中的文字部分, 用于说明和提示; 数字区是指图中的数字部分, 用于显示一些实时的数据, 例如时间、直流值、交流值、存储器容量等; 图形区则是指界面中间显示波形的部分, 主要用于显示实时动态波形。
在确定实时曲线点地址时, 其二维坐标的任意一点都是由横坐标和纵坐标来确定的。对于横坐标, 它们是一组等间隔的整数, 因此, 每画完当前一个点后, 再在其水平坐标加上某一固定的整数, 即可得到下一个要画的点的水平坐标。例如, 若横坐标间隔为5, 则横坐标X就依次加5。
对于纵坐标则相对复杂些, 假设A/D转换后得到的数据为y, Y为所求点在动态显示区中所在的行, 横轴所在的行为H, 则Y=H- (int) (y×20)。
20实际上是为了方便运算而取的一个幅值, 该值可以根据不同的数据情况来设定其大小。
为了在液晶屏幕上实时动态地显示曲线, 刷新是一个很重要的环节。传统的刷新方法是不断地刷新每个显示单元。显示的控制过程实际上就是对图形区RAM 数据的控制过程, 从左到右按单位扫描时间逐一置动态图形区RAM 中的显示数据, 直到扫描到LCD 最右边时, 再清除所有动态图形区RAM的数据, 之后, 又按单位扫描时间从左到右继续逐一置动态图形区RAM 中的显示数据, 并以逐点显示方式来实现整幅图形的刷新。由于图形显示数据的运算量大、读写次数较多, 液晶屏的读操作要连续进行两次, 第一次读操作将地址输出读到一个无效数据, 第二次读操作才读到有效数据。所以, 用这种方法实现的显示会感到刷新不及时、视觉效果较差。本文采用静态随机存取存储器(SRAM) 的映射方式, 即在(SRAM) 中开辟一个与液晶屏动态图形变化区域相同容量的存储区域, 并使图形的刷新全部在(SRAM) 中进行, 然后重新写屏。由于采用的是相同的地址指针, 从而减少了ARM地址指针切换所带来的延迟, 这样就使得图形曲线更新的动态性能大大提高。除此之外, 本文还采用了指定有变化的部分刷新的方法, 即让没有变化的部分保留原样, 而不采取任何操作, 只改变有变化的部分。因此, 刷新的效率也大大地提高了。刷新操作的具体程序如下:
对于波形动态显示的效果, 现假设一整屏波形显示56个数据, 那么第一屏应依次描点, 即从X轴最左边起, 一个单位时间描一个点且描一个点刷新一次。当第一屏描满, 即56个点全部描完时, 图形区域将显示一个完整的波形。之后从第二屏开始, 将一次性显示满屏的56个点, 然后再刷新。其中第56个点, 即最新的点显示在图形区域的最右边, 它的纵坐标是最新读到的数据转换值。左边的55个点的纵坐标是之前显示的旧的55个点的纵坐标。之后, 绘制每一屏的方法都与绘制第二屏的相同。通过这种方法, 波形将呈现不断往前平移的效果, 从而实现一个连续波形的动态显示。
4 结束语
本文所讨论的液晶显示应用技术的实现方法, 已在工程实践中表明是可行的, 并且运行比较稳定。