ccschen 发表于 2022-9-8 22:42:21

Emwin 定时器工作若干时间后不能进 case WM_TIMER:

在window中,每秒刷新一次数据,创建定时器成功,刷新也正常,只是几小时,或者几天,几十天后,界面不刷新了。
挂上仿真器后,也复现了现象,发现界面也能切换,界面切换回去,部分条件分支也是执行了的,但WM_TIMER就是进不去,不知道什么原因。

部分代码如下:

WM_SetFocus(pMsg->hWin);       
hTimerTime = WM_CreateTimer(pMsg->hWin, ID_ACQ_TIMER_TIME, 1000, 0);       

case WM_TIMER:
                WM_InvalidateWindow(WM_GetClientWindow(pMsg->hWin));
    /* Refrish real time display */   
    WM_InvalidateWindow(pMsg->hWin);//定时器消息,这里要特别注意,如果想要定时器周期性执行,而不是只执行一次,必须得调用重启定时器函数WM_RestartTimer()。在这个消息里面将桌面窗口无效,从而会触发窗口管理器去执行WM_PAINT消息,这样就实现了定时修改桌面窗口背景色。
    WM_RestartTimer(pMsg->Data.v, 1000);
break;

ccschen 发表于 2022-9-8 23:11:19

刚才又试了下,将这个界面结束掉,重新进界面,又可以刷新了,重开界面会重新创建定时器的,难道定时器某种原因挂掉了?

eric2013 发表于 2022-9-9 12:30:59

ccschen 发表于 2022-9-8 23:11
刚才又试了下,将这个界面结束掉,重新进界面,又可以刷新了,重开界面会重新创建定时器的,难道定时器某种 ...

这里怎么更新了两次,你的是框架窗口?仅更新客户区就行了。
WM_InvalidateWindow(WM_GetClientWindow(pMsg->hWin));
WM_InvalidateWindow(pMsg->hWin);

另外是不是更新内容很多,如果更新内容很多,使用局部区域更新的那个API方便些。


ccschen 发表于 2022-9-9 14:30:32

