嵌入式LCD闪烁--emWin使用内存设备避免闪烁
啊哈彭 人气:10、引子
近日在论坛看到有人说屏幕闪烁,问道怎么解决。在嵌入式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应用开发实战指南》
加载全部内容