硬汉嵌入式论坛

 找回密码
 立即注册
查看: 724|回复: 6
收起左侧

[emWin] 关于界面切换卡顿的问题

[复制链接]

8

主题

14

回帖

38

积分

新手上路

积分
38
发表于 2024-12-3 17:34:31 | 显示全部楼层 |阅读模式
按键按下后,界面切换肉眼可见的卡顿,想请教一下大佬们原因?是emWIN相关还是通信这块不对的原因
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2024-12-4 09:55:37 | 显示全部楼层
这个得看什么样的界面才好下结论。
回复

使用道具 举报

8

主题

14

回帖

38

积分

新手上路

积分
38
 楼主| 发表于 2024-12-4 10:33:13 | 显示全部楼层
eric2013 发表于 2024-12-4 09:55
这个得看什么样的界面才好下结论。

大佬,是这样的:开机之后是四个小窗口,按键按下后依次切换其中的小窗口为大窗口,最后回到四个小窗口

下面是具体的绘制函数,在这之前还有很多判断
//=================================================================
static void _cbDeskQuarterWindow(WM_MESSAGE * pMsg)
{
    INT32S bReDrawClient;

    switch(pMsg->MsgId)
    {
        case WM_SET_FOCUS:
        {
            pMsg->Data.v = 0;
        }
        break;
        case WM_CREATE: break;
        case WM_PAINT:
        {
            HalfOfWindow_t HalfOfWindowData;
            const ChannelShowData_t *pChannelData;

            WM_GetUserData(pMsg->hWin,&HalfOfWindowData,sizeof(HalfOfWindowData));
                        if(SHOW_CHANNEL_1 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh1;
            }
            else if(SHOW_CHANNEL_2 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh2;
            }
                        else if(SHOW_CHANNEL_3 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh3;
            }
                        else
            {
                pChannelData = &g_ShowDataCh4;
            }
            bReDrawClient = DesktopQuarterDrawTitleBar(pChannelData,&HalfOfWindowData,!HalfOfWindowData.bInit);
            DesktopQuarterDrawCurrentVoltage(pChannelData,&HalfOfWindowData,bReDrawClient);
            DesktopQuarterDrawDataArea(pChannelData,&HalfOfWindowData,bReDrawClient);
            if(bReDrawClient)
            {
                DeskDrawBitMap_QuarterWin(pChannelData);
            }
            DeskQuarterSaveAllData(&HalfOfWindowData,pChannelData);
            WM_SetUserData(pMsg->hWin,&HalfOfWindowData,sizeof(HalfOfWindowData));
        }
        break;
        case WM_GET_ID:  pMsg->Data.v = WINID_DESK_TITLE;  break;
        case WM_TIMER:
        {
            INT32U bReDraw;
            INT32U CurTime;
            HalfOfWindow_t HalfOfWindowData;
            const ChannelShowData_t *pChannelData;

            WM_GetUserData(pMsg->hWin,&HalfOfWindowData,sizeof(HalfOfWindowData));
            if(SHOW_CHANNEL_1 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh1;
            }
            else if(SHOW_CHANNEL_2 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh2;
            }
                        else if(SHOW_CHANNEL_3 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh3;
            }
                        else
            {
                pChannelData = &g_ShowDataCh4;
            }
            if(UI_STATUS_STANDBY == pChannelData->SysStatus)
            {
                if(StandbyErrorDetect(HalfOfWindowData.ChannelNum))
                {
                    break;
                }
                WM_RestartTimer(pMsg->Data.v,500/portTICK_PERIOD_MS);
                WM_InvalidateWindow(pMsg->hWin);
            }
            else
            {
                WM_RestartTimer(pMsg->Data.v,100/portTICK_PERIOD_MS);
                if(RunErrorStop(HalfOfWindowData.ChannelNum))
                {
                    break;
                }
                bReDraw = FALSE;
                CurTime = GUI_GetTime() / (configTICK_RATE_HZ / 2);
                if(CurTime != HalfOfWindowData.LastTick)
                {
                    bReDraw = TRUE;
                }
                if(bReDraw)
                {
                    WM_GetUserData(pMsg->hWin,&HalfOfWindowData,sizeof(HalfOfWindowData));
                    HalfOfWindowData.LastTick = CurTime;
                    WM_SetUserData(pMsg->hWin,&HalfOfWindowData,sizeof(HalfOfWindowData));
                    WM_InvalidateWindow(pMsg->hWin);
                }
            }
        }
        break;
        case WM_KEY:
        {
            if(((WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt)
            {
                ProcessKeyEvent(((WM_KEY_INFO*)(pMsg->Data.p))->Key, ((WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt);
            }
        }
        break;
        default:  WM_DefaultProc(pMsg); break;
    }
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2024-12-5 09:52:10 | 显示全部楼层
YISHUI 发表于 2024-12-4 10:33
大佬,是这样的:开机之后是四个小窗口,按键按下后依次切换其中的小窗口为大窗口,最后回到四个小窗口
...

重回里面的这个执行有必要改进下,因为WM_PAINT会频繁的进入

放在其它地方执行

[C] 纯文本查看 复制代码
case WM_PAINT:
        {
            HalfOfWindow_t HalfOfWindowData;
            const ChannelShowData_t *pChannelData;

            WM_GetUserData(pMsg->hWin,&HalfOfWindowData,sizeof(HalfOfWindowData));
                        if(SHOW_CHANNEL_1 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh1;
            }
            else if(SHOW_CHANNEL_2 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh2;
            }
                        else if(SHOW_CHANNEL_3 == HalfOfWindowData.ChannelNum)
            {
                pChannelData = &g_ShowDataCh3;
            }
                        else
            {
                pChannelData = &g_ShowDataCh4;
            }
            bReDrawClient = DesktopQuarterDrawTitleBar(pChannelData,&HalfOfWindowData,!HalfOfWindowData.bInit);
            DesktopQuarterDrawCurrentVoltage(pChannelData,&HalfOfWindowData,bReDrawClient);
            DesktopQuarterDrawDataArea(pChannelData,&HalfOfWindowData,bReDrawClient);
            if(bReDrawClient)
            {
                DeskDrawBitMap_QuarterWin(pChannelData);
            }
            DeskQuarterSaveAllData(&HalfOfWindowData,pChannelData);
            WM_SetUserData(pMsg->hWin,&HalfOfWindowData,sizeof(HalfOfWindowData));
        }
        break;
回复

使用道具 举报

8

主题

14

回帖

38

积分

新手上路

积分
38
 楼主| 发表于 2024-12-5 15:00:24 | 显示全部楼层
eric2013 发表于 2024-12-5 09:52
重回里面的这个执行有必要改进下,因为WM_PAINT会频繁的进入

放在其它地方执行

大佬,这个应该放在哪里执行呢?
还有就是下面的两个函数如果用DMA来传输,这样会不会快一些:
static void LPSWriteDataByteBuf(const uint8_t *pData,INT32S size)
{
           IPC_RS_HI();
           IPC_CS_LOW();
           while(size--)
           {
                      GUITxData(*pData++);
           }
           WaitTxEnd();
           IPC_CS_HI();
}

static void LPSFillHalfWord(uint32_t Data,INT32S size)
{
           uint8_t Low;
           uint8_t Hight;
   
           IPC_RS_HI();
           IPC_CS_LOW();
           Hight = Data >> 8;
           Low = Data;
           while(size--)
           {
                      GUITxData(Hight);
                      GUITxData(Low);
           }
           WaitTxEnd();
           IPC_CS_HI();
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2024-12-6 08:58:40 | 显示全部楼层
YISHUI 发表于 2024-12-5 15:00
大佬,这个应该放在哪里执行呢?
还有就是下面的两个函数如果用DMA来传输,这样会不会快一些:
static  ...

1、使用DMA会快。
2、就在你的定时器消息里面做就行。
回复

使用道具 举报

8

主题

14

回帖

38

积分

新手上路

积分
38
 楼主| 发表于 2024-12-6 11:33:41 | 显示全部楼层
YISHUI 发表于 2024-12-5 15:00
大佬,这个应该放在哪里执行呢?
还有就是下面的两个函数如果用DMA来传输,这样会不会快一些:
static  ...

参考淘宝上买的屏幕的源码改的,直接花屏了,不知道哪里出了问题
static void LPSWriteDataByteBuf(const uint8_t *pData,INT32S size)
{
       
    IPC_RS_HI();
    IPC_CS_LOW();
       
        //DMA_Cmd(DMA1_Channel3, DISABLE );

        MYDMA_Config(DMA1_Channel3,(u32)&SPI1->DR,(u32)pData,size);
        SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);
        MYDMA_Enable(DMA1_Channel3);
        while(1)
        {
                if(DMA_GetFlagStatus(DMA1_FLAG_TC3)!=RESET)//等待通道3传输完成
                {
                        DMA_ClearFlag(DMA1_FLAG_TC3);//清除通道3传输完成标志
                        break;
                }
        }
        IPC_CS_HI();

}
static void LPSFillHalfWord(uint32_t Data, INT32S size)
{
        uint8_t buffer[3];
        buffer[0] = Data >> 8;
        buffer[1] = Data;
   
           IPC_RS_HI();
           IPC_CS_LOW();


        MYDMA_Config(DMA1_Channel3,(u32)&SPI1->DR,(u32)buffer,size*2);
        SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);
        MYDMA_Enable(DMA1_Channel3);
        while(1)
        {
                if(DMA_GetFlagStatus(DMA1_FLAG_TC3)!=RESET)//等待通道3传输完成
                {
                        DMA_ClearFlag(DMA1_FLAG_TC3);//清除通道3传输完成标志
                        break;
                }
        }
           IPC_CS_HI();

}
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 20:00 , Processed in 0.041290 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表