嵌入式LCD闪烁--emWin使用内存设备避免闪烁

2019/04/10 10:10
阅读数 69

0、引子

近日在论坛看到有人说屏幕闪烁,问道怎么解决。在嵌入式gui使用方面,屏幕闪烁一般多出现在多个窗口层叠、多图层层叠、更新图层时。受限于接口速度,即使屏幕有很高的刷新率,也做不到无闪烁,所以要从减少数据传送上下功夫,比如使用内存设备处理好数据再整体搬到LCD上,还有就是使用局部刷新较少刷新的数据量,同时还要注意图层顺序的问题。

1、内存设备避免闪烁原理

当在液晶屏上绘制一些文字叠加在图片上的效果时,通常是先在液晶屏上绘制底层的图片,然后再在图片上叠加上文字,多次刷新会出现闪烁。

存储设备可在各种情况下使用,主要用于防止在绘制重叠项目时出现显示器闪烁。其基本思想很简单,不使用存储设备时,绘制操作直接写入显示器,屏幕在执行绘制操作时随时更新,从而在进行各种更新时使屏幕闪烁。例如,如果要在背景中绘制一个位图,在前景中绘制一些透明文本,应首先绘制位图,然后绘制文本。效果将是文本出现闪烁。但是,如果在此过程中使用存储设备,则所有绘制操作都在存储器中执行。仅在所有操作都完成后才将最终结果显示在屏幕上,实现一次性从内存到LCD绘制,其优点是没有闪烁。

下图形象的解释了内存设备避免闪烁的原理。

2、emWin使用内存设备

emWin使用内存设备需要先打开配置:

#define GUI_SUPPORT_MEMDEV  (1)  // Memory devices available

测试例子:

void MainTask(void) {
    GUI_Init();
    //
    // Check if recommended memory for the sample is available
    //
    if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
        GUI_ErrorOut("Not enough memory available.");
        return;
    }

    GUI_SetColor(GUI_LIGHTGRAY);
    GUI_RECT rect = { 0, 0, LCD_GetXSize(), 49 };
    GUI_FillRectEx(&rect);
    char title[] = "Draw direct And Use Memory device";
    GUI_SetFont(GUI_FONT_24_ASCII);
    GUI_SetColor(GUI_RED);
    GUI_SetTextMode(GUI_TEXTMODE_TRANS);
    GUI_DispStringInRect(title, &rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
    GUI_DispStringAt("Direct Draw", 70, 200);
    GUI_DispStringAt("Use Memory", 300, 200);

    GUI_MEMDEV_Handle hMem = GUI_MEMDEV_Create(280, 50, 150, 150);
    int i = 0;
    while (1)
    {
        GUI_Delay(5);
        Draw(50, 50, 200, 200, i); // 直接在LCD绘制
        GUI_MEMDEV_Select(hMem); //选择内存设备
        Draw(280, 50, 430, 200, i); // 在内存中绘制
        GUI_MEMDEV_Select(0); // 恢复LCD设备
        GUI_MEMDEV_CopyToLCDAt(hMem, 280, 50);
        i++;
        if (i >= 1000) i = 0;
    }

  while(1);
}


void Draw(int x0, int y0, int x1, int y1, int i)
{
    char buf[10] = { 0 };
    
    GUI_SetColor(GUI_BLUE);
    GUI_FillRect(x0, y0, x1, y1);

    GUI_SetFont(GUI_FONT_D64);
    GUI_SetTextMode(GUI_TEXTMODE_XOR);
    sprintf(buf, "%d", i);
    GUI_DispStringHCenterAt(buf, x0 + (x1 - x0) / 2, y0 + (y1 - y0) / 2 - 32);
}

3、测试效果

测试截图如下:

动态效果可以看到,左侧直接绘制有闪烁,尤其是百位数字即使没有更新时候也会闪烁一次。右侧是先在内存中绘制,然后从内存设备拷贝到界面上,只需要更新一次,没有闪烁。

4、参考文献

1、《emWin用户参考手册》

2、野火《emWin应用开发实战指南》

 

原文出处:https://www.cnblogs.com/pingwen/p/12584076.html

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部