eric2013 发表于 2022-9-9 12:30
这里怎么更新了两次,你的是框架窗口?仅更新客户区就行了。
WM_InvalidateWindow(WM_GetClientWindow(p ...

上次不是也不刷新么,就加了句,是重复了,测试了个多月,定时器就不刷新了。

ccschen 发表于 2022-9-9 14:58:40

是这样的,窗口128*64,上面一行做成的子窗口,用来显示状态,时间这些,下面就是主显示区域,都是WINDOW。子窗口里面有定时器,主窗口也有定时器。

ccschen 发表于 2022-9-9 15:07:47

之前状态栏那用这个函数 WM_CreateWindowAsChild,现在改成 WM_CreateWindow,不知道会有改善不。下面部分主界面都是用的GUI_CreateDialogBox。

eric2013 发表于 2022-9-11 11:00:46

ccschen 发表于 2022-9-9 15:07
之前状态栏那用这个函数 WM_CreateWindowAsChild,现在改成 WM_CreateWindow,不知道会有改善不。下面部分 ...

这两个区别不大,你改用仅更新局部指定区域的API试试,另外你的这个分辨率只有128*64,很大概率不是更新上的问题,估计有地方实现有问题。

ccschen 发表于 2022-9-11 12:15:06

eric2013 发表于 2022-9-11 11:00
这两个区别不大,你改用仅更新局部指定区域的API试试,另外你的这个分辨率只有128*64,很大概率不是更新 ...

仅更新局部指定区域的API?
请明示?

ccschen 发表于 2022-9-11 12:16:29

eric2013 发表于 2022-9-11 11:00
这两个区别不大,你改用仅更新局部指定区域的API试试,另外你的这个分辨率只有128*64,很大概率不是更新 ...

关键是定时器中断不进了,不进WM_TIMER

ccschen 发表于 2022-9-11 12:20:22

状态栏参考ST官方的DEMO做的,刷新方式也是这样的。

/**
******************************************************************************
* @file    demo_menu.c
* @authorMCD Application Team
* @version V1.0.1
* @date    11-November-2013
* @brief   Demo menu and icons
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
*      http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "WM.h"
#include "Res\menu_res.c"
#include "Res\clock.c"
#include "Res\cpu.c"
#include "Res\game.c"
#include "Res\image.c"
#include "Res\info.c"
#include "Res\multimedia.c"
#include "Res\background.c"
#include "time_utils.h"
#include "cpu_utils.h"

/* External variables --------------------------------------------------------*/
extern __IO uint8_t alarm_now;
extern __IO uint32_t alarm_set;
extern RTC_AlarmTypeDefRTC_AlarmStructure;
extern WM_HWINVIDEO_hWin, hVideoScreen;
extern WM_HWINIMAGE_hWin, vFrame;
extern __IO uint32_t TS_Orientation;
extern __IO uint32_t IMAGE_Enlarge;
extern __IO uint32_t VIDEO_Enlarge;

extern void DEMO_SystemInfo ( WM_HWIN hWin);
extern void DEMO_Game(WM_HWIN hWin);
extern void DEMO_Video(WM_HWIN hWin);
extern void DEMO_Image(WM_HWIN hWin);
extern void DEMO_Clock(WM_HWIN hWin);
extern void DEMO_Cpu(WM_HWIN hWin);

/* Private typedef -----------------------------------------------------------*/
typedef struct {
const GUI_BITMAP * pBitmap;
const char       * pText;
const char       * pExplanation;
} BITMAP_ITEM;

/* Private defines -----------------------------------------------------------*/
#define WM_MSG_USB_STATUS_CHANGED      WM_USER + 0x01
#define ID_TIMER_TIME                  1

/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t current_module = 0xFF;

static const BITMAP_ITEM _aBitmapItem[] = {
{&bmmultimedia,   "Video Player"      , "Launch MPJPEG video"},
{&bmimage,      "Image Browser"       , "Browse Images"},
{&bmclock,      "Clock/Calendar"      , "Clock settings"},
{&bmgame,         "Game"                , "Launch Reversi game"},
{&bmcpu,          "Perfomance"          , "Show CPU performance"},
{&bminfo,         "System Info"         , "Get System Information"},
};

static void (* _apModules[])( WM_HWIN hWin) =
{
DEMO_Video,
DEMO_Image,
DEMO_Clock,
DEMO_Game,
DEMO_Cpu,
DEMO_SystemInfo,
};

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
* @briefCallback routine of desktop window
* @parampMsg: pointer to a data structure of type WM_MESSAGE
* @retval None
*/
static void _cbBk(WM_MESSAGE * pMsg) {
uint32_t NCode, Id, sel;
static uint32_t module_mutex = 0;

switch (pMsg->MsgId)
{
case WM_PAINT:
    GUI_SetBkColor(GUI_TRANSPARENT);
    GUI_Clear();
    break;
   
case WM_NOTIFY_PARENT:
    Id    = WM_GetId(pMsg->hWinSrc);   
    NCode = pMsg->Data.v;
   
    switch (NCode)
    {
    case WM_NOTIFICATION_CLICKED:
      if (Id == '0')
      {
      sel = ICONVIEW_GetSel(pMsg->hWinSrc);
      if(sel < GUI_COUNTOF(_aBitmapItem))
      {
          if(module_mutex == 0)
          {
            module_mutex = 1;
            _apModules (pMsg->hWinSrc);
            current_module = sel;
          }
      }
      }
      break;
      
    case 0x500:
      module_mutex = 0;
      current_module = 0xFF;
      ICONVIEW_SetSel(pMsg->hWinSrc, -1);
      break;
      
    default:
      break;
    }
    break;
default:
    WM_DefaultProc(pMsg);
}
}

/**
* @briefCallback routine of the status bar
* @parampMsg: pointer to a data structure of type WM_MESSAGE
* @retval None
*/
static void _cbStatus(WM_MESSAGE * pMsg) {
int xSize, ySize;
static uint8_t TempStr;

RTC_TimeTypeDef   RTC_TimeStructure;
RTC_DateTypeDef   RTC_DateStructure;
uint8_t sec, min, hour;

static WM_HTIMER hTimerTime;
WM_HWIN hWin;

hWin = pMsg->hWin;
switch (pMsg->MsgId) {

case WM_CREATE:
    hTimerTime = WM_CreateTimer(hWin, ID_TIMER_TIME, 1000, 0);
    break;
case WM_DELETE:
    WM_DeleteTimer(hTimerTime);
    break;
case WM_TIMER:
    WM_InvalidateWindow(hWin);
    WM_RestartTimer(pMsg->Data.v, 0);
    break;
   
case WM_MSG_USB_STATUS_CHANGED:   
    WM_InvalidateWindow(hWin);
    break;
   
case WM_PAINT:
    xSize = WM_GetWindowSizeX(hWin);
    ySize = WM_GetWindowSizeY(hWin);
   
    /* Draw background */
    GUI_SetColor(0x303030);
    GUI_FillRect(0, 0, xSize , ySize - 3);
    GUI_SetColor(0x808080);
    GUI_DrawHLine(ySize - 2, 0, xSize );
    GUI_SetColor(0x404040);
    GUI_DrawHLine(ySize - 1, 0, xSize );
   
    /* Draw time & Date */
    GUI_SetTextMode(GUI_TM_TRANS);
    GUI_SetColor(GUI_WHITE);
    GUI_SetFont(GUI_FONT_13B_ASCII);
   
    RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
    sec    =RTC_TimeStructure.RTC_Seconds;
    min    =RTC_TimeStructure.RTC_Minutes;
    hour   =RTC_TimeStructure.RTC_Hours;
   
    RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);
   
    sprintf((char *)TempStr, "%02d:%02d:%02d", hour , min, sec);
    GUI_DispStringAt((char *)TempStr, xSize - 50, 4);
   
    /* Draw alarm icon */
    if (alarm_set == 1)
    {
      GUI_DrawBitmap(&_bmAlarm_16x16, xSize - 73, 3);
    }
   
    /* Logo */
    GUI_DrawBitmap(&bmSTLogo40x20, 5, 1);
   
    /* USB */
    if(USB_Host_Application_Ready == 1)
    {
      GUI_DrawBitmap(&bmusbdisk, xSize - 115, 0);
    }
   
    sprintf((char *)TempStr, "CPU : %d %%", FreeRTOS_GetCPUUsage());
   
    if(FreeRTOS_GetCPUUsage() < 75 )
    {
      GUI_SetColor(GUI_WHITE);
    }
    else
    {
      GUI_SetColor(GUI_RED);
    }
    GUI_DispStringAt( (char *)TempStr, 50, 4);
    GUI_SetColor(GUI_WHITE);
    break;
   
default:
    WM_DefaultProc(pMsg);
}
}

/**
* @briefDemo Main menu
* @paramNone
* @retval None
*/
void DEMO_MainMenu(void)
{
ICONVIEW_Handle hIcon;
WM_HWIN hStatusWin;
static uint32_t prev_usb_state = 0;
int i = 0;


GUI_DrawBitmap(&bmbackground, 0,0);   
GUI_SetAlpha(0xA0);
GUI_DrawBitmap(&bmSTM32_F4, LCD_GetXSize() - bmSTM32_F4.XSize - 10 , LCD_GetYSize() - bmSTM32_F4.YSize - 10);
GUI_SetAlpha(0x00);

WM_SetCallback(WM_GetDesktopWindowEx(1), _cbBk);

hStatusWin = WM_CreateWindowAsChild(
                                    0,
                                    0,
                                    LCD_GetXSize(),
                                    25,
                                    WM_GetDesktopWindowEx(1), WM_CF_SHOW | WM_CF_HASTRANS , _cbStatus, 0);

hIcon = ICONVIEW_CreateEx(0, 25, LCD_GetXSize(), LCD_GetYSize()- 26, WM_GetDesktopWindowEx(1), WM_CF_SHOW | WM_CF_HASTRANS ,0 ,'0', 115, 95);

ICONVIEW_SetFont(hIcon, &GUI_Font13B_ASCII);

ICONVIEW_SetBkColor(hIcon, ICONVIEW_CI_SEL, 0x941000 | 0x80404040);

ICONVIEW_SetSpace(hIcon, GUI_COORD_Y, 3);

ICONVIEW_SetFrame(hIcon, GUI_COORD_Y, 1);

for (i = 0; i < GUI_COUNTOF(_aBitmapItem); i++)
{
    ICONVIEW_AddBitmapItem(hIcon,_aBitmapItem.pBitmap, _aBitmapItem.pText);
}

GUI_SelectLayer(1);

while (1)
{
    if(USB_Host_Application_Ready != prev_usb_state)
    {
      prev_usb_state = USB_Host_Application_Ready;
      WM_SendMessageNoPara(hStatusWin, WM_MSG_USB_STATUS_CHANGED);
      
      if(USB_Host_Application_Ready == 0)
      {
      if(current_module == 0)
      {
          GUI_EndDialog(VIDEO_hWin, 0);
          if (VIDEO_Enlarge == 1)
          {
            WM_DeleteWindow(hVideoScreen);
            GUI_SetOrientation(0);
            TS_Orientation = 0;
          }
      }
      else if (current_module == 1)
      {
          GUI_EndDialog(IMAGE_hWin, 0);
          if (IMAGE_Enlarge == 1)
          {
            WM_DeleteWindow(vFrame);
            GUI_SetOrientation(0);
            TS_Orientation = 0;
          }
      }
      }
    }
    GUI_Delay(100);
}
}

/*************************** End of file ****************************/

ccschen 发表于 2024-4-7 00:24:59

已经解决了,就是在RTOS中定时发送事件给窗口,窗口再刷新,就不用窗口中的定时器了。
页: [1]
查看完整版本: Emwin 定时器工作若干时间后不能进 case WM_TIMER: