本文系博主原创,若转载请标明出处!
我们在LCD/OLED点阵屏上显示内容,纵坐标上都是以页(page)为单位进行操作。拿128x64的点阵屏为例,纵向为8个page,若有一个图标占用了2个page,那么在这个图标2个page的上下空白部分,就不能显示其它内容了。因为要在这2个page的空白部分显示其它内容的话,会擦除这2个page上已存在的内容。
有一种方法可以实现在已使用page空白部分显示其它内容,就是用并行接口去控制点阵屏。并行接口可以读取屏RAM的显示内容,我们对page空白区域写数据之前,先把page里面的数据读出来,进行或操作之后再写,这样就保留了之前的图标内容。这种方法会占用MCU很多的IO口。
但是大多数产品设计都是使用SPI或者I2C接口控制屏,很少使用并行接口控制屏,因为这样占用CPU的IO资源更少。当使用SPI或者I2C接口进行控制时,是不能读取屏RAM数据的。这个时候想要在page空白部分显示内容的话还有什么办法?
我现在所使用的办法是在MCU里面创建一个和屏大小相同的数组
#define LCD_WIDTH 128
#define LCD_WIDTH_OFFSET 0
#define LCD_HIGH 64
/* 全局变量定义 */
/* clone lcd ddram */
unsigned char m_lcdVirtualRam[LCD_WIDTH * LCD_HIGH / 8]; /* 注意写数据时不要超过此数组最大值,否则会内存泄露,程序崩溃 */
写数据时同步写入到这个数组里。这个数组相当于屏RAM的镜像。当我需要读page内容的时候,只需要从这个数组里面读数据即可。
绘制点阵图形的函数如下
void LcdDriver_draw(
uint8_t _ucX,
uint8_t _ucY,
uint8_t _ucWidth,
uint8_t _ucHigh,
const uint8_t *_ptr
)
{
uint8_t i, j, h, y0, y1, hight;
uint8_t leftShift, rightShift;
uint8_t ucPageAddr;
uint8_t ucColAddr;
uint8_t ucValue;
uint8_t ucRam, ucData;
ucPageAddr = _ucY / 8;
ucColAddr = _ucX;
/* 计算高度值 */
hight = _ucHigh + _ucY;
leftShift = _ucY % 8;
rightShift = (8 - leftShift);
for (i = 0 ; i < (((_ucHigh + _ucY % 8) <= ((_ucHigh + 7) / 8) * 8) ? ( (_ucHigh + 7) / 8) : ((_ucHigh + 7) / 8 + 1)); i++)
{
LCD_Write_cmd (0xB