3484|1

167

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

OLED_12896_GR_Lib函数(二)——_PSET及PSET函数的实现 [复制链接]

前面已经定好函数构架了,下面就从最基本的函数开始实现,首先是画点函数。即_PSET函数和PSET函数。
不过在绘制图像前还有一个十分重要的问题需要解决,那就是我们的显示缓冲区该定义为多大呢?这当然要根据显示的模式来确定,函数中用一个宏定义Color_Mode来确定采用哪种显示模式。当Color_Mode不为0时表示使用灰度显示模式,当Color_Mode为0时表示采用黑白显示模式,即像素的亮度只能为0和0xF中的一个。
显示模式定义及缓冲区数组定义语句如下:
#define Color_Mode   0

#if Color_Mode
 unsigned char Display_Buf[64][96];
 unsigned char Data_Mask[]={0x0f,0xf0};
#else
 unsigned char Display_Buf[16][96];
#endif

用户在使用函数之前先修改Color_Mode的值为自己需要的显示模式代表值,然后程序会用条件编译来定义所需要的数组大小。在程序中,不同显示模式的语句均采用条件编译来进行,程序运行中不再做显示模式判断,以减小代码量。
在灰度显示模式中由于要对半字节进行修改,所以定义了两个字节掩码Data_Mask来对不用的数据位加以保护。
一、PSET函数的实现
在前面的基本结构里面已经说了,_PSET函数是基本的画点函数,PSET是调用_PSET函数来实现画点功能的,为什么不先介绍基本的_PSET函数呢,这是由于PSET函数不是用简单的一句调用语句来实现这个功能的,在PSET函数里面,首先对灰度数据做了一个预处理,然后才交给_PSET函数来实现这个功能的。为了方便大家理解,我就按照程序语句的执行顺序来介绍。
PSET函数如下:
void PSET(unsigned char x,unsigned char y,unsigned char color)
{
if ((x>127)||(y>95)) return;
if (color>0x0f) color &=0x0f;
#if Color_Mode
 color = (color<<4) + color;
#else
 color >>=3;
#endif
_PSET(x,y,color);
P_Cursor_X=x,P_Cursor_Y=y;
}
该函数共有三个参数,x,y和color,其中x,y为该点的横坐标和纵坐标。Color为该点的灰度数据。x,y的取值范围分别是0~127和0~95,Color的取值范围在灰度模式下为0~0x0F,在黑白显示模式下为{0x00,0x0F}。不过由于color值的特殊性,对其采取了一系列的措施,使得可以使用该范围以外的值。即对于大于0x0F的值,只取低四位。在黑白显示模式下,取值范围也为0x0~0x0F,但是大于0x07的值都被认为0x0F,小于等于0x07的值都被认为0x00,方便灰度图形模式向黑白图形模式移植。
在该函数中,对color参数做了一些处理。具体为:
在灰度模式下,将低四位数据复制到高四位。这样,在_PSET函数中,用掩码进行一次覆盖即可在需要的位置得到需要的灰度数据。
在黑白模式下,将数据右移三位,则只有最高位有效,完成了将灰度数据黑白化的界定。
在处理完color参数后,即可调用_PSET完成该点的绘制并将图形光标置于当前点,完成该函数的功能。
二、_PSET函数的实现
处理完color数据后,程序就要进入该功能的重头戏_PSET函数了,在这里将完成读取缓冲区当前颜色状态,处理缓冲区数据及将数据写入OLED显示器等操作。在这里也是根据Color_Mode状态来分别完成相应状态的图形绘制的。
灰度显示模式:
在灰度显示模式下的代码如下:
 HarfByte=x & 0x01;
 ByteX=x>>1;
 Display_Buf[ByteX][y]&=Data_Mask[HarfByte];
 color =color & (~Data_Mask[HarfByte]);
 Display_Buf[ByteX][y]|=color;
 color=Display_Buf[ByteX][y];
 pucCommand[0]=0x15;
 pucCommand[1]=ByteX;
 pucCommand[2]=63;
 RITWriteCommand(pucCommand, 3);
 pucCommand[0]=0x75;
 pucCommand[1]=y;
 pucCommand[2]=95;
 RITWriteCommand(pucCommand, 3);
 RITWriteData(&color, 1);
在这里,HarfByte变量用来指示当前修改的值在字节中的位置,低半字节、高半字节(灰度显示模式)或者某一位(黑白显示模式),ByteX则为当前像素在显示内存缓冲区数据中的横坐标。
在灰度模式下,将该点的横坐标高7位全部屏蔽掉,只留最低位,如果该位为0,则表示当前点在显示缓冲区中某一字节的低位,如果为1 则表示其在某一字节的高位。
由于在灰度显示模式下,一个字节控制横向相邻两个像素,所以,将横坐标整除2即可得出当前坐标所处的字节在显示缓冲区中的横坐标位置。
确定所要修改的数据后,取出该数据,将要修改的位清零;同时将灰度数据中的无用位清零。最后将两个数据进行或操作即可拼接在一起,完成所需要像素灰度的修改工作。
完成后将缓冲区中修改的数据写入OLED显示器即可完成该点的绘制操作。具体写入操作可参考TI官方的OLED例程。
黑白显示模式:
黑白显示模式下的代码如下:
 unsigned char TempColor;
 HarfByte=x & 0x07;
 ByteX=x>>3;
 TempColor=1<<HarfByte;
 if (color) Display_Buf[ByteX][y]|=TempColor;
 else Display_Buf[ByteX][y]&=(~TempColor);
 HarfByte &=0x06;
 TempColor=Display_Buf[ByteX][y]>>HarfByte;
 TempColor&=0x03;
 TempColor=(TempColor>>1)*0xf0+(TempColor&0x01)*0x0f;
 pucCommand[0]=0x15;
 pucCommand[1]=(ByteX<<2)+(HarfByte>1);
 pucCommand[2]=63;
 RITWriteCommand(pucCommand, 3);
 pucCommand[0]=0x75;
 pucCommand[1]=y;
 pucCommand[2]=95;
 RITWriteCommand(pucCommand, 3);
 RITWriteData(&TempColor, 1);
在这里由于要根据参数color的不同在相应位置写入1或者0(不影响其他位),所以引入了一个TempColor用来存放待处理的颜色数据。
HarfByte变量和ByteX变量的意义和灰度模式下的一样,不过在此由于一个数据控制8个像素,所以像素在字节中的位置为0~7,而内存缓冲区横坐标和像素横坐标变成了8倍的关系。所以对这两个变量的操作变成了对低三位进行操作。
根据HarfByte变量确定当前像素在字节中的位置,然后将TempColor中相应位置1。
根据color来确定要在该位写入的数据。如果要写入1,则将TempColor和当前数据进行或操作,其他位为0,所以不影响其他位。如果要写入0,则将TempColor取反后与当前数据进行与操作,此时其他位变成了1,与操作时也不影响其他位。
对缓冲区数据操作完成后就要将缓冲区的像素反应到显示器上了。在黑白模式下,缓冲区中一个字节表示8个像素,与显示器中的一个字节表示两个像素不一致,还需要将其中需要进行修改的两位扩展为8位后才能写入。
为了操作上的统一,这里先将需要修改的数据位移动到最低位来进行操作。由于缓冲区中的数据位两位为一个单位(表示OLED内存中的一个字节),所以这里的移位操作也应该是2的倍数。将ByteX最低位屏蔽就可以保证为偶数,即为当前需要移动的位数。
将需要修改的位移动到最低位后屏蔽高6位,根据最低两位的值分别设置字节的高低四位。计算方式为: TempColor=(TempColor>>1)*0xf0+(TempColor&0x01)*0x0f;
然后跟上面灰度模式下一样,将该数据写入OLED显示器完成该点的绘制。
综上,_PSET函数的完整代码如下:
__inline static void _PSET(unsigned char x,unsigned char y,unsigned char color)
{
unsigned char HarfByte,ByteX,pucCommand[3];
#if Color_Mode
 HarfByte=x & 0x01;
 ByteX=x>>1;
 Display_Buf[ByteX][y]&=Data_Mask[HarfByte];
 color =color & (~Data_Mask[HarfByte]);
 Display_Buf[ByteX][y]|=color;
 color=Display_Buf[ByteX][y];
 pucCommand[0]=0x15;
 pucCommand[1]=ByteX;
 pucCommand[2]=63;
 RITWriteCommand(pucCommand, 3);
 pucCommand[0]=0x75;
 pucCommand[1]=y;
 pucCommand[2]=95;
 RITWriteCommand(pucCommand, 3);
 RITWriteData(&color, 1);
#else
 unsigned char TempColor;
 HarfByte=x & 0x07;
 ByteX=x>>3;
 TempColor=1<<HarfByte;
 if (color) Display_Buf[ByteX][y]|=TempColor;
 else Display_Buf[ByteX][y]&=(~TempColor);
 HarfByte &=0x06;
 TempColor=Display_Buf[ByteX][y]>>HarfByte;
 TempColor&=0x03;
 TempColor=(TempColor>>1)*0xf0+(TempColor&0x01)*0x0f;
 pucCommand[0]=0x15;
 pucCommand[1]=(ByteX<<2)+(HarfByte>1);
 pucCommand[2]=63;
 RITWriteCommand(pucCommand, 3);
 pucCommand[0]=0x75;
 pucCommand[1]=y;
 pucCommand[2]=95;
 RITWriteCommand(pucCommand, 3);
 RITWriteData(&TempColor, 1);
#endif
}
测试程序包可以在下面下载,测试程序用描点的方式绘制了两条从左到右逐渐变亮的线,color参数也采用了定义范围以内变量和定义范围以外变量两种方式,以测试对color参数预处理效果。由于是在函数编写过程中进行的测试,所以没有采用独立的测试程序,只是在函数文件中加入了一个main函数来进行测试的。

OLED12896_GR_Lib.rar (93.91 KB, 下载次数: 14)

最新回复

晚上回去测试一下,谢谢分享。  详情 回复 发表于 2011-5-3 15:28
 
点赞 关注

回复
举报

918

帖子

0

TA的资源

纯净的硅(中级)

沙发
 

回复 楼主 柳叶舟 的帖子

晚上回去测试一下,谢谢分享。
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表