硬汉嵌入式论坛

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

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

[复制链接]

19

主题

125

回帖

182

积分

初级会员

积分
182
发表于 2022-9-8 22:42:21 | 显示全部楼层 |阅读模式
在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;

回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2022-9-8 23:11:19 | 显示全部楼层
刚才又试了下,将这个界面结束掉,重新进界面,又可以刷新了,重开界面会重新创建定时器的,难道定时器某种原因挂掉了?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106709
QQ
发表于 2022-9-9 12:30:59 | 显示全部楼层
ccschen 发表于 2022-9-8 23:11
刚才又试了下,将这个界面结束掉,重新进界面,又可以刷新了,重开界面会重新创建定时器的,难道定时器某种 ...

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

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


回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2022-9-9 14:30:32 | 显示全部楼层
eric2013 发表于 2022-9-9 12:30
这里怎么更新了两次,你的是框架窗口?仅更新客户区就行了。
WM_InvalidateWindow(WM_GetClientWindow(p ...

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

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2022-9-9 14:58:40 | 显示全部楼层
是这样的,窗口128*64,上面一行做成的子窗口,用来显示状态,时间这些,下面就是主显示区域,都是WINDOW。子窗口里面有定时器,主窗口也有定时器。
回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2022-9-9 15:07:47 | 显示全部楼层
之前状态栏那用这个函数 WM_CreateWindowAsChild,现在改成 WM_CreateWindow,不知道会有改善不。下面部分主界面都是用的GUI_CreateDialogBox。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106709
QQ
发表于 2022-9-11 11:00:46 | 显示全部楼层
ccschen 发表于 2022-9-9 15:07
之前状态栏那用这个函数 WM_CreateWindowAsChild,现在改成 WM_CreateWindow,不知道会有改善不。下面部分 ...

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

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2022-9-11 12:15:06 | 显示全部楼层
eric2013 发表于 2022-9-11 11:00
这两个区别不大,你改用仅更新局部指定区域的API试试,另外你的这个分辨率只有128*64,很大概率不是更新 ...

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

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2022-9-11 12:16:29 | 显示全部楼层
eric2013 发表于 2022-9-11 11:00
这两个区别不大,你改用仅更新局部指定区域的API试试,另外你的这个分辨率只有128*64,很大概率不是更新 ...

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

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2022-9-11 12:20:22 | 显示全部楼层
状态栏参考ST官方的DEMO做的,刷新方式也是这样的。

/**
  ******************************************************************************
  * @file    demo_menu.c
  * @author  MCD 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_AlarmTypeDef  RTC_AlarmStructure;
extern WM_HWIN  VIDEO_hWin, hVideoScreen;
extern WM_HWIN  IMAGE_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 ---------------------------------------------------------*/

/**
  * @brief  Callback routine of desktop window
  * @param  pMsg: 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 [sel](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);
  }
}

/**
  * @brief  Callback routine of the status bar
  * @param  pMsg: pointer to a data structure of type WM_MESSAGE
  * @retval None
  */
static void _cbStatus(WM_MESSAGE * pMsg) {
  int xSize, ySize;
  static uint8_t TempStr[50];
  
  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);
  }
}

/**
  * @brief  Demo Main menu
  * @param  None
  * @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 ****************************/
回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
 楼主| 发表于 2024-4-7 00:24:59 来自手机 | 显示全部楼层
已经解决了,就是在RTOS中定时发送事件给窗口,窗口再刷新,就不用窗口中的定时器了。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-30 12:37 , Processed in 0.196998 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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