移植UCGUI时,调用GUI_Delay();的解决办法!

2019-10-15 19:35发布

 
最近在学习UCGUI一段时间了,终于成功移植了UCGUI里面的大部分源码,感觉移植代码量还是比较大的,不过倒是GUI_Delay();对于很多菜鸟可能会搞不懂,下面就说一下关于按照原子论坛里的教程成功移植UCGUI3.90后,会发现GUI_Delay();这个函数一调用程序就会卡在这个函数里面,修改一下底层函数,即使没加入操作系统,只移植了UCGUI也可以调用GUI_Delay(); fficeffice" />      解析GUI_Delay()函数:    使用GUI_Delay()函数时,对于其延时时间不确定,明明设置为最小值1,延时时间仍旧太长,不能达到需求。遂决定研究明白其实现机理。  第一使用操作系统uc/os时:   uC/OS-II使用OSTimeDly()函数实现延时,其单位是OS_TICKS,即延时多少个系统节拍。GUI使用GUI_Delay()函数延时,同时也实现显示刷新;基于同一个平台,估计也会调用OSTimeDly()函数以实现基本的延时功能。 下面分析GUI_Delay()函数功能 void GUI_Delay(int eriod) {    int EndTime = GUI_GetTime()+Period;   int tRem; /* remaining Time */   GUI_ASSERT_NO_LOCK();    while (tRem = EndTime- GUI_GetTime(), tRem>0) {     GUI_Exec();      GUI_X_Delay((tRem >5) ? 5: tRem);   } }  首先EndTime变量获得延时结束时间;  使用一个while循环,在结束时间之前循环调用GUI_Exec()函数和GUI_X_Delay()函数;  前者是GUI的刷新函数,保证在延时过程中不会停止GUI任务处理。后者就是我们要分析的延时函数GUI_X_Delay了。  参数用三目变量,每次送给延时的参数最大是5  跟踪GUI_X_Delay()函数,在GUI_X_uCOS.C文件中实现。 void  GUI_X_Delay (int period)  {      INT32U  ticks;      ticks = (period * 1000) / OS_TICKS_PER_SEC;     OSTimeDly((INT16U)ticks); }  可以看到,在GUI_X_Delay()函数中调用了系统延时函数OSTimeDly(),就像前面我们说过的,OSTimeDly()函数的延时时间是系统节拍,如果要改变GUI_Delay()函数的延时时间,就需要从此着手。  再看看延时时间的取值:OS_TICKS_PER_SECOS_CFG.H中设置为100,即每秒产生100个系统节拍。ticks变量在这里被扩展了10倍。即GUI_Delay()函数传递一个延时参数1,而实际的延时时间就是10个节拍即100毫秒。在这个延时时间之内,调用GUI_Delay()函数的任务就不能执行,使得响应速度慢。为保持源程序的风格一致,这里改period的倍数为100,使GUI_Delay()函数的延时时间和OSTimeDly()函数时间单位一致,提高了响应速度增强其易用性。   第二,只移植了UCGUI时;也可以使用GUI_Delay();延时函数,不过要修改相关的底层函数:   按照网上的教程成功移植UCGUI3.90后,会发现GUI_Delay();这个函数一调用程序就会卡在这个函数里面, 找到:c文件:  GUI_X.C   *********************************************************************************************************
*                                                uC/GUI
*                        Universal graphic software for embedded applications
*
*                       (c) Copyright 2002, Micrium Inc., ffice:smarttags" />WestonFL
*                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
*              
/GUI is protected by international copyright laws. Knowledge of the
*              source code may not be used to write a similar product. This file may
*              only be used in accordance with a license and should not be redistributed
*              in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File     : GUI_X.C
Purpose  : Config / System dependent externals for GUI
---------------------------END-OF-HEADER------------------------------
*/

#include "GUI.h"
#include "GUI_X.h"

/*********************************************************************
*
*       Global data
*/
volatile int OS_TimeMS;

/*********************************************************************
*
*      Timing:
*                 GUI_X_GetTime()
*                 GUI_X_Delay(int)

  Some timing dependent routines require a GetTime
  and delay function. Default time unit (tick), normally is
  1 ms.
*/

int GUI_X_GetTime(void) { 
  return OS_TimeMS; 
}

void GUI_X_Delay(int ms) { 
  int tEnd = OS_TimeMS + ms;
  while ((tEnd - OS_TimeMS) > 0);
}

/*********************************************************************
*
*       GUI_X_Init()
*
* Note:
*     GUI_X_Init() is called from GUI_Init is a possibility to init
*     some hardware which needs to be up and running before the GUI.
*     If not required, leave this routine blank.
*/

void GUI_X_Init(void) {}


/*********************************************************************
*
*       GUI_X_ExecIdle
*
* Note:
*  Called if WM is in idle state
*/

void GUI_X_ExecIdle(void) {}

/*********************************************************************
*
*      Logging: OS dependent

Note:
  Logging is used in higher debug levels only. The typical target
  build does not use logging and does therefor not require any of
  the logging routines below. For a release build without logging
  the routines below may be eliminated to save some space.
  (If the linker is not function aware and eliminates unreferenced
  functions automatically)

void GUI_X_Log     (const char *s) { GUI_USE_PARA(s); }
void GUI_X_Warn    (const char *s) { GUI_USE_PARA(s); }
void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); }
    修改volatile int OS_TimeMS; 可以使用STM32的系统嘀嗒定时器systick();设置好作为GUI_Delay()的时钟节拍,然后让滴答定时器作为volatile int OS_TimeMS;的时钟,就可以调UCGU的延时函数了。 或者直接调用原子哥delay_ms();加入到GUI_Delay()也可以延时的。        

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
13条回答
神通广大
1楼-- · 2019-10-16 00:45
回复【楼主位】神通广大:
---------------------------------
裸跑,没有系统,在调用GUI_Delay()时,出现死循环的问题,跟踪发现,GUI_Delay()需要调用GUI_X_GetTime(),GUI_X_GetTime是获取系统时间用的,我裸跑时,除了去获取控制芯片实时时钟外,我还没想到其他的办法(这种方法还没调试,前提是控制芯片本身有实时时钟模块),能获取系统时间,在网上查了好多资料,还是没有其他的解决办法,最后索性修改GUI_Delay(),反正这个也主要是延时用的,我就直接修改了,我修改的代码如下:

void GUI_Delay(int eriod) {

  GUI_ASSERT_NO_LOCK();

  while (Period) {
    GUI_Exec();
    eriod--;
  }

}
传说中的松哥
2楼-- · 2019-10-16 03:21
MARK 也碰到这个问题,学习一下。
衡阳落雁
3楼-- · 2019-10-16 05:06
 精彩回答 2  元偷偷看……
衡阳落雁
4楼-- · 2019-10-16 08:49
回复【4楼】衡阳落雁:
---------------------
找到解决办法了,新版子的函数已经修正了
传说中的松哥
5楼-- · 2019-10-16 09:53
回复【5楼】衡阳落雁:
---------------------------------
新版子?什么新版子?
衡阳落雁
6楼-- · 2019-10-16 13:29
回复【6楼】传说中的松哥:
---------------------------------
就是那个大版,好像是2.0吧,不是mini版
实际上他这个函数应该横竖屏时代码都一样的,他分开写反而错了

一周热门 更多>