液晶显示屏(liquid crystal display,LCD) 因具有低功耗、体积小、重量轻、寿命长、显示信息量大、无闪烁等诸多特点,被广泛应用于各种显示领域。在通讯设备、家用电器、仪器仪表等产品中,其显示部件也越来越多采用了各种小尺寸的液晶显示模块(LCD Module,LCM)。液晶显示模块根据显示方式可分为段位型、字符型和点阵型三种。其中点阵液晶显示模块由于既能显示字符,又能显示各种图形,被广泛应用于对图文显示要求相对较高的场合中。在进行图形用户界面设计时,矩形、圆、椭圆等都是常用的图形元素,绘图时都可通过调用画点函数来实现。但对于单片机控制的小尺寸LCM 来说,当绘制的图形点数较多(如内部填充的图形),如采用画点函数来绘制每个点,运行速度会比较慢。如我们根据LCM 内部显示存储器结构特点对画竖线程序进行优化,采用优化的画竖线程序来绘制这些内部填充的基本图形,将可以大大提高程序的运行速度。本文将以STC90C52RC 单片机控制128(列)×64(行)点阵液晶显示模块(TG12864B)为例,根据LCM 的存储器结构特点,对其画竖线程序进行优化,并将它应用到绘制内部填充的矩形、圆、椭圆等基本图形中。
本文引用地址:http://driyadhasan.com/article/202205/434592.htm1 LCM与单片机接口电路设计
TG12864B 是广州同华公司生产的一款无字库的单色点阵液晶显示模块,控制芯片为SBN0064,支持68时序8 位并行总线,采用标准20 脚接口[1]。VDD、VSS为模块逻辑电路电源,VEE 是模块内部提供的液晶驱动电压,V0 是液晶对比度调节端,LED+、LED- 是背光电源。单片机STC90C52RC 通过I/O 方式读写控制TG12864B 液晶模块,见图1 所示。
2 LCM画竖线算法的实现与优化
我们采用的屏坐标系:TG12864B 屏的左上角为坐标原点(0,0),水平方向为x 轴,自左向右;垂直方向为y 轴,自上向下。TG12864B 屏上各点的亮灭由其内置的显示数据RAM(DDRAM) 控制。这DDRAM 的每一位数据对应屏上一个点的亮(数据为1)和暗(数据为0)。DDRAM 与页、列地址的对应关系如下表1所示。
CS1=1 时,DDRAM 的列地址0-63 对应左半屏的0-63 列;CS2=1 时,DDRAM 的列地址0-63 对应右半屏的0-63 列。DDRAM 的页地址为0-7,每页8 位,共64 位,分别对应着显示屏的0-63 行。用户可通过页地址和列地址按字节读写DDRAM。
2.1 画点程序
对点阵显示屏来说,点是一切图形的基础。对单色屏来说,对它的每个像素点只有三种操作:画点、擦除点、取反点(点由亮变暗,或由暗变亮)。根据LCM 内部的DDRAM 结构,我们在其屏幕上描画一个点,比如点(15,20),步骤如下:
(1)根据点的屏幕坐标(15,20),计算出它的DDRAM 地址:左半屏(CS1=1),DDRAM 列地址为15,页地址为2。
必威精装版app手机(2)读出该地址对应存储单元(1 字节)的数据。
(3)根据需要对该点的操作(画点、擦除点、取反点),对该字节数据的对应位(DB4 位)进行相应的处理,获得一个新的数据。
必威精装版app手机(4)将新数据写回原地址的DDRAM。按以上思路,用C 语言编写TG12864B 的画点函数如下。为了书写方便,我们重新定义无符号字符数据类型为uchar。程序中用到两个读、写DDRAM的底层函数,声明如下:
必威精装版app手机uchar ReadPosDat(uchar page,uchar col);
必威精装版app手机// 读DDRAM page 页,col 列的一字节数据, 并返回void WritePosDat(uchar page,uchar col,uchar dat);
必威精装版app手机// 将一字节数据dat 写到DDRAM page 页,col 列
/**************************************************
参数:屏幕像素坐标(x,y),列x(0-127),行y(0-63)
type=0: 该点填充0,擦除点
type=1: 该点填充1,画点
必威精装版app手机type=2: 该点取反 ,取反点
必威精装版app手机**************************************************/
void draw_point(uchar x,uchar y,uchar type){ uchar dat,page;
page=y>>3;// 计算页地址dat=ReadPosDat(page,x);// 读出对应DDRAM 单元switch(type) // 修改对应位
{
必威精装版app手机case 0:dat &=(~(1<<(y%8)));break; //擦除
case 1:dat |=(1<<(y%8));break; // 画点
case 2:dat ^=(1<<(y%8));break; // 取反
}
必威精装版app手机WritePosDat(page,x,dat);// 写回修改数据
}
2.2 传统的画竖线程序
直线由点构成。给出竖线的起点和终点坐标,根据前面的画点函数便可逐点画出竖线,其C语言程序如下:
/**************************************************
画竖线函数( 利用画点函数)
必威精装版app手机参数:type=0, 擦除;type=1, 画线;type=2,取反x 为水平坐标值,y0,y1 为起点和终点的垂直坐标值
**************************************************/
必威精装版app手机void draw_vline(uchar x,uchar y0, uchar y1,uchartype)
必威精装版app手机{// 数据调整, 使y1>=y0 uchar temp
;if(y0>y1)
{
temp=y1;
y1=y0;
y0=temp;
}
do // 从上到下逐点显示
{
draw_point(x,y0,type);// 调用画点函数
y0++;
必威精装版app手机} while(y1>=y0);
}
2.3 画竖线程序的优化
必威精装版app手机根据表1 DDRAM 与屏幕显示位置的关系, 由DDRAM 页地址和列地址确定的1 个字节单元对应着屏幕的Y 轴方向的8 个像素点。在我们上面传统的画竖线程序中,采用逐点描画竖线,对同一个DDRAM 字节对应的点,也需要重复的操作8 次:重复读同一个DDRAM 字节8 次,计算该字节上对应位8 次,回写该字节8 次。显然,这是一个巨大的冗余。其实,根据DDRAM 的结构特点,在画竖线时,我们通过读、修改、写DDRAM 1 个字节1 次,就可直接描画出竖线上的8个点。而且,在进行画线或擦除线操行时,除了竖线的起点和终点所在DDRAM 字节,我们需要进行读、修改、写操作,竖线经过的中间字节,我们直接写入全1 或全0 就可以了,这将大大提高程序的运行速度。基于以上思想,我们对画竖线程序进行优化,其C 语言程序如下:
/*************************************************
必威精装版app手机优化的画竖线函数
必威精装版app手机参数:type=0, 擦除;type=1, 画线;type=2,取反x 为水平坐标值,y0,y1 为起始和终点的垂直坐标值
必威精装版app手机**************************************************/
uchar code up_page[]={0xff,0xfe,0xfc,0xf8,0xf0,0xe0,
0xc0,0x80};
必威精装版app手机// 起点字节控制码,控制起点以下各点
uchar code down_page[]={0x01,0x03,0x07,0x0f,0x1f,
0x3f,0x7f,0xff};
必威精装版app手机// 终点字节控制码,控制终点以上各点
必威精装版app手机void imp_vline(uchar x,uchar y0, uchar y1,uchar type)
{// 数据调整,使y1>=y0
uchar temp,y0_page,y1_page;
if(y0>y1)
{ temp=y1;
y1=y0;
y0=temp;
}
必威精装版app手机y0_page=y0>>3;// 计算y0 所在页
必威精装版app手机y1_page=y1>>3;// 计算y1 所在页
if(y0_page==y1_page) //y0、y1 在同一页{ temp=ReadPosDat(y0_page,x);// 读起点对应DDRAM字节
switch(type)// 修改该字节
{ case 0:// 擦除
temp =~(up_page[y0%8] & down_page[y1%8]);
temp &=ReadPosDat(y0_page,x);
break;
必威精装版app手机case 1:// 画线
temp =up_page[y0%8] &down_page[y1%8];
temp | =ReadPosDat(y0_page,x);
break;
必威精装版app手机case 2: // 取反
temp =up_page[y0%8] & down_page[y1%8];
temp ^=ReadPosDat(y0_
page,x);
break;
}
WritePosDat(y0_page,x,temp);// 回写该字节
}
必威精装版app手机else //y0、y1 不在同一页
{ temp=ReadPosDat(y0_page,x); // 读起点字节
必威精装版app手机switch(type)// 修改起点字节
{ case 0:temp &=(~up_page[y0%8]);break;
case 1:temp |=up_page[y0%8];break;
case 2:temp ^=up_page[y0%8];break;
}
WritePosDat(y0_page,x,temp);// 回写起点字节
必威精装版app手机for(y0_page++;y0_page<y1_page;y0_page++)
// 写中间字节
{ switch(type)
{case 0:WritePosDat(y0_page,x,0); break; //
直接写0
case 1:WritePosDat(y0_page,x,0xff);break;//
直接写0xff
必威精装版app手机case 2:temp=ReadPosDat(y0_page,x); // 读
改写
temp ^=0xff;
WritePosDat(y0_page,x,temp);
break;
}
}
temp=ReadPosDat(y1_page,x); // 读、改写最
后字节
必威精装版app手机switch(type)
必威精装版app手机{case 0:temp &=(~down_page[y1%8]);break;
case 1:temp |=down_page[y1%8];break;
case 2:temp ^=down_page[y1%8];break;
}
必威精装版app手机WritePosDat(y1_page,x,temp);
}
}
2.4 画竖线程序的测试
必威精装版app手机对这两种画竖线函数,输入各种不同的运行参数(uchar x,uchar y0, uchar y1,uchar type),测量它们的运行效果和时间。
运行时间测试方法:采用电路中的STC90C52RC单片机(外接晶振12MHz)的定时器T0 进行检测,设置T0 为16 位定时模式,一次定时50 ms,采用中断方式工作。50 ms 以上的时间,通过统计中断次数计算获得,50 ms 以内的时间,通过读取定时器的计数寄存器TH0、TL0 获得。经过运行测试,两种画竖线函数均能正确画出相应的竖线,运行时间如表2 所示。
在以上三组测试数据中,传统的画竖线程序的运时间分别是优化的画竖线程序的5.7 倍、11.5 倍和9.1 倍,优化效果显著。
3 画竖线程序在图形填充中的应用
在进行图形用户界面设计时,矩形、圆、椭圆等都是常用的基本图形元素。采用优化的画竖线程序来绘制这些内部填充的基本图形,相比直接采用画点函数(种子填充法、扫描线填充法[2])或基于画点函数的传统画竖线程序,可以大幅地提高程序的运行速度。
3.1 画填充矩形
给出矩形的左上角点和右下角点坐标,根据上面的画竖线函数,便可从左到右逐根竖线地绘制出填充的矩形,其C 语言程序如下:
/*************************************************
画填充矩形函数
必威精装版app手机参数:x0、y0 为矩形左上角点坐标
x1、y1 为矩形右下角点坐标
必威精装版app手机type=0,填充0;type=1,填充1;type=2,
取反
**************************************************/
void draw_rectangle_fill(uchar x0,uchar y0,uchar x1,uchar y1,uchar type)
{ while(x0 <= x1)// 画填充矩形
必威精装版app手机{ imp_vline(x0,y0,y1,type);
x0 ++;
}
}
对调用传统的画竖线函数实现的填充矩形函数和调用优化的画竖线函数实现的填充矩形函数,输入各种不同的运行参数(uchar x0,uchar y0,uchar x1,uchar y1,uchar type),测量它们的运行效果和时间。经过运行测试,两种画填充矩形函数均能正确画出相应的矩形,运行时间如表3 所示。
在以上三组测试数据中,采用传统画竖线函数的填充矩形程序的运行时间分别是采用优化画竖线函数的填充矩形程序的9.3 倍、10.0 倍、9.1 倍,优化效果显著。
3.2 画填充椭圆
根据中点生成椭圆的整数型算法[3],可计算出椭圆圆心在坐标原点的标准椭圆在第一象限上的1/4 椭圆弧的各点坐标。再由椭圆关于X 轴和Y 轴的对称性,便可得到其在另外3 个象限的椭圆弧坐标。经过平移,就可得到椭圆圆心在任意位置的椭圆弧各点坐标。以椭圆弧关于过椭圆圆心的水平线对称的每一对点为端点画竖线,便能画出内部填充的椭圆。
对调用传统的画竖线函数实现的填充椭圆函数和调用优化的画竖线函数实现的填充椭圆函数,输入各种不同的运行参数(uchar x0,uchar y0,uchar a,uchar b,uchar type) ,(x0,y0)为椭圆圆心坐标,a 为椭圆长半轴,b 为椭圆短半轴。测量它们的运行效果和时间。经过运行测试,两种画填充椭圆函数均能正确画出相应的椭圆,运行时间如表4 所示。
在以上三组测试数据中,采用传统画竖线函数的填充椭圆程序的运行时间分别是采用优化画竖线函数的填充椭圆程序的7.8 倍、10.0 倍、6.1 倍,优化效果显著。
5 结论
本文以SBN0064 控制的点阵液晶模块TG12864B为例,根据LCM 内部显示存储器结构,对画竖线程序进行优化,在绘制竖线、填充矩形、圆形、椭圆等常用基本图形时,可以大幅度地提高程序的运行速度,具有较强的实用价值。以上结论,亦适用于其它采用SBN0064 或其兼容芯片( 如KS0108、S6B0108、HD61202 等)控制的12864 点阵液晶模块。而对采用ST7920 或其兼容芯片控制的带中文字库的点阵液晶模块,则可根据其内部GDRAM 结构,对画横线程序进行优化。
参考文献:
必威精装版app手机[1] 广州同华实业有限公司.TG12864B-01使用说明书[EB/OL].[2021-10].http://gb.tinsharp.com.
必威精装版app手机[2] 郭晓新,徐长青,杨瀛涛.计算机图形学[M].3版.北京:机械工业出版社,2017:25-28.
[3] 张博,周丽韫,李兴霞.中点生成椭圆的整数型算法[J].工程图学学报,2011,32(1):1-4.
[4] 谭浩强.C程序设计[M].5版.北京:清华大学出版社,2017.
(本文来源于《电子产品世界》杂志2022年5月期)
评论