9. 关于Emwin用WM_TIMER刷新TEXT控件屏幕闪烁解决方法注:
本人于2021.03.06遇到Emwin界面刷新时的闪烁问题,因为我的屏幕上控件分布在屏幕的四周。几乎覆盖整个屏幕,刷新起来的时候整个屏幕都会闪烁
条件
以下几个的定时器都是15ms刷新一次
如图,我用五个text控件模拟了emwin的闪烁问题
第一张
4个控件都刷新数据
很明显可以看到整个屏幕都在闪烁,因为中间的E并没有刷新,但是却也闪烁
TEXT_SetText(TEXT_A, A1);
TEXT_SetText(TEXT_B, B1);
TEXT_SetText(TEXT_C, C1);
TEXT_SetText(TEXT_D, D1);
//TEXT_SetText(TEXT_E, E1);
第二张
五个控件都刷新了数据
TEXT_SetText(TEXT_A, A1);
TEXT_SetText(TEXT_B, B1);
TEXT_SetText(TEXT_C, C1);
TEXT_SetText(TEXT_D, D1);
TEXT_SetText(TEXT_E, E1);
五个控件都闪烁
第三个
只刷新AB
几乎看不到闪烁,但是还是有一点
TEXT_SetText(TEXT_A, A1);
TEXT_SetText(TEXT_B, B1);
//TEXT_SetText(TEXT_C, C1);
//TEXT_SetText(TEXT_D, D1);
//TEXT_SetText(TEXT_E, E1);
第四个
只刷新A
TEXT_SetText(TEXT_A, A1);
//TEXT_SetText(TEXT_B, B1);
//TEXT_SetText(TEXT_C, C1);
//TEXT_SetText(TEXT_D, D1);
//TEXT_SetText(TEXT_E, E1);
明显,已经看不出来闪烁了,这是因为只有A控件在刷新,
如果五个控件同时刷新的话
当A有内容刷新后,此时没有调用GUI_Exec(),然后继续等B更新数据,继续到C,D,E,等所有控件的数据都改变后,才开始调用GUI_Exec()刷新屏幕,这就造成Emwin的整个屏幕一起刷新,导致闪烁
解决方法
如果我们只要控件一刷新,就开始调用GUI_Exec函数更新控件内容,在很大程度上就避免了所有的控件数据更新后才刷新屏幕,导致闪烁,也就是刷新单个控件,
我对每个控件更新后都使用了GUI_Exec来刷新屏幕,接下来看效果
TEXT_SetText(TEXT_A, A1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_B, B1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_C, C1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_D, D1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_E, E1);
GUI_Exec();//立即刷新数据
测试代码
#include "DIALOG.h"
WM_HTIMER RUN_Timer;
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x03)
#define ID_TEXT_0 (GUI_ID_USER + 0x04)
#define ID_TEXT_1 (GUI_ID_USER + 0x05)
#define ID_TEXT_2 (GUI_ID_USER + 0x06)
#define ID_TEXT_3 (GUI_ID_USER + 0x07)
#define ID_TEXT_4 (GUI_ID_USER + 0x08)
int A, B, C, D, E = 0;
// USER START (Optionally insert additional defines)
// USER END
WM_HWIN TEXT_A;
WM_HWIN TEXT_B;
WM_HWIN TEXT_C;
WM_HWIN TEXT_D;
WM_HWIN TEXT_E;
char A1[10];
char B1[10];
char C1[10];
char D1[10];
char E1[10];
/*********************************************************************
*
* _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ FRAMEWIN_CreateIndirect, "ABCDE", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x0, 0 },
{ TEXT_CreateIndirect, "A", ID_TEXT_0, 22, 32, 80, 54, 0, 0x0, 0 },
{ TEXT_CreateIndirect, "B", ID_TEXT_1, 709, 35, 80, 44, 0, 0x0, 0 },
{ TEXT_CreateIndirect, "C", ID_TEXT_2, 700, 380, 80, 35, 0, 0x0, 0 },
{ TEXT_CreateIndirect, "D", ID_TEXT_3, 62, 374, 80, 38, 0, 0x0, 0 },
{ TEXT_CreateIndirect, "E", ID_TEXT_4, 349, 172, 80, 32, 0, 0x0, 0 },
// USER START (Optionally insert additional widgets)
// USER END
};
/*********************************************************************
*
* _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
WM_HWIN hItem;
// USER START (Optionally insert additional variables)
// USER END
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
//
// Initialization of 'ABCDE'
//
hItem = pMsg->hWin;
FRAMEWIN_SetFont(hItem, GUI_FONT_32B_1);
//
TEXT_A = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
TEXT_SetFont(TEXT_A, GUI_FONT_32B_1);
//
// Initialization of 'E'
//
TEXT_B = WM_GetDialogItem(pMsg->hWin, ID_TEXT_1);
TEXT_SetFont(TEXT_B, GUI_FONT_32B_1);
TEXT_C = WM_GetDialogItem(pMsg->hWin, ID_TEXT_2);
TEXT_SetFont(TEXT_C, GUI_FONT_32B_1);
//
// Initialization of 'E'
//
TEXT_D = WM_GetDialogItem(pMsg->hWin, ID_TEXT_3);
TEXT_SetFont(TEXT_D, GUI_FONT_32B_1);
TEXT_E = WM_GetDialogItem(pMsg->hWin, ID_TEXT_4);
TEXT_SetFont(TEXT_E, GUI_FONT_32B_1);
// USER START (Optionally insert additional code for further widget initialization)
// USER END
break;
// USER START (Optionally insert additional message handling)
// USER END
default:
WM_DefaultProc(pMsg);
break;
case WM_TIMER:
A++;
B++;
C = A + B;
D = A + C;
E = C + D;
sprintf(A1, "A=%d", A);
sprintf(B1, "B=%d", B);
sprintf(C1, "C=%d", C);
sprintf(D1, "D=%d", D);
sprintf(E1, "E=%d", E);
TEXT_SetText(TEXT_A, A1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_B, B1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_C, C1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_D, D1);
GUI_Exec();//立即刷新数据
TEXT_SetText(TEXT_E, E1);
GUI_Exec();//立即刷新数据
WM_RestartTimer(RUN_Timer, 15); //16ms刷新一次窗口(9)
break;
}
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* CreateABCDE
*/
WM_HWIN CreateABCDE(void);
WM_HWIN CreateABCDE(void) {
WM_HWIN hWin;
hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
return hWin;
}
// USER START (Optionally insert additional public code)
// USER END
/*************************** End of file ****************************/
void MainTask(void)
{
GUI_Init(); //GUI初始化
GUI_UC_SetEncodeUTF8();
CreateABCDE();
RUN_Timer = WM_CreateTimer(WM_GetClientWindow(CreateABCDE()), 3, 30, 0);
while (1)
{
GUI_Delay(200);
}
